From 3012df4775c771499cac34d9cd8e85c8afcda35a Mon Sep 17 00:00:00 2001 From: EvadeMaster <93124920+EvadeMaster@users.noreply.github.com> Date: Fri, 31 Mar 2023 22:18:34 +0700 Subject: [PATCH 01/34] build: update Kotlin to 1.8.10 (#1824) --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3d81b8e74..dff3d309d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - kotlin("jvm") version "1.7.0" + kotlin("jvm") version "1.8.10" } group = "app.revanced" From f48e794eebf9ea44008c4c8a3967ad039d19180a Mon Sep 17 00:00:00 2001 From: fe <58902674+1fexd@users.noreply.github.com> Date: Sat, 1 Apr 2023 01:03:26 +0200 Subject: [PATCH 02/34] feat(id-austria): bump compatibility to `2.6.0` (#1827) Co-authored-by: Your Name --- .../detection/shared/annotations/DetectionCompatibility.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/idaustria/detection/shared/annotations/DetectionCompatibility.kt b/src/main/kotlin/app/revanced/patches/idaustria/detection/shared/annotations/DetectionCompatibility.kt index bfbb42399..b25a6f409 100644 --- a/src/main/kotlin/app/revanced/patches/idaustria/detection/shared/annotations/DetectionCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/idaustria/detection/shared/annotations/DetectionCompatibility.kt @@ -3,6 +3,6 @@ package app.revanced.patches.idaustria.detection.shared.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("at.gv.oe.app", arrayOf("2.5.2"))]) +@Compatibility([Package("at.gv.oe.app", arrayOf("2.5.2", "2.6.0"))]) @Target(AnnotationTarget.CLASS) internal annotation class DetectionCompatibility \ No newline at end of file From ef8f26fb976c3044039f9bff0496088763ab66cd Mon Sep 17 00:00:00 2001 From: morpheus133 Date: Sat, 1 Apr 2023 02:23:08 +0200 Subject: [PATCH 03/34] feat(youtube-music): `bypass-certificate-checks` patch (#1810) Co-authored-by: oSumAtrIX --- .../BypassCertificateChecksCompatibility.kt | 35 ++++++++++++++++ .../CheckCertificateFingerprint.kt | 10 +++++ .../patch/BypassCertificateChecksPatch.kt | 41 +++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/androidauto/annotations/BypassCertificateChecksCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/androidauto/patch/BypassCertificateChecksPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/annotations/BypassCertificateChecksCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/annotations/BypassCertificateChecksCompatibility.kt new file mode 100644 index 000000000..dbbd31992 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/annotations/BypassCertificateChecksCompatibility.kt @@ -0,0 +1,35 @@ +package app.revanced.patches.music.misc.androidauto.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.apps.youtube.music", + arrayOf( + "5.14.53", + "5.16.51", + "5.17.51", + "5.21.52", + "5.22.54", + "5.23.50", + "5.25.51", + "5.25.52", + "5.26.52", + "5.27.51", + "5.28.52", + "5.29.52", + "5.31.50", + "5.34.51", + "5.36.51", + "5.38.53", + "5.39.52", + "5.40.51", + "5.41.50", + "5.48.52" + ) + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class BypassCertificateChecksCompatibility diff --git a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt new file mode 100644 index 000000000..f0a261588 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/fingerprints/CheckCertificateFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.music.misc.androidauto.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.music.misc.androidauto.patch.BypassCertificateChecksPatch + + +object CheckCertificateFingerprint : MethodFingerprint( + "Z", + strings = listOf("No match") // Unique in combination with boolean return type +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/androidauto/patch/BypassCertificateChecksPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/patch/BypassCertificateChecksPatch.kt new file mode 100644 index 000000000..db5af5baf --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/androidauto/patch/BypassCertificateChecksPatch.kt @@ -0,0 +1,41 @@ +package app.revanced.patches.music.misc.androidauto.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.addInstruction +import app.revanced.patcher.extensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.music.misc.androidauto.annotations.BypassCertificateChecksCompatibility +import app.revanced.patches.music.misc.androidauto.fingerprints.CheckCertificateFingerprint + +@Patch +@Name("bypass-certificate-checks") +@Description("Bypasses certificate checks which prevent YouTube Music from working on Android Auto.") +@BypassCertificateChecksCompatibility +@Version("0.0.1") +class BypassCertificateChecksPatch : BytecodePatch( + listOf( + CheckCertificateFingerprint + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + CheckCertificateFingerprint.result?.let { result -> + val noMatchIndex = result.scanResult.stringsScanResult!!.matches.first().index + + result.mutableMethod.apply { + val isPartnerIndex = noMatchIndex + 2 + + replaceInstruction(isPartnerIndex, "const/4 p1, 0x1") + addInstruction(isPartnerIndex + 1, "return p1") + } + } ?: return CheckCertificateFingerprint.toErrorResult() + + return PatchResultSuccess() + } +} From 47ff447f8ec0e5bbc174f34bd7d61b3031276641 Mon Sep 17 00:00:00 2001 From: johnconner122 <107796137+johnconner122@users.noreply.github.com> Date: Sat, 1 Apr 2023 14:08:14 +0500 Subject: [PATCH 04/34] fix(youtubevanced/hide-ads): hide more types of ads (#1781) --- .../youtubevanced/ad/general/patch/HideAdsPatch.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt index c820e1e46..105b9289e 100644 --- a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt @@ -35,7 +35,7 @@ class HideAdsPatch : BytecodePatch( val adsListRegister = (instruction(insertIndex - 2) as Instruction21c).registerA listOf( - "video_display_full_buttoned_layout", + "_buttoned_layout", "full_width_square_image_layout", "_ad_with", "landscape_image_wide_button_layout", @@ -46,7 +46,9 @@ class HideAdsPatch : BytecodePatch( "video_display_full_layout", "hero_promo_image", "statement_banner", - "primetime_promo" + "primetime_promo", + "carousel_footered_layout", + "feature_grid_interstitial" ).forEach { component -> addInstructions( insertIndex, """ @@ -60,4 +62,4 @@ class HideAdsPatch : BytecodePatch( return PatchResultSuccess() } -} \ No newline at end of file +} From 04a2accfe9f9254af9074ad0a309d485cedb01cb Mon Sep 17 00:00:00 2001 From: Aunali321 <48486084+Aunali321@users.noreply.github.com> Date: Sun, 2 Apr 2023 06:03:57 +0530 Subject: [PATCH 05/34] feat(inshorts): `hide-ads` patch (#1828) --- .../ad/annotations/HideAdsCompatibility.kt | 9 +++++ .../ad/fingerprints/InshortsAdsFingerprint.kt | 9 +++++ .../inshorts/ad/patch/InshortsAdsPatch.kt | 38 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/inshorts/ad/annotations/HideAdsCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/inshorts/ad/fingerprints/InshortsAdsFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/inshorts/ad/patch/InshortsAdsPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/inshorts/ad/annotations/HideAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/inshorts/ad/annotations/HideAdsCompatibility.kt new file mode 100644 index 000000000..372929a12 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/inshorts/ad/annotations/HideAdsCompatibility.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.inshorts.ad.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility([Package("com.nis.app")]) + +@Target(AnnotationTarget.CLASS) +internal annotation class HideAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/inshorts/ad/fingerprints/InshortsAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/inshorts/ad/fingerprints/InshortsAdsFingerprint.kt new file mode 100644 index 000000000..1cbb57933 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/inshorts/ad/fingerprints/InshortsAdsFingerprint.kt @@ -0,0 +1,9 @@ +package app.revanced.patches.inshorts.ad.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object InshortsAdsFingerprint : MethodFingerprint( + "V", + strings = listOf("GoogleAdLoader","exception in requestAd") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/inshorts/ad/patch/InshortsAdsPatch.kt b/src/main/kotlin/app/revanced/patches/inshorts/ad/patch/InshortsAdsPatch.kt new file mode 100644 index 000000000..7c809f6f8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/inshorts/ad/patch/InshortsAdsPatch.kt @@ -0,0 +1,38 @@ +package app.revanced.patches.inshorts.ad.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.inshorts.ad.annotations.HideAdsCompatibility +import app.revanced.patches.inshorts.ad.fingerprints.InshortsAdsFingerprint + +@Patch +@Name("hide-ads") +@Description("Removes ads from Inshorts.") +@HideAdsCompatibility +@Version("0.0.1") +class HideAdsPatch : BytecodePatch( + listOf(InshortsAdsFingerprint) +) { + override fun execute(context: BytecodeContext): PatchResult { + InshortsAdsFingerprint.result?.let { result -> + result.apply { + mutableMethod.addInstruction( + 0, + """ + return-void + """ + ) + } + } ?: return InshortsAdsFingerprint.toErrorResult() + + return PatchResultSuccess() + } +} From b5d712a3326d1e8cdb8d8642aa7bd1bee6e30ac1 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 2 Apr 2023 18:10:26 +0400 Subject: [PATCH 06/34] feat(youtube): sponsorblock improvements (#1557) Co-authored-by: oSumAtrIX --- .../NextGenWatchLayoutFingerprint.kt | 10 - .../patch/SponsorBlockBytecodePatch.kt | 74 +++-- .../patch/VideoInformationPatch.kt | 5 +- .../host/values/strings.xml | 1 + .../sponsorblock/drawable/ic_sb_voting.xml | 10 +- .../host/layout/youtube_controls_layout.xml | 30 +- .../sponsorblock/host/values/strings.xml | 291 ++++++++++-------- .../layout/inline_sponsor_overlay.xml | 22 +- .../sponsorblock/layout/new_segment.xml | 106 +++---- .../layout/skip_sponsor_button.xml | 37 ++- 10 files changed, 346 insertions(+), 240 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/NextGenWatchLayoutFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/NextGenWatchLayoutFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/NextGenWatchLayoutFingerprint.kt deleted file mode 100644 index d17333720..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/fingerprints/NextGenWatchLayoutFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.util.MethodUtil - -object NextGenWatchLayoutFingerprint : MethodFingerprint( - "V", // constructors return void, in favour of speed of matching, this fingerprint has been added - customFingerprint = { methodDef -> MethodUtil.isConstructor(methodDef) && methodDef.parameterTypes.size == 3 && methodDef.definingClass.endsWith("NextGenWatchLayout;") } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt index b7e775ca2..e147ce4d1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.layout.sponsorblock.bytecode.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version @@ -22,10 +23,13 @@ import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.* import app.revanced.patches.youtube.layout.sponsorblock.resource.patch.SponsorBlockResourcePatch +import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatFingerprint +import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParentFingerprint import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch +import app.revanced.patches.youtube.misc.video.speed.remember.patch.RememberPlaybackSpeedPatch import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import org.jf.dexlib2.Opcode import org.jf.dexlib2.iface.instruction.* @@ -38,11 +42,12 @@ import org.jf.dexlib2.iface.reference.StringReference @DependsOn( dependencies = [ VideoInformationPatch::class, // updates video information and adds method to seek in video + VideoIdPatch::class, PlayerControlsBytecodePatch::class, PlayerTypeHookPatch::class, + RememberPlaybackSpeedPatch::class, IntegrationsPatch::class, SponsorBlockResourcePatch::class, - VideoIdPatch::class ] ) @Name("sponsorblock") @@ -52,15 +57,21 @@ import org.jf.dexlib2.iface.reference.StringReference class SponsorBlockBytecodePatch : BytecodePatch( listOf( SeekbarFingerprint, - NextGenWatchLayoutFingerprint, AppendTimeFingerprint, PlayerOverlaysLayoutInitFingerprint, + AutoRepeatParentFingerprint, ) ) { private companion object { - const val INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR = - "Lapp/revanced/integrations/sponsorblock/PlayerController;" + const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/sponsorblock/SegmentPlaybackController;" + const val INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController;" + const val INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/sponsorblock/ui/VotingButtonController;" + const val INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/sponsorblock/ui/SponsorBlockViewController;" } override fun execute(context: BytecodeContext): PatchResult { @@ -69,19 +80,15 @@ class SponsorBlockBytecodePatch : BytecodePatch( */ with(VideoInformationPatch) { videoTimeHook( - INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR, + INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, "setVideoTime" ) - highPrecisionTimeHook( - INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR, - "setHighPrecisionVideoTime" - ) } /* Set current video id */ - VideoIdPatch.injectCallBackgroundPlay("$INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V") + VideoIdPatch.injectCallBackgroundPlay("$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V") /* Seekbar drawing @@ -99,7 +106,7 @@ class SponsorBlockBytecodePatch : BytecodePatch( if (instruction.opcode != Opcode.MOVE_OBJECT_FROM16) continue seekbarMethod.addInstruction( index + 1, - "invoke-static/range {p0 .. p0}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V" + "invoke-static/range {p0 .. p0}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V" ) break } @@ -115,7 +122,7 @@ class SponsorBlockBytecodePatch : BytecodePatch( // set the thickness of the segment seekbarMethod.addInstruction( insertIndex, - "invoke-static {v${invokeInstruction.registerC}}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V" + "invoke-static {v${invokeInstruction.registerC}}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V" ) break } @@ -136,11 +143,11 @@ class SponsorBlockBytecodePatch : BytecodePatch( // the reason for that is that we get the index, add instructions and then the offset would be wrong seekbarMethod.addInstruction( indexLeft + 1, - "invoke-static {v$rectangleLeftRegister}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarAbsoluteLeft(Landroid/graphics/Rect;)V" + "invoke-static {v$rectangleLeftRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarAbsoluteLeft(Landroid/graphics/Rect;)V" ) seekbarMethod.addInstruction( indexRight + 1, - "invoke-static {v$rectangleRightRegister}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarAbsoluteRight(Landroid/graphics/Rect;)V" + "invoke-static {v$rectangleRightRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarAbsoluteRight(Landroid/graphics/Rect;)V" ) /* @@ -152,7 +159,7 @@ class SponsorBlockBytecodePatch : BytecodePatch( } seekbarMethod.addInstruction( drawSegmentInstructionInsertIndex, - "invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V" + "invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V" ) /* @@ -181,8 +188,8 @@ class SponsorBlockBytecodePatch : BytecodePatch( method.addInstructions( moveResultInstructionIndex + 1, // insert right after moving the view to the register and use that register """ - invoke-static {v$inflatedViewRegister}, Lapp/revanced/integrations/sponsorblock/ShieldButton;->initialize(Ljava/lang/Object;)V - invoke-static {v$inflatedViewRegister}, Lapp/revanced/integrations/sponsorblock/VotingButton;->initialize(Ljava/lang/Object;)V + invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Ljava/lang/Object;)V + invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Ljava/lang/Object;)V """ ) } @@ -193,8 +200,8 @@ class SponsorBlockBytecodePatch : BytecodePatch( // change visibility of the buttons invertVisibilityMethod.addInstructions( 0, """ - invoke-static {p1}, Lapp/revanced/integrations/sponsorblock/ShieldButton;->changeVisibilityNegatedImmediate(Z)V - invoke-static {p1}, Lapp/revanced/integrations/sponsorblock/VotingButton;->changeVisibilityNegatedImmediate(Z)V + invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V + invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V """.trimIndent() ) } @@ -203,15 +210,8 @@ class SponsorBlockBytecodePatch : BytecodePatch( } // change visibility of the buttons - PlayerControlsBytecodePatch.injectVisibilityCheckCall("Lapp/revanced/integrations/sponsorblock/ShieldButton;->changeVisibility(Z)V") - PlayerControlsBytecodePatch.injectVisibilityCheckCall("Lapp/revanced/integrations/sponsorblock/VotingButton;->changeVisibility(Z)V") - - // set SegmentHelperLayout.context to the player layout instance - val instanceRegister = 0 - NextGenWatchLayoutFingerprint.result!!.mutableMethod.addInstruction( - 3, // after super call - "invoke-static/range {p$instanceRegister}, $INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR->addSkipSponsorView15(Landroid/view/View;)V" - ) + PlayerControlsBytecodePatch.injectVisibilityCheckCall("$INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibility(Z)V") + PlayerControlsBytecodePatch.injectVisibilityCheckCall("$INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibility(Z)V") // append the new time to the player layout val appendTimeFingerprintResult = AppendTimeFingerprint.result!! @@ -221,18 +221,18 @@ class SponsorBlockBytecodePatch : BytecodePatch( appendTimeFingerprintResult.mutableMethod.addInstructions( appendTimePatternScanStartIndex + 2, """ - invoke-static {v$targetRegister}, Lapp/revanced/integrations/sponsorblock/SponsorBlockUtils;->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String; + invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String; move-result-object v$targetRegister """ ) // initialize the player controller - VideoInformationPatch.onCreateHook(INTEGRATIONS_PLAYER_CONTROLLER_CLASS_DESCRIPTOR, "initialize") + VideoInformationPatch.onCreateHook(INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, "initialize") // initialize the sponsorblock view PlayerOverlaysLayoutInitFingerprint.result!!.mutableMethod.addInstruction( 6, // after inflating the view - "invoke-static {p0}, Lapp/revanced/integrations/sponsorblock/player/ui/SponsorBlockView;->initialize(Ljava/lang/Object;)V" + "invoke-static {p0}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Ljava/lang/Object;)V" ) // get rectangle field name @@ -244,7 +244,7 @@ class SponsorBlockBytecodePatch : BytecodePatch( // replace the "replaceMeWith*" strings context - .proxy(context.classes.first { it.type.endsWith("PlayerController;") }) + .proxy(context.classes.first { it.type.endsWith("SegmentPlaybackController;") }) .mutableClass .methods .find { it.name == "setSponsorBarRect" } @@ -268,6 +268,16 @@ class SponsorBlockBytecodePatch : BytecodePatch( } } ?: return PatchResultError("Could not find the method which contains the replaceMeWith* strings") + + // detect end of the video has been reached + AutoRepeatParentFingerprint.result ?: return AutoRepeatParentFingerprint.toErrorResult() + AutoRepeatFingerprint.also { + it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef) + }.result?.mutableMethod?.addInstruction( + 0, + "invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V" + ) ?: return AutoRepeatFingerprint.toErrorResult() + // TODO: isSBChannelWhitelisting implementation return PatchResultSuccess() diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt index 83a9333a0..7ae872218 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt @@ -122,7 +122,7 @@ class VideoInformationPatch : BytecodePatch( /* Hook the methods which set the time */ - highPrecisionTimeHook(INTEGRATIONS_CLASS_DESCRIPTOR, "setVideoTime") + highPrecisionTimeHook(INTEGRATIONS_CLASS_DESCRIPTOR, "setVideoTimeHighPrecision") return PatchResultSuccess() } @@ -155,6 +155,7 @@ class VideoInformationPatch : BytecodePatch( /** * Hook the video time. + * The hook is usually called once per second. * * @param targetMethodClass The descriptor for the static method to invoke when the player controller is created. * @param targetMethodName The name of the static method to invoke when the player controller is created. @@ -167,6 +168,8 @@ class VideoInformationPatch : BytecodePatch( /** * Hook the high precision video time. + * The hooks is called extremely often (10 to 15 times a seconds), so use with caution. + * Note: the hook is usually called _off_ the main thread * * @param targetMethodClass The descriptor for the static method to invoke when the player controller is created. * @param targetMethodName The name of the static method to invoke when the player controller is created. diff --git a/src/main/resources/returnyoutubedislike/host/values/strings.xml b/src/main/resources/returnyoutubedislike/host/values/strings.xml index e97bbbc1f..31ca93597 100644 --- a/src/main/resources/returnyoutubedislike/host/values/strings.xml +++ b/src/main/resources/returnyoutubedislike/host/values/strings.xml @@ -21,6 +21,7 @@ Like button styled for minimum width Like button styled for best appearance + About ReturnYouTubeDislike.com Dislike data is provided by the Return YouTube Dislike API. Tap here to learn more. diff --git a/src/main/resources/sponsorblock/drawable/ic_sb_voting.xml b/src/main/resources/sponsorblock/drawable/ic_sb_voting.xml index 97db9c98d..30224f149 100644 --- a/src/main/resources/sponsorblock/drawable/ic_sb_voting.xml +++ b/src/main/resources/sponsorblock/drawable/ic_sb_voting.xml @@ -1,9 +1,9 @@ - + android:height="24dp" + android:tint="#FFFFFF" + android:viewportWidth="24" + android:viewportHeight="24"> diff --git a/src/main/resources/sponsorblock/host/layout/youtube_controls_layout.xml b/src/main/resources/sponsorblock/host/layout/youtube_controls_layout.xml index 97796266a..33a11b83b 100644 --- a/src/main/resources/sponsorblock/host/layout/youtube_controls_layout.xml +++ b/src/main/resources/sponsorblock/host/layout/youtube_controls_layout.xml @@ -1,4 +1,28 @@ - - - + + + + + diff --git a/src/main/resources/sponsorblock/host/values/strings.xml b/src/main/resources/sponsorblock/host/values/strings.xml index 2f4838352..3d6ef38c7 100644 --- a/src/main/resources/sponsorblock/host/values/strings.xml +++ b/src/main/resources/sponsorblock/host/values/strings.xml @@ -1,142 +1,173 @@ - Enable SponsorBlock - SponsorBlock is a crowd-sourced system for skipping annoying parts in YouTube videos - Enable new segment adding - Switch this on to enable experimental segment adding (has button visibility issues) - What to do with different segments - General - Show a toast when skipping segment automatically - Click to see an example toast - Skip count tracking - This lets SponsorBlock leaderboard system know how much time people have saved. The extension sends a message to the server each time you skip a segment - Adjusting new segment step - This is the number of milliseconds you can move when you use the time adjustment buttons while adding new segment - Minimum segment duration - Segments shorter than the set value (in seconds) will not be skipped or shown in the player - Your private user id - This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you - Import/Export settings - This is your entire configuration that is applicable in the desktop extension in JSON. This includes your Private userID, so be sure to share this wisely. - Change API URL - The address SponsorBlock uses to make calls to the server. <b>Don\'t change this unless you know what you\'re doing.</b> - Settings were successfully imported - Failed to import settings - Failed to export settings - Cache segments locally - Frequently watched videos (eg. music videos) may store segments in app cache to make skipping segments faster - Clear SponsorBlock segments cache - Sponsor - Paid promotion, paid referrals and direct advertisements - Intermission/Intro Animation - An interval without actual content. Could be a pause, static frame, repeating animation - Endcards/Credits - Credits or when the YouTube endcards appear. Not for spoken conclusions - Interaction Reminder (Subscribe) - When there is a short reminder to like, subscribe, follow or interact with them on any free or paid platform - Unpaid/Self Promotion - When there is unpaid or self promotion. This includes specific sections about merchandise, donations, or information about who they collaborated with - Music: Non-Music Section - Only for use in music videos. Skips parts of the video not in official mixes - Filler Tangent/Jokes - Tangential scenes added only for filler or humor that are not required to understand the main content of the video. This should not include context or background details - Skipped a sponsor segment - Skipped sponsor - Skipped intro - Skipped outro - Skipped annoying reminder - Skipped self promotion - Skipped a non-music section - Skipped preview - Skipped filler - Skipped unsubmitted segment - Skip automatically - Skip automatically once - Show a skip button - Don\'t do anything - Skip segment - About - This app uses the API from SponsorBlock - Tap to learn more, and see downloads for other platforms at: sponsor.ajay.app - Integration made by JakubWeg, recoded by oSumAtrIX - Tap to skip + Enable SponsorBlock + SponsorBlock is a crowd-sourced system for skipping annoying parts of YouTube videos + Show voting button + Segment voting button is shown + Segment voting button is not shown + Show create new segment button + Create new segment button is shown + Create new segment button is not shown + Use compact skip button + Skip button styled for minimum width + Skip button styled for best appearance + What to do with different segments + General + Show a toast when skipping segment automatically + Toast shown when a segment is automatically skipped. Tap here to see an example + Toast not shown. Tap here to see an example + Enable skip count tracking + Lets the SponsorBlock leaderboard know how much time is saved. A message is sent to the leaderboard each time a segment is skipped + Skip count tracking is not enabled + Show video length without segments + Video length minus all segments, shown in parentheses next to the full video length + Full video length shown + Adjust new segment step + Number of milliseconds the time adjustment buttons move when creating new segments + Value must be a positive number + Minimum segment duration + Segments shorter than this value (in seconds) will not be shown or skipped + Your private user id + This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you + User id cannot be blank + Import/Export settings + Your SponsorBlock JSON configuration that can be imported/exported to ReVanced and other SponsorBlock platforms. This includes your private user id. Be sure to share this wisely + Change API URL + The address SponsorBlock uses to make calls to the server. <b>Don\'t change this unless you know what you\'re doing</b> + Settings imported successfully + Failed to import: %s + Failed to export settings (try clearing app data) - Can\'t submit the segment: %s - Unable to submit segments: Status: %d %s - Can\'t submit the segment.\nRate Limited (Too many from the same user or IP) - Can\'t submit the segment.\n\n%s - Can\'t submit the segment.\nAlready exists - Segment submitted successfully - Submitting segment… + Sponsor + Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shout-outs to causes/creators/websites/products they like + Unpaid/Self Promotion + Similar to \'Sponsor\' except for unpaid or self promotion. Includes sections about merchandise, donations, or information about who they collaborated with + Interaction Reminder (Subscribe) + A short reminder to like, subscribe or follow them in the middle of content. If it is long or about something specific, it should instead be under self promotion + Intermission/Intro Animation + An interval without actual content. Could be a pause, static frame, or repeating animation. Does not include transitions containing information + Endcards/Credits + Credits or when the YouTube endcards appear. Not for conclusions with information + Preview/Recap + Collection of clips that show what is coming up or what happened in the video or in other videos of a series, where all information is repeated elsewhere + Filler Tangent/Jokes + Tangential scenes added only for filler or humor that are not required to understand the main content of the video. Does not include segments providing context or background details + Music: Non-Music Section + Only for use in music videos. Sections of music videos without music, that aren\'t already covered by another category - Unable to vote for segment: Status: %d %s - Can\'t vote for segment.\nRate Limited (Too many from the same user or IP) - Can\'t vote for segment.\n\n%s - Voted successfully - Voting for segment… - Upvote - Downvote - Change category - There are no segments to vote for - Enable voting - Switch this on to enable voting. + Skip + Skip sponsor + Skip promo + Skip interact + Skip intro + Skip intermission + Skip intermission + Skip outro + Skip preview + Skip preview + Skip recap + Skip filler + Skip non-music + Skip segment - Choose the segment category - You\'ve disabled this category in the settings, enable it to be able to submit - New SponsorBlock segment - Set %02d:%02d:%04d as the start or end of a new segment? - start - end - now - Time the segment begins at - Time the segment ends at - Beginning of segment set - End of segment set - Are the times correct? - The segment lasts from %02d:%02d to %02d:%02d (%d minutes %02d seconds)\nIs it ready to submit? - Mark two locations on the time bar first - Edit timing of segment manually - Do you want to edit the timing for the start or end of the segment? - Done - Invalid time given + Skipped sponsor + Skipped self promotion + Skipped annoying reminder + Skipped intro + Skipped intermission + Skipped intermission + Skipped outro + Skipped preview + Skipped preview + Skipped recap + Skipped filler + Skipped a non-music section + Skipped unsubmitted segment + Skipped multiple segments + + Skip automatically + Skip automatically once + Show a skip button + Show in seek bar + Disable + + About + Sponsor.Ajay.app + Data is provided by the SponsorBlock API. Tap here to learn more and see downloads for other platforms + ReVanced integration by JakubWeg,\nrecoded by oSumAtrIX + + Can\'t submit the segment: %s + Unable to submit segments (API timed out) + Unable to submit segments (status: %d %s) + Can\'t submit the segment.\nRate Limited (too many from the same user or IP) + Can\'t submit the segment: %s + Can\'t submit the segment.\nAlready exists + Segment submitted successfully + + SponsorBlock temporarily not available + SponsorBlock temporarily not available (status %d) + SponsorBlock temporarily not available (API timed out) + + Unable to vote for segment (API timed out) + Unable to vote for segment (status: %d %s) + Unable to vote for segment: %s + Upvote + Downvote + Change category + There are no segments to vote for + + Choose the segment category + Category is disabled in settings. Enable category to submit. + New SponsorBlock segment + Set %02d:%02d:%04d as the start or end of a new segment? + start + end + now + Time the segment begins at + Time the segment ends at + Are the times correct? + The segment lasts from %02d:%02d to %02d:%02d (%d minutes %02d seconds)\nIs it ready to submit? + Mark two locations on the time bar first + Preview the segment, and ensure it skips smoothly + Edit timing of segment manually + Do you want to edit the timing for the start or end of the segment? + Invalid time given View guidelines - Guidelines contain tips and rules about submitting segments - There are guidelines - It\'s recommended to read the SponsorBlock guidelines before submitting any segment + Guidelines contain rules and tips for creating new segments + Follow the guidelines + Read the SponsorBlock guidelines before creating new segments Already read Show me - Show time without segments - This time appears in brackets next to the current time. This shows the total video duration minus any segments. - Preview/Recap - Recap of previous episodes, or a preview of what\'s coming up later in the current video or future videos in the same series. Clips should not provide additional information. - Stats - Loading.. - SponsorBlock is disabled - Your username: <b>%s</b> - Click to change your username - Unable to change username: Status: %d %s - Username successfully changed - Submissions: <b>%s</b> - You\'ve saved people from <b>%s</b> segments. - That\'s <b>%s</b> of their lives. Click to see the leaderboard - You\'ve skipped <b>%s</b> segments. - That\'s <b>%s</b>. - minutes - Are you looking for changing colors? - You can now change a category\'s color by clicking on it above. - Choose the category - Color changed - Color reset - Invalid hex code - Change - Reset + Stats + Stats temporarily not available (API is down) + Loading... + SponsorBlock is disabled + Your username: <b>%s</b> + Tap here to change your username + Unable to change username: Status: %d %s + Username successfully changed + You\'re reputation is <b>%.2f</b> + You\'ve created <b>%s</b> segments + SponsorBlock leaderboard + You\'ve saved people from <b>%s</b> segments + Tap here to see the global stats and top contributors + That\'s <b>%s</b> of their lives.<br>Tap here to see the leaderboard + You\'ve skipped <b>%s</b> segments + That\'s <b>%s</b> + Reset skipped segments counter? + %d hours %d minutes + %d minutes %d seconds + %d seconds + Color: + Color changed + Color reset + Invalid color code + Reset color - Segments - SB Browser - - API URL changed - API URL reset - Provided API URL is invalid + Reset + API URL reset + API URL is invalid + API URL changed diff --git a/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml b/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml index 6bc670fb9..9f4221735 100644 --- a/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml +++ b/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml @@ -1,5 +1,23 @@ - - + + + + \ No newline at end of file diff --git a/src/main/resources/sponsorblock/layout/new_segment.xml b/src/main/resources/sponsorblock/layout/new_segment.xml index 155907c96..be5020be2 100644 --- a/src/main/resources/sponsorblock/layout/new_segment.xml +++ b/src/main/resources/sponsorblock/layout/new_segment.xml @@ -3,58 +3,58 @@ xmlns:yt="http://schemas.android.com/apk/res-auto"> + android:layout_height="wrap_content" + android:background="#66000000" + android:gravity="start|center" + android:orientation="vertical"> + android:paddingTop="3.0dip" + android:paddingEnd="5.0dip" + android:paddingBottom="3.0dip" + android:src="@drawable/player_fast_rewind" /> + android:paddingTop="3.0dip" + android:paddingEnd="5.0dip" + android:paddingBottom="3.0dip" + android:src="@drawable/player_fast_forward" /> + android:paddingTop="3.0dip" + android:paddingEnd="10.0dip" + android:paddingBottom="3.0dip" + android:src="@drawable/ic_sb_adjust" /> + android:paddingTop="3.0dip" + android:paddingEnd="5.0dip" + android:paddingBottom="3.0dip" + android:src="@drawable/ic_sb_compare" /> + android:paddingTop="3.0dip" + android:paddingEnd="5.0dip" + android:paddingBottom="3.0dip" + android:src="@drawable/ic_sb_edit" /> + android:paddingTop="3.0dip" + android:paddingEnd="10.0dip" + android:paddingBottom="3.0dip" + android:src="@drawable/ic_sb_publish" /> \ No newline at end of file diff --git a/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml b/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml index 3ceb8c362..3a3167bb8 100644 --- a/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml +++ b/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml @@ -1,7 +1,36 @@ - - - - + + + + + + + \ No newline at end of file From b0834faa69755a94f70ae5075a10cf15e8a6b857 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Mon, 3 Apr 2023 05:34:25 +0200 Subject: [PATCH 07/34] fix(youtube/sponsorblock): do not depend on `remember-playback-speed` patch --- .../sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt index e147ce4d1..e82d50d5c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt @@ -45,7 +45,6 @@ import org.jf.dexlib2.iface.reference.StringReference VideoIdPatch::class, PlayerControlsBytecodePatch::class, PlayerTypeHookPatch::class, - RememberPlaybackSpeedPatch::class, IntegrationsPatch::class, SponsorBlockResourcePatch::class, ] From 4f4ceab2cc32a38dd3967fd4e81f690330c08f5c Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 19 Mar 2023 23:24:31 +0100 Subject: [PATCH 08/34] feat(youtube): support version `18.08.37` --- .../autoplay/patch/HideAutoplayButtonPatch.kt | 9 +- .../annotations/PivotBarCompatibility.kt | 5 +- .../CrowdfundingBoxFingerprint.kt | 3 - .../bytecode/patch/CrowdfundingBoxPatch.kt | 25 +++-- .../ReturnYouTubeDislikeCompatibility.kt | 15 +-- .../fingerprints/DislikeFingerprint.kt | 3 - .../fingerprints/LikeFingerprint.kt | 3 - .../fingerprints/RemoveLikeFingerprint.kt | 3 - .../TextComponentConstructorFingerprint.kt | 11 ++ .../fingerprints/TextComponentFingerprint.kt | 8 -- .../TextComponentSpecParentFingerprint.kt | 8 -- .../fingerprints/TextReferenceFingerprint.kt | 14 +++ .../TextReferenceParamFingerprint.kt | 11 ++ .../patch/ReturnYouTubeDislikePatch.kt | 55 +++++---- .../bytecode/patch/SpoofAppVersionPatch.kt | 8 +- ...niPlayerDimensionsCalculatorFingerprint.kt | 2 +- .../MiniPlayerOverrideParentFingerprint.kt | 13 +++ .../patch/TabletMiniPlayerPatch.kt | 38 ++++--- .../FixBackToExitGestureCompatibility.kt | 5 +- .../patch/SpoofSignatureVerificationPatch.kt | 2 +- .../annotations/IntegrationsCompatibility.kt | 5 +- .../fingerprints/InitFingerprint.kt | 2 +- .../ComponentContextParserFingerprint.kt | 7 -- .../EmptyComponentBuilderFingerprint.kt | 1 + .../ReadComponentIdentifierFingerprint.kt | 12 ++ .../litho/filter/patch/LithoFilterPatch.kt | 65 ++++++----- .../fingerprints/IntegrityCheckFingerprint.kt | 10 -- .../patch/bytecode/MicroGBytecodePatch.kt | 4 +- .../fingerprints/ThemeSetterAppFingerprint.kt | 8 +- ...dexMethodClassFieldReferenceFingerprint.kt | 14 +++ ...ideoQualityItemOnClickParentFingerprint.kt | 9 ++ .../VideoQualityReferenceFingerprint.kt | 12 -- .../VideoQualitySetterFingerprint.kt | 5 +- .../VideoUserQualityChangeFingerprint.kt | 20 ---- .../patch/RememberVideoQualityPatch.kt | 105 +++++++++++++----- ...gePlaybackSpeedFragmentStateFingerprint.kt | 8 -- ...nitializePlaybackSpeedValuesFingerprint.kt | 3 +- .../OnPlaybackSpeedItemClickFingerprint.kt | 6 +- .../patch/RememberPlaybackSpeedPatch.kt | 99 ++++++++--------- 39 files changed, 357 insertions(+), 279 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentSpecParentFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceParamFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ReadComponentIdentifierFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/IntegrityCheckFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityItemOnClickParentFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityReferenceFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoUserQualityChangeFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/ChangePlaybackSpeedFragmentStateFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt index cdc013341..2700bbad9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/patch/HideAutoplayButtonPatch.kt @@ -6,6 +6,7 @@ import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.extensions.instruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess @@ -20,6 +21,7 @@ import app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints.LayoutC import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import org.jf.dexlib2.iface.instruction.Instruction +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.WideLiteralInstruction import org.jf.dexlib2.iface.reference.MethodReference @@ -66,12 +68,15 @@ class HideAutoplayButtonPatch : BytecodePatch( val jumpInstruction = layoutGenMethodInstructions[insertIndex + branchIndex] as Instruction + // can be clobbered because this register is overwritten after the injected code + val clobberRegister = (instruction(insertIndex) as OneRegisterInstruction).registerA + addInstructions( insertIndex, """ invoke-static {}, Lapp/revanced/integrations/patches/HideAutoplayButtonPatch;->isButtonShown()Z - move-result v11 - if-eqz v11, :hidden + move-result v$clobberRegister + if-eqz v$clobberRegister, :hidden """, listOf(ExternalLabel("hidden", jumpInstruction)) ) } ?: return LayoutConstructorFingerprint.toErrorResult() diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/annotations/PivotBarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/annotations/PivotBarCompatibility.kt index 6a1a5c71b..64b22133a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/annotations/PivotBarCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/pivotbar/shared/annotations/PivotBarCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt index ef7a8b81b..0ad96367d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/fingerprints/CrowdfundingBoxFingerprint.kt @@ -7,12 +7,9 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction object CrowdfundingBoxFingerprint : MethodFingerprint( opcodes = listOf( - Opcode.CONST_4, - Opcode.CONST, Opcode.INVOKE_VIRTUAL, Opcode.MOVE_RESULT_OBJECT, Opcode.IPUT_OBJECT, - Opcode.CONST, ), customFingerprint = { methodDef -> methodDef.implementation?.instructions?.any { instruction -> diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/patch/CrowdfundingBoxPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/patch/CrowdfundingBoxPatch.kt index 82435026f..94d3b103f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/patch/CrowdfundingBoxPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/bytecode/patch/CrowdfundingBoxPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version @@ -15,7 +16,7 @@ import app.revanced.patches.youtube.layout.hide.crowdfundingbox.annotations.Crow import app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.fingerprints.CrowdfundingBoxFingerprint import app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch.CrowdfundingBoxResourcePatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction +import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction @Patch @DependsOn([IntegrationsPatch::class, CrowdfundingBoxResourcePatch::class]) @@ -29,18 +30,20 @@ class CrowdfundingBoxPatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - val crowdfundingBoxResult = CrowdfundingBoxFingerprint.result!! - val crowdfundingBoxMethod = crowdfundingBoxResult.mutableMethod + CrowdfundingBoxFingerprint.result?.let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + val objectRegister = (instruction(insertIndex) as TwoRegisterInstruction).registerA - val moveResultObjectIndex = - crowdfundingBoxResult.scanResult.patternScanResult!!.endIndex - 2 - - crowdfundingBoxMethod.addInstruction( - moveResultObjectIndex + 1, """ - invoke-static {v${(crowdfundingBoxMethod.instruction(moveResultObjectIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideCrowdfundingBoxPatch;->hideCrowdfundingBox(Landroid/view/View;)V - """ - ) + addInstruction(insertIndex, "invoke-static {v$objectRegister}, $INTEGRATIONS_METHOD_DESCRIPTOR") + } + } ?: return CrowdfundingBoxFingerprint.toErrorResult() return PatchResultSuccess() } + + private companion object { + const val INTEGRATIONS_METHOD_DESCRIPTOR = + "Lapp/revanced/integrations/patches/HideCrowdfundingBoxPatch;->hideCrowdfundingBox(Landroid/view/View;)V" + } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt index c84dbac0d..d3f7bd41c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/annotations/ReturnYouTubeDislikeCompatibility.kt @@ -3,19 +3,6 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40" - ) - )] -) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.08.37"))]) @Target(AnnotationTarget.CLASS) internal annotation class ReturnYouTubeDislikeCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikeFingerprint.kt index 81c56995c..63609aff7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikeFingerprint.kt @@ -1,11 +1,8 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints -import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags object DislikeFingerprint : MethodFingerprint( "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, strings = listOf("like/dislike") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt index f3d9a8f04..5761a395e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt @@ -1,14 +1,11 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints -import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags @FuzzyPatternScanMethod(2) object LikeFingerprint : MethodFingerprint( "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, strings = listOf("like/like") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt index 17b43b252..9c226ccf8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt @@ -1,11 +1,8 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints -import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags object RemoveLikeFingerprint : MethodFingerprint( "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, strings = listOf("like/removelike") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt new file mode 100644 index 000000000..ca29b8eee --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints + + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags + +object TextComponentConstructorFingerprint : MethodFingerprint( + access = AccessFlags.CONSTRUCTOR or AccessFlags.PRIVATE, + strings = listOf("TextComponent") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentFingerprint.kt deleted file mode 100644 index dadd8e607..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object TextComponentFingerprint : MethodFingerprint( - strings = listOf("com.google.android.apps.youtube.music") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentSpecParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentSpecParentFingerprint.kt deleted file mode 100644 index 631ca5f77..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentSpecParentFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object TextComponentSpecParentFingerprint : MethodFingerprint( - strings = listOf("TextComponentSpec: No converter for extension: ") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceFingerprint.kt new file mode 100644 index 000000000..763aef752 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints + + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object TextReferenceFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.INVOKE_STATIC_RANGE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_DIRECT, + Opcode.INVOKE_VIRTUAL + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceParamFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceParamFingerprint.kt new file mode 100644 index 000000000..f81420fcb --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceParamFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object TextReferenceParamFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.MOVE_OBJECT, + Opcode.MOVE_OBJECT_FROM16 // the first occurrence of this instruction uses the register for the text object + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt index 6a63c83d0..b483afa1d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt @@ -25,7 +25,9 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import org.jf.dexlib2.builder.instruction.BuilderInstruction35c +import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction +import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction @Patch @DependsOn( @@ -42,7 +44,7 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Version("0.0.1") class ReturnYouTubeDislikePatch : BytecodePatch( listOf( - TextComponentSpecParentFingerprint, + TextComponentConstructorFingerprint, ShortsTextComponentParentFingerprint, LikeFingerprint, DislikeFingerprint, @@ -78,27 +80,37 @@ class ReturnYouTubeDislikePatch : BytecodePatch( // region Hook components - TextComponentFingerprint.also { it.resolve(context, TextComponentSpecParentFingerprint.result!!.classDef) } - .result?.let { - with(it.mutableMethod) { - val createComponentMethod = this + TextReferenceFingerprint.also { + it.resolve( + context, + TextComponentConstructorFingerprint.result!!.classDef + ) + }.result?.let { result -> + val moveTextRefParamInstructionIndex = TextReferenceParamFingerprint.also { + if (!TextReferenceParamFingerprint.resolve(context, result.method, result.classDef)) + return TextReferenceParamFingerprint.toErrorResult() + }.result!!.scanResult.patternScanResult!!.endIndex - val conversionContextParam = 5 - val textRefParam = createComponentMethod.parameters.size - 2 - // Insert index must be 0, otherwise UI does not updated correctly in some situations - // such as switching from full screen or when using previous/next overlay buttons. - val insertIndex = 0 + result.mutableMethod.apply { + val insertIndex = result.scanResult.patternScanResult!!.endIndex - createComponentMethod.addInstructions( - insertIndex, - """ - move-object/from16 v7, p$conversionContextParam - move-object/from16 v8, p$textRefParam - invoke-static {v7, v8}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onComponentCreated(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;)V - """ - ) - } - } ?: return TextComponentFingerprint.toErrorResult() + val atomicReferenceInstruction = (instruction(insertIndex - 1) as FiveRegisterInstruction) + val conversionContextParam = atomicReferenceInstruction.registerC + val textRefParam = (instruction(moveTextRefParamInstructionIndex) as TwoRegisterInstruction).registerA + + // Overwritten after injected code, which is why it can be used. + val clobberRegister = atomicReferenceInstruction.registerD + + addInstructions( + insertIndex, + """ + # required instruction, otherwise register might be out of range + move-object/from16 v$clobberRegister, v$textRefParam + invoke-static {v$clobberRegister, v$conversionContextParam}, $ON_COMPONENT_CREATED_DESCRIPTOR + """ + ) + } + } ?: return TextReferenceFingerprint.toErrorResult() ShortsTextComponentParentFingerprint.result?.let { context @@ -138,6 +150,9 @@ class ReturnYouTubeDislikePatch : BytecodePatch( const val INTEGRATIONS_PATCH_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;" + const val ON_COMPONENT_CREATED_DESCRIPTOR = + "$INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onComponentCreated(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;)V" + private fun MethodFingerprint.toPatch(voteKind: Vote) = VotePatch(this, voteKind) } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt index 3a3b5c81b..8c071d31a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt @@ -30,10 +30,6 @@ class SpoofAppVersionPatch : BytecodePatch( SpoofAppVersionFingerprint ) ) { - companion object { - const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/SpoofAppVersionPatch" - } - override fun execute(context: BytecodeContext): PatchResult { SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( SwitchPreference( @@ -61,4 +57,8 @@ class SpoofAppVersionPatch : BytecodePatch( return PatchResultSuccess() } + + private companion object { + const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/SpoofAppVersionPatch" + } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt index a378eaf65..247655248 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerDimensionsCalculatorFingerprint.kt @@ -7,7 +7,7 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode -@FuzzyPatternScanMethod(2) // TODO: Find a good threshold value +@FuzzyPatternScanMethod(2) object MiniPlayerDimensionsCalculatorFingerprint : MethodFingerprint( "V", AccessFlags.PUBLIC or AccessFlags.FINAL, diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt new file mode 100644 index 000000000..49a394933 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/fingerprints/MiniPlayerOverrideParentFingerprint.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags + + +object MiniPlayerOverrideParentFingerprint : MethodFingerprint( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("L"), + strings = listOf("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt index 8c4269ee2..a290173e6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/patch/TabletMiniPlayerPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.layout.tabletminiplayer.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version @@ -16,10 +17,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility -import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorFingerprint -import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint -import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint -import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint +import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.* import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @@ -33,7 +31,8 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction class TabletMiniPlayerPatch : BytecodePatch( listOf( MiniPlayerDimensionsCalculatorFingerprint, - MiniPlayerResponseModelSizeCheckFingerprint + MiniPlayerResponseModelSizeCheckFingerprint, + MiniPlayerOverrideParentFingerprint ) ) { override fun execute(context: BytecodeContext): PatchResult { @@ -47,33 +46,42 @@ class TabletMiniPlayerPatch : BytecodePatch( ) ) - // first resolve the fingerprints via the parent fingerprint + // First resolve the fingerprints via the parent fingerprint. val miniPlayerClass = MiniPlayerDimensionsCalculatorFingerprint.result!!.classDef /* - * no context parameter method + * No context parameter method. */ MiniPlayerOverrideNoContextFingerprint.resolve(context, miniPlayerClass) val (method, _, parameterRegister) = MiniPlayerOverrideNoContextFingerprint.addProxyCall() - // - 1 means to insert before the return instruction + + // Insert right before the return instruction. val secondInsertIndex = method.implementation!!.instructions.size - 1 - method.insertOverride(secondInsertIndex, parameterRegister /** same register used to return **/) + method.insertOverride( + secondInsertIndex, parameterRegister + /** same register used to return **/ + ) /* - * method with context parameter + * Method with context parameter. */ - MiniPlayerOverrideFingerprint.resolve(context, miniPlayerClass) - val (_, _, _) = MiniPlayerOverrideFingerprint.addProxyCall() + MiniPlayerOverrideParentFingerprint.result?.let { + if (!MiniPlayerOverrideFingerprint.resolve(context, it.classDef)) + return MiniPlayerOverrideFingerprint.toErrorResult() + + MiniPlayerOverrideFingerprint.addProxyCall() + + } ?: return MiniPlayerOverrideParentFingerprint.toErrorResult() /* - * size check return value override + * Size check return value override. */ - val (_, _, _) = MiniPlayerResponseModelSizeCheckFingerprint.addProxyCall() + MiniPlayerResponseModelSizeCheckFingerprint.addProxyCall() return PatchResultSuccess() } - // helper methods + // Helper methods. private companion object { fun MethodFingerprint.addProxyCall(): Triple { val (method, scanIndex, parameterRegister) = this.unwrap() diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt index 7ba4cfcf2..88d68b981 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/annotation/FixBackToExitGestureCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt index a8c48cbd1..d40cf2281 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt @@ -107,7 +107,7 @@ class SpoofSignatureVerificationPatch : BytecodePatch( return PatchResultSuccess() } - companion object { + private companion object { const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/SpoofSignatureVerificationPatch;" } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt index 293035d7e..96fc2e7fc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/InitFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/InitFingerprint.kt index 730e856c1..be3b5d8b7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/InitFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/fingerprints/InitFingerprint.kt @@ -3,5 +3,5 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints import app.revanced.patches.shared.integrations.patch.AbstractIntegrationsPatch.IntegrationsFingerprint object InitFingerprint : IntegrationsFingerprint( - strings = listOf("Application creation"), + strings = listOf("Application creation", "Application.onCreate"), ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt index 7f661ac49..a57ae700f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt @@ -5,13 +5,6 @@ import org.jf.dexlib2.Opcode object ComponentContextParserFingerprint : MethodFingerprint( opcodes = listOf( - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.GOTO, - Opcode.INVOKE_VIRTUAL, - Opcode.CONST_16, Opcode.INVOKE_VIRTUAL, Opcode.IPUT_OBJECT, Opcode.NEW_INSTANCE diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/EmptyComponentBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/EmptyComponentBuilderFingerprint.kt index 1842275a5..7c77b9f96 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/EmptyComponentBuilderFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/EmptyComponentBuilderFingerprint.kt @@ -5,6 +5,7 @@ import org.jf.dexlib2.Opcode object EmptyComponentBuilderFingerprint : MethodFingerprint( opcodes = listOf( + Opcode.INVOKE_INTERFACE, Opcode.INVOKE_STATIC_RANGE ), ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ReadComponentIdentifierFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ReadComponentIdentifierFingerprint.kt new file mode 100644 index 000000000..b78e48af1 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ReadComponentIdentifierFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.youtube.misc.litho.filter.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object ReadComponentIdentifierFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.IF_NEZ, + null, + Opcode.MOVE_RESULT_OBJECT // Register stores the component identifier string + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt index 9ea24e433..96dfba82c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/patch/LithoFilterPatch.kt @@ -1,10 +1,12 @@ package app.revanced.patches.youtube.misc.litho.filter.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.instruction +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult @@ -16,12 +18,10 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.litho.filter.annotation.LithoFilterCompatibility import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ComponentContextParserFingerprint import app.revanced.patches.youtube.misc.litho.filter.fingerprints.EmptyComponentBuilderFingerprint +import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ReadComponentIdentifierFingerprint import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction -import org.jf.dexlib2.iface.reference.FieldReference -import org.jf.dexlib2.iface.reference.MethodReference @DependsOn([IntegrationsPatch::class]) @Description("Hooks the method which parses the bytes into a ComponentContext to filter components.") @@ -31,33 +31,40 @@ class LithoFilterPatch : BytecodePatch( listOf(ComponentContextParserFingerprint) ) { override fun execute(context: BytecodeContext): PatchResult { - ComponentContextParserFingerprint.result?.let { result -> - val builderMethodIndex = EmptyComponentBuilderFingerprint - .also { it.resolve(context, result.mutableMethod, result.mutableClass) } - .let { it.result!!.scanResult.patternScanResult!!.startIndex } - + ComponentContextParserFingerprint.result?.also { + arrayOf(EmptyComponentBuilderFingerprint, ReadComponentIdentifierFingerprint).forEach { fingerprint -> + if (!fingerprint.resolve(context, it.mutableMethod, it.mutableClass)) + return fingerprint.toErrorResult() + } + }?.let { result -> + val builderMethodIndex = EmptyComponentBuilderFingerprint.patternScanEndIndex val emptyComponentFieldIndex = builderMethodIndex + 2 - with(result.mutableMethod) { + result.mutableMethod.apply { val insertHookIndex = result.scanResult.patternScanResult!!.endIndex - val clobberedRegister = (instruction(insertHookIndex - 3) as OneRegisterInstruction).registerA + val builderMethodDescriptor = instruction(builderMethodIndex).descriptor + val emptyComponentFieldDescriptor = instruction(emptyComponentFieldIndex).descriptor + // Register is overwritten right after it is used for this patch, therefore free to clobber. + val clobberedRegister = instruction(insertHookIndex).oneRegister - val builderMethodDescriptor = instruction(builderMethodIndex).toDescriptor() - val emptyComponentFieldDescriptor = instruction(emptyComponentFieldIndex).toDescriptor() + @Suppress("UnnecessaryVariable") + // The register, this patch clobbers, is previously used for the StringBuilder, + // later on a new StringBuilder is instantiated on it. + val stringBuilderRegister = clobberedRegister - val stringBuilderRegister = (instruction(insertHookIndex - 1) as TwoRegisterInstruction).registerA + val identifierRegister = instruction(ReadComponentIdentifierFingerprint.patternScanEndIndex).oneRegister addInstructions( insertHookIndex, // right after setting the component.pathBuilder field, """ - invoke-static {v$stringBuilderRegister, v0}, Lapp/revanced/integrations/patches/LithoFilterPatch;->filter(Ljava/lang/StringBuilder;Ljava/lang/String;)Z + invoke-static {v$stringBuilderRegister, v$identifierRegister}, Lapp/revanced/integrations/patches/LithoFilterPatch;->filter(Ljava/lang/StringBuilder;Ljava/lang/String;)Z move-result v$clobberedRegister if-eqz v$clobberedRegister, :not_an_ad - move-object/from16 v0, p1 - invoke-static {v0}, $builderMethodDescriptor - move-result-object v0 - iget-object v0, v0, $emptyComponentFieldDescriptor - return-object v0 + move-object/from16 v$clobberedRegister, p1 + invoke-static {v$clobberedRegister}, $builderMethodDescriptor + move-result-object v$clobberedRegister + iget-object v$clobberedRegister, v$clobberedRegister, $emptyComponentFieldDescriptor + return-object v$clobberedRegister """, listOf(ExternalLabel("not_an_ad", instruction(insertHookIndex))) ) @@ -68,14 +75,14 @@ class LithoFilterPatch : BytecodePatch( } private companion object { - fun Instruction.toDescriptor() = when (val reference = (this as? ReferenceInstruction)?.reference) { - is MethodReference -> "${reference.definingClass}->${reference.name}(${ - reference.parameterTypes.joinToString( - "" - ) { it } - })${reference.returnType}" - is FieldReference -> "${reference.definingClass}->${reference.name}:${reference.type}" - else -> throw PatchResultError("Unsupported reference type") - } + val MethodFingerprint.patternScanEndIndex + get() = result!!.scanResult.patternScanResult!!.endIndex + + val Instruction.descriptor + get() = (this as ReferenceInstruction).reference.toString() + + val Instruction.oneRegister + get() = (this as OneRegisterInstruction).registerA + } -} +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/IntegrityCheckFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/IntegrityCheckFingerprint.kt deleted file mode 100644 index f3d41191b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/fingerprints/IntegrityCheckFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.microg.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object IntegrityCheckFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L"), - strings = listOf("This should never happen.", "GooglePlayServicesUtil", "Google Play Store signature invalid.") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt index 22b1a65da..72b6135a6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt @@ -10,8 +10,8 @@ import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch import app.revanced.patches.shared.fingerprints.WatchWhileActivityFingerprint -import app.revanced.patches.youtube.layout.buttons.cast.patch.HideCastButtonPatch import app.revanced.patches.shared.misc.fix.spoof.patch.ClientSpoofPatch +import app.revanced.patches.youtube.layout.buttons.cast.patch.HideCastButtonPatch import app.revanced.patches.youtube.misc.fix.playback.patch.SpoofSignatureVerificationPatch import app.revanced.patches.youtube.misc.microg.annotations.MicroGPatchCompatibility import app.revanced.patches.youtube.misc.microg.fingerprints.* @@ -34,7 +34,6 @@ import app.revanced.util.microg.MicroGBytecodeHelper @Version("0.0.1") class MicroGBytecodePatch : BytecodePatch( listOf( - IntegrityCheckFingerprint, ServiceCheckFingerprint, GooglePlayUtilityFingerprint, CastDynamiteModuleFingerprint, @@ -59,7 +58,6 @@ class MicroGBytecodePatch : BytecodePatch( REVANCED_PACKAGE_NAME ), listOf( - IntegrityCheckFingerprint, ServiceCheckFingerprint, GooglePlayUtilityFingerprint, CastDynamiteModuleFingerprint, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterAppFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterAppFingerprint.kt index 01c4c1087..1fceecd38 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterAppFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/bytecode/fingerprints/ThemeSetterAppFingerprint.kt @@ -10,16 +10,16 @@ object ThemeSetterAppFingerprint : MethodFingerprint( AccessFlags.PUBLIC or AccessFlags.STATIC, parameters = listOf("L", "L", "L", "L"), opcodes = listOf( - Opcode.CONST, //target reference + Opcode.CONST, // target reference Opcode.GOTO, - Opcode.CONST, //target reference + Opcode.CONST, // target reference Opcode.INVOKE_DIRECT, Opcode.RETURN_OBJECT, Opcode.NEW_INSTANCE, - Opcode.INVOKE_INTERFACE, + null, // changed from invoke interface to invoke virtual Opcode.MOVE_RESULT_OBJECT, Opcode.SGET_OBJECT, Opcode.IF_NE, - Opcode.CONST, //target reference + Opcode.CONST, // target reference ) ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt new file mode 100644 index 000000000..896b5de3e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/SetQualityByIndexMethodClassFieldReferenceFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.misc.video.quality.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object SetQualityByIndexMethodClassFieldReferenceFingerprint : MethodFingerprint( + returnType = "V", + parameters = listOf("L"), + opcodes = listOf( + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.RETURN_VOID + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityItemOnClickParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityItemOnClickParentFingerprint.kt new file mode 100644 index 000000000..592c62fc0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityItemOnClickParentFingerprint.kt @@ -0,0 +1,9 @@ + +package app.revanced.patches.youtube.misc.video.quality.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object VideoQualityItemOnClickParentFingerprint : MethodFingerprint( + "V", + strings = listOf("VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityReferenceFingerprint.kt deleted file mode 100644 index 3ea366f78..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualityReferenceFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.misc.video.quality.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object VideoQualityReferenceFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( - Opcode.IPUT_OBJECT, Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualitySetterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualitySetterFingerprint.kt index db1853c17..9a29d162b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualitySetterFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoQualitySetterFingerprint.kt @@ -9,12 +9,13 @@ import org.jf.dexlib2.Opcode object VideoQualitySetterFingerprint : MethodFingerprint( "V", AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("[L", "I", "I", "Z", "I"), + listOf("[L", "I", "Z"), listOf( Opcode.IF_EQZ, Opcode.INVOKE_VIRTUAL, Opcode.MOVE_RESULT_OBJECT, Opcode.INVOKE_VIRTUAL, Opcode.IPUT_BOOLEAN, - ) + ), + strings = listOf("menu_item_video_quality"), ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoUserQualityChangeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoUserQualityChangeFingerprint.kt deleted file mode 100644 index 2575d5d3d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/fingerprints/VideoUserQualityChangeFingerprint.kt +++ /dev/null @@ -1,20 +0,0 @@ - -package app.revanced.patches.youtube.misc.video.quality.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object VideoUserQualityChangeFingerprint : MethodFingerprint( - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L","L","I","J"), - listOf( - Opcode.MOVE, - Opcode.MOVE_WIDE, - Opcode.INVOKE_INTERFACE_RANGE, - Opcode.RETURN_VOID - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt index 416ef3f04..28b382d76 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.misc.video.quality.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version @@ -9,6 +10,7 @@ import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch @@ -17,9 +19,9 @@ import app.revanced.patches.shared.settings.preference.impl.SwitchPreference 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.video.quality.annotations.RememberVideoQualityCompatibility -import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoQualityReferenceFingerprint +import app.revanced.patches.youtube.misc.video.quality.fingerprints.SetQualityByIndexMethodClassFieldReferenceFingerprint +import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoQualityItemOnClickParentFingerprint import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoQualitySetterFingerprint -import app.revanced.patches.youtube.misc.video.quality.fingerprints.VideoUserQualityChangeFingerprint import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.reference.FieldReference @@ -32,14 +34,18 @@ import org.jf.dexlib2.iface.reference.FieldReference @Version("0.0.1") class RememberVideoQualityPatch : BytecodePatch( listOf( - VideoQualitySetterFingerprint + VideoQualitySetterFingerprint, + VideoQualityItemOnClickParentFingerprint ) ) { override fun execute(context: BytecodeContext): PatchResult { SettingsPatch.PreferenceScreen.MISC.addPreferences( SwitchPreference( "revanced_remember_video_quality_last_selected", - StringResource("revanced_remember_video_quality_last_selected_title", "Remember video quality changes"), + StringResource( + "revanced_remember_video_quality_last_selected_title", + "Remember video quality changes" + ), true, StringResource( "revanced_remember_video_quality_last_selected_summary_on", @@ -52,37 +58,80 @@ class RememberVideoQualityPatch : BytecodePatch( ) ) - val setterMethod = VideoQualitySetterFingerprint.result!! + /* + * The following code works by hooking the method which is called when the user selects a video quality + * to remember the last selected video quality. + * + * It also hooks the method which is called when the video quality to set is determined. + * Conveniently, at this point the video quality is overridden to the remembered playback speed. + */ - VideoUserQualityChangeFingerprint.resolve(context, setterMethod.classDef) - val userQualityMethod = VideoUserQualityChangeFingerprint.result!! + VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;)V") - VideoQualityReferenceFingerprint.resolve(context, setterMethod.classDef) - val qualityFieldReference = - VideoQualityReferenceFingerprint.result!!.method.let { method -> - (method.implementation!!.instructions.elementAt(0) as ReferenceInstruction).reference as FieldReference - } + // Inject a call to set the remembered quality once a video loads. + VideoQualitySetterFingerprint.result?.also { + if (!SetQualityByIndexMethodClassFieldReferenceFingerprint.resolve(context, it.classDef)) + return PatchResultError("Could not resolve fingerprint to find setQualityByIndex method") + }?.let { + // This instruction refers to the field with the type that contains the setQualityByIndex method. + val instructions = SetQualityByIndexMethodClassFieldReferenceFingerprint.result!! + .method.implementation!!.instructions - VideoIdPatch.injectCall("Lapp/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch;->newVideoStarted(Ljava/lang/String;)V") + val getOnItemClickListenerClassReference = + (instructions.elementAt(0) as ReferenceInstruction).reference + val getSetQualityByIndexMethodClassFieldReference = + (instructions.elementAt(1) as ReferenceInstruction).reference - val qIndexMethodName = - context.classes.single { it.type == qualityFieldReference.type }.methods.single { it.parameterTypes.first() == "I" }.name + val setQualityByIndexMethodClassFieldReference = + getSetQualityByIndexMethodClassFieldReference as FieldReference - setterMethod.mutableMethod.addInstructions( - 0, - """ - iget-object v0, p0, ${setterMethod.classDef.type}->${qualityFieldReference.name}:${qualityFieldReference.type} - const-string v1, "$qIndexMethodName" - invoke-static {p1, p2, v0, v1}, Lapp/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch;->setVideoQuality([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I - move-result p2 - """, - ) + val setQualityByIndexMethodClass = context.classes + .find { classDef -> classDef.type == setQualityByIndexMethodClassFieldReference.type }!! - userQualityMethod.mutableMethod.addInstruction( - 0, - "invoke-static {p3}, Lapp/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch;->userChangedQuality(I)V" - ) + // Get the name of the setQualityByIndex method. + val setQualityByIndexMethod = setQualityByIndexMethodClass.methods + .find { method -> method.parameterTypes.first() == "I" } + ?: return PatchResultError("Could not find setQualityByIndex method") + it.mutableMethod.addInstructions( + 0, + """ + # Get the object instance to invoke the setQualityByIndex method on. + iget-object v0, p0, $getOnItemClickListenerClassReference + iget-object v0, v0, $getSetQualityByIndexMethodClassFieldReference + + # Get the method name. + const-string v1, "${setQualityByIndexMethod.name}" + + # Set the quality. + # The first parameter is the array list of video qualities. + # The second parameter is the index of the selected quality. + # The register v0 stores the object instance to invoke the setQualityByIndex method on. + # The register v1 stores the name of the setQualityByIndex method. + invoke-static {p1, p2, v0, v1}, $INTEGRATIONS_CLASS_DESCRIPTOR->setVideoQuality([Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/String;)I + move-result p2 + """, + ) + } ?: return VideoQualitySetterFingerprint.toErrorResult() + + // Inject a call to remember the selected quality. + VideoQualityItemOnClickParentFingerprint.result?.let { + val onItemClickMethod = it.mutableClass.methods.find { method -> method.name == "onItemClick" } + + onItemClickMethod?.apply { + val listItemIndexParameter = 3 + + addInstruction( + 0, + "invoke-static {p$listItemIndexParameter}, $INTEGRATIONS_CLASS_DESCRIPTOR->userChangedQuality(I)V" + ) + } ?: return PatchResultError("Failed to find onItemClick method") + } ?: return VideoQualityItemOnClickParentFingerprint.toErrorResult() return PatchResultSuccess() } + + private companion object { + const val INTEGRATIONS_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch;" + } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/ChangePlaybackSpeedFragmentStateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/ChangePlaybackSpeedFragmentStateFingerprint.kt deleted file mode 100644 index cb1aca4f6..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/ChangePlaybackSpeedFragmentStateFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.youtube.misc.video.speed.remember.fingerprint - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -object ChangePlaybackSpeedFragmentStateFingerprint : MethodFingerprint( - "V", - strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt index 140e243cb..e244a298e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt @@ -3,5 +3,6 @@ package app.revanced.patches.youtube.misc.video.speed.remember.fingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint object InitializePlaybackSpeedValuesFingerprint : MethodFingerprint( - parameters = listOf("[L", "I") + parameters = listOf("[L", "I"), + strings = listOf("menu_item_playback_speed") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/OnPlaybackSpeedItemClickFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/OnPlaybackSpeedItemClickFingerprint.kt index 059d31783..e92afa1c9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/OnPlaybackSpeedItemClickFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/OnPlaybackSpeedItemClickFingerprint.kt @@ -6,7 +6,9 @@ import org.jf.dexlib2.Opcode object OnPlaybackSpeedItemClickFingerprint : MethodFingerprint( customFingerprint = { it.name == "onItemClick" }, opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.INVOKE_VIRTUAL, + Opcode.RETURN_VOID ) ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt index ecd909fc0..ca2260853 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt @@ -8,8 +8,6 @@ import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.* import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch @@ -19,12 +17,12 @@ import app.revanced.patches.shared.settings.preference.impl.SwitchPreference 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.video.speed.remember.annotation.RememberPlaybackSpeedCompatibility -import app.revanced.patches.youtube.misc.video.speed.remember.fingerprint.ChangePlaybackSpeedFragmentStateFingerprint import app.revanced.patches.youtube.misc.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint import app.revanced.patches.youtube.misc.video.speed.remember.fingerprint.OnPlaybackSpeedItemClickFingerprint import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import org.jf.dexlib2.Opcode import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction +import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction @Patch @@ -34,7 +32,10 @@ import org.jf.dexlib2.iface.instruction.ReferenceInstruction @RememberPlaybackSpeedCompatibility @Version("0.0.1") class RememberPlaybackSpeedPatch : BytecodePatch( - listOf(ChangePlaybackSpeedFragmentStateFingerprint) + listOf( + OnPlaybackSpeedItemClickFingerprint, + InitializePlaybackSpeedValuesFingerprint + ) ) { override fun execute(context: BytecodeContext): PatchResult { SettingsPatch.PreferenceScreen.MISC.addPreferences( @@ -56,54 +57,67 @@ class RememberPlaybackSpeedPatch : BytecodePatch( ) ) - context.resolveFingerprints() - VideoIdPatch.injectCall("${INTEGRATIONS_CLASS_DESCRIPTOR}->newVideoLoaded(Ljava/lang/String;)V") + /* + * The following code works by hooking the method which is called when the user selects a playback speed + * to remember the last selected playback speed. + * + * It also hooks the method which is called when the playback speeds are initialized. + * Conveniently, at this point the playback speed is set to the remembered playback speed. + */ + + // Set the remembered playback speed. - InitializePlaybackSpeedValuesFingerprint.result!!.apply { - // Infer everything necessary for setPlaybackSate() + InitializePlaybackSpeedValuesFingerprint.result?.apply { + // Infer everything necessary for calling the method setPlaybackSpeed(). + val instructions = OnPlaybackSpeedItemClickFingerprint.result!!.mutableMethod.implementation!!.instructions + fun getReference(offset: Int = 0, opcode: Opcode) = + instructions[instructions.indexOfFirst { it.opcode == opcode } + offset].reference - val playbackHandlerWrapperFieldReference = - (object : MethodFingerprint(opcodes = listOf(Opcode.IF_EQZ)) {}).apply { - OnPlaybackSpeedItemClickFingerprint.result!!.apply { - resolve( - context, - method, - classDef - ) - } - }.getReference(-1) - val playbackHandlerWrapperImplementorClassReference = OnPlaybackSpeedItemClickFingerprint - .getReference(-1) - val playbackHandlerFieldReference = OnPlaybackSpeedItemClickFingerprint - .getReference() - val setPlaybackSpeedMethodReference = OnPlaybackSpeedItemClickFingerprint - .getReference(1) + val setPlaybackSpeedContainerClassFieldReference = + getReference(-1, Opcode.IF_EQZ) + val setPlaybackSpeedClassFieldReference = + getReference(1, Opcode.IGET) + + val setPlaybackSpeedMethodReference = + getReference(2, Opcode.IGET) + + val onItemClickListenerClassFieldReference = mutableMethod.instruction(0).reference + + // Registers are not used at index 0, so they can be freely used. mutableMethod.addInstructions( 0, """ invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->getCurrentPlaybackSpeed()F move-result v0 - # check if the playback speed is not 1.0x + + # Check if the playback speed is not 1.0x. const/high16 v1, 0x3f800000 # 1.0f cmpg-float v1, v0, v1 if-eqz v1, :do_not_override + + # Get the instance of the class which has the container class field below. + iget-object v1, p0, $onItemClickListenerClassFieldReference - # invoke setPlaybackSpeed - iget-object v1, p0, $playbackHandlerWrapperFieldReference - check-cast v1, $playbackHandlerWrapperImplementorClassReference - iget-object v2, v1, $playbackHandlerFieldReference + # Get the container class field. + iget-object v1, v1, $setPlaybackSpeedContainerClassFieldReference + + # Get the field from its class. + iget-object v2, v1, $setPlaybackSpeedClassFieldReference + + # Invoke setPlaybackSpeed on that class. invoke-virtual {v2, v0}, $setPlaybackSpeedMethodReference """.trimIndent(), listOf(ExternalLabel("do_not_override", mutableMethod.instruction(0))) ) - } + } ?: return InitializePlaybackSpeedValuesFingerprint.toErrorResult() // Remember the selected playback speed. - OnPlaybackSpeedItemClickFingerprint.result!!.apply { - val setPlaybackSpeedIndex = scanResult.patternScanResult!!.endIndex + OnPlaybackSpeedItemClickFingerprint.result?.apply { + val setPlaybackSpeedIndex = scanResult.patternScanResult!!.startIndex - 3 + val selectedPlaybackSpeedRegister = (mutableMethod.instruction(setPlaybackSpeedIndex) as FiveRegisterInstruction).registerD @@ -111,8 +125,7 @@ class RememberPlaybackSpeedPatch : BytecodePatch( setPlaybackSpeedIndex, "invoke-static { v$selectedPlaybackSpeedRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->setPlaybackSpeed(F)V" ) - } - + } ?: return OnPlaybackSpeedItemClickFingerprint.toErrorResult() return PatchResultSuccess() } @@ -121,20 +134,6 @@ class RememberPlaybackSpeedPatch : BytecodePatch( const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch;" - fun MethodFingerprint.getReference(offsetFromPatternScanResultStartIndex: Int = 0) = this.result!!.let { - val referenceInstruction = it.mutableMethod - .instruction(it.scanResult.patternScanResult!!.startIndex + offsetFromPatternScanResultStartIndex) as ReferenceInstruction - referenceInstruction.reference.toString() - } - - fun BytecodeContext.resolveFingerprints() { - ChangePlaybackSpeedFragmentStateFingerprint.result?.also { - fun MethodFingerprint.resolve() = resolve(this@resolveFingerprints, it.classDef) - - OnPlaybackSpeedItemClickFingerprint.resolve() - InitializePlaybackSpeedValuesFingerprint.resolve() - - } ?: throw ChangePlaybackSpeedFragmentStateFingerprint.toErrorResult() - } + val Instruction.reference get() = (this as ReferenceInstruction).reference.toString() } -} +} \ No newline at end of file From 29561eca10e18e11f2d4a7f9bab2f12303490b6f Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 19 Mar 2023 23:24:41 +0100 Subject: [PATCH 09/34] feat(youtube): bump compatibility to `18.08.37` --- .../annotation/GeneralAdsCompatibility.kt | 5 +++-- .../annotations/VideoAdsCompatibility.kt | 5 +++-- .../annotation/CopyVideoUrlCompatibility.kt | 5 +++-- .../annotation/DownloadsCompatibility.kt | 5 +++-- .../annotation/SeekbarTappingCompatibility.kt | 5 +++-- .../annotation/SwipeControlsCompatibility.kt | 5 +++-- .../annotations/AutoCaptionsCompatibility.kt | 5 +++-- .../annotations/HideButtonsCompatibility.kt | 5 +++-- .../AutoplayButtonCompatibility.kt | 5 +++-- .../HideCaptionsButtonCompatibility.kt | 5 +++-- .../PlayerButtonBackgroundCompatibility.kt | 5 +++-- .../annotations/AlbumCardsCompatibility.kt | 5 +++-- .../HideArtistCardCompatibility.kt | 5 +++-- .../annotations/BreakingNewsCompatibility.kt | 5 +++-- .../annotations/CommentsCompatibility.kt | 5 +++-- .../CrowdfundingBoxCompatibility.kt | 5 +++-- .../HideEndScreenCardsCompatibility.kt | 5 +++-- ...deFloatingMicrophoneButtonCompatibility.kt | 3 ++- .../annotations/HideInfocardsCompatibility.kt | 5 +++-- .../MixPlaylistsPatchCompatibility.kt | 5 +++-- .../HideEmailAddressCompatibility.kt | 5 +++-- .../annotations/HideSeekbarCompatibility.kt | 3 ++- .../time/annotations/HideTimeCompatibility.kt | 5 +++-- .../annotations/WatchinVRCompatibility.kt | 3 ++- .../annotations/HideWaterwarkCompatibility.kt | 5 +++-- .../HideTimeAndSeekbarCompatibility.kt | 22 ------------------- .../OldQualityLayoutCompatibility.kt | 5 +++-- .../FullscreenPanelsCompatibility.kt | 5 +++-- .../PlayerPopupPanelsCompatibility.kt | 5 +++-- .../annotations/WideSearchbarCompatibility.kt | 3 ++- .../annotations/SponsorBlockCompatibility.kt | 5 +++-- .../SpoofAppVersionCompatibility.kt | 5 +++-- .../StartupShortsResetCompatibility.kt | 5 +++-- .../TabletMiniPlayerCompatibility.kt | 15 +------------ .../annotations/WideSearchbarCompatibility.kt | 22 ------------------- .../annotations/AutoRepeatCompatibility.kt | 5 +++-- .../annotation/ProtobufSpoofCompatibility.kt | 5 +++-- .../annotations/HDRBrightnessCompatibility.kt | 5 +++-- .../OpenLinksExternallyCompatibility.kt | 5 +++-- .../annotation/LithoFilterCompatibility.kt | 5 +++-- .../annotations/MicroGPatchCompatibility.kt | 5 +++-- .../MinimizedPlaybackCompatibility.kt | 5 +++-- .../OpenLinksDirectlyCompatibility.kt | 22 ------------------- .../annotation/PlayerControlsCompatibility.kt | 5 +++-- .../PlayerOverlaysHookCompatibility.kt | 5 +++-- .../annotation/PlayerTypeHookCompatibility.kt | 5 +++-- .../VideoInformationCompatibility.kt | 5 +++-- .../CustomPlaybackSpeedCompatibility.kt | 5 +++-- .../annotation/VideoIdCompatibility.kt | 5 +++-- .../CustomVideoBufferCompatibility.kt | 5 +++-- 50 files changed, 135 insertions(+), 168 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hidetimeandseekbar/annotations/HideTimeAndSeekbarCompatibility.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/annotations/WideSearchbarCompatibility.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/annotations/OpenLinksDirectlyCompatibility.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/GeneralAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/GeneralAdsCompatibility.kt index 876c3ebab..3560b8147 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/GeneralAdsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/general/annotation/GeneralAdsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt index bf9f741de..163353849 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt index 48e04f2d3..313c2f2b8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/annotation/CopyVideoUrlCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/DownloadsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/DownloadsCompatibility.kt index 44dfc0d18..15f5b8419 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/DownloadsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/annotation/DownloadsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt index caa5ea370..b9f287107 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt index 15b2e8d27..b217cbbed 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/annotation/SwipeControlsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) 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 index f4de5e41e..3d2010909 100644 --- 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 @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt index 81c954045..1abfd93ab 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/annotations/HideButtonsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt index 2e5c24c4a..5ec82ebce 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/annotations/AutoplayButtonCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt index 6400c43f3..7bce79a2a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/annotations/HideCaptionsButtonCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/annotations/PlayerButtonBackgroundCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/annotations/PlayerButtonBackgroundCompatibility.kt index 810381462..b3d8a4a5d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/annotations/PlayerButtonBackgroundCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/background/annotations/PlayerButtonBackgroundCompatibility.kt @@ -5,14 +5,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt index 7cc609fe9..d69330041 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/annotations/AlbumCardsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/annotations/HideArtistCardCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/annotations/HideArtistCardCompatibility.kt index 26c4f318e..0d0799a5f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/annotations/HideArtistCardCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/artistcards/annotations/HideArtistCardCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt index 83790642a..4bd60942d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/annotations/BreakingNewsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/CommentsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/CommentsCompatibility.kt index d2dfdcaa2..7fa3e0f76 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/CommentsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/CommentsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt index a44f34ffc..f61f1f2b3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/annotations/CrowdfundingBoxCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndScreenCardsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndScreenCardsCompatibility.kt index 4da83d894..397822fdd 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndScreenCardsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/annotations/HideEndScreenCardsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt index e82d9cf54..2cb65f028 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/annotations/HideFloatingMicrophoneButtonCompatibility.kt @@ -13,7 +13,8 @@ import app.revanced.patcher.annotation.Package "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt index 20e95b8d5..931a8cbe8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/annotations/HideInfocardsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/mixplaylists/annotations/MixPlaylistsPatchCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/mixplaylists/annotations/MixPlaylistsPatchCompatibility.kt index b3262fdb3..08237e9cf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/mixplaylists/annotations/MixPlaylistsPatchCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/mixplaylists/annotations/MixPlaylistsPatchCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt index 0736123e4..a4f0ce845 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/personalinformation/annotations/HideEmailAddressCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt index 7d3f9ef97..1fd33ec99 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/annotations/HideSeekbarCompatibility.kt @@ -13,7 +13,8 @@ import app.revanced.patcher.annotation.Package "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt index 6b14849b1..6646bb1aa 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/annotations/HideTimeCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchinVRCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchinVRCompatibility.kt index e181a7231..57439d1de 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchinVRCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watchinvr/annotations/WatchinVRCompatibility.kt @@ -13,7 +13,8 @@ import app.revanced.patcher.annotation.Package "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWaterwarkCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWaterwarkCompatibility.kt index 0e29cb5a7..1e2cb301e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWaterwarkCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/watermark/annotations/HideWaterwarkCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hidetimeandseekbar/annotations/HideTimeAndSeekbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hidetimeandseekbar/annotations/HideTimeAndSeekbarCompatibility.kt deleted file mode 100644 index 9e9afee29..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hidetimeandseekbar/annotations/HideTimeAndSeekbarCompatibility.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.layout.hidetimeandseekbar.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.RUNTIME) -internal annotation class HideTimeAndSeekbarCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt index 79cb458eb..446c1750e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt index 8d4ada3b0..43472021d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/fullscreen/remove/annotations/FullscreenPanelsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt index 3596c6cf1..b83c3003d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/annotations/PlayerPopupPanelsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt index 9851eb560..91f712441 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/annotations/WideSearchbarCompatibility.kt @@ -13,7 +13,8 @@ import app.revanced.patcher.annotation.Package "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt index 481d696cb..da2bfffb4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt index e6f87b66d..b65016ffb 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/annotations/SpoofAppVersionCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt index c5bdec69d..82c1b333b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/annotations/StartupShortsResetCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt index e4629fb43..61651c1b5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/annotations/TabletMiniPlayerCompatibility.kt @@ -3,19 +3,6 @@ package app.revanced.patches.youtube.layout.tabletminiplayer.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40" - ) - )] -) +@Compatibility([Package("com.google.android.youtube", arrayOf("18.08.37"))]) @Target(AnnotationTarget.CLASS) internal annotation class TabletMiniPlayerCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/annotations/WideSearchbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/annotations/WideSearchbarCompatibility.kt deleted file mode 100644 index 30639b3b5..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/annotations/WideSearchbarCompatibility.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.layout.widesearchbar.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.RUNTIME) -internal annotation class WideSearchbarCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt index b6c421584..001061ae0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/annotations/AutoRepeatCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotation/ProtobufSpoofCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotation/ProtobufSpoofCompatibility.kt index 1f7d7513d..698a4f0bf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotation/ProtobufSpoofCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/annotation/ProtobufSpoofCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/annotations/HDRBrightnessCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/annotations/HDRBrightnessCompatibility.kt index 1ff06a101..9c7bba1e2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/annotations/HDRBrightnessCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/hdrbrightness/annotations/HDRBrightnessCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt index cb79ce80b..169c4dff8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/annotation/LithoFilterCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/annotation/LithoFilterCompatibility.kt index e81e6ffc2..d89900243 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/annotation/LithoFilterCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/annotation/LithoFilterCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt index 67884e5bd..65ffd1898 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/annotations/MicroGPatchCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt index 152e1844a..fe77a8aec 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/annotations/OpenLinksDirectlyCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/annotations/OpenLinksDirectlyCompatibility.kt deleted file mode 100644 index e25ef7823..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/openlinksdirectly/annotations/OpenLinksDirectlyCompatibility.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.patches.youtube.misc.openlinksdirectly.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40" - ) - )] -) -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.RUNTIME) -internal annotation class OpenLinksDirectlyCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt index 0fb69614a..c5114acc6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/annotation/PlayerControlsCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt index 98fb6a84b..c41ad4f16 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/annotation/PlayerOverlaysHookCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt index 99295a865..a54f3aada 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playertype/annotation/PlayerTypeHookCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt index d3e753234..aeaec2de8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/annotations/CustomPlaybackSpeedCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/annotations/CustomPlaybackSpeedCompatibility.kt index 2d57cecc6..1cb9593e0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/annotations/CustomPlaybackSpeedCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/annotations/CustomPlaybackSpeedCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/annotation/VideoIdCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/annotation/VideoIdCompatibility.kt index 777e015c1..35ba3251a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/annotation/VideoIdCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/videoid/annotation/VideoIdCompatibility.kt @@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt index 5139f029f..98e8f802b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/videobuffer/annotations/CustomVideoBufferCompatibility.kt @@ -7,14 +7,15 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( "com.google.android.youtube", arrayOf( - "17.49.37", + "17.49.37", "18.03.36", "18.03.42", "18.04.35", "18.04.41", "18.05.32", "18.05.35", - "18.05.40" + "18.05.40", + "18.08.37" ) )] ) From 7403fc86ae7b7d756a2939fa0a507f237aaf6edf Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 2 Apr 2023 06:13:11 +0200 Subject: [PATCH 10/34] feat(youtube): constrain compatibility to `18.08.37` --- .../RememberVideoQualityCompatibility.kt | 13 +------------ .../RememberPlaybackSpeedCompatibility.kt | 13 +------------ 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/annotations/RememberVideoQualityCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/annotations/RememberVideoQualityCompatibility.kt index d37cab1d3..ffb5921b5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/annotations/RememberVideoQualityCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/annotations/RememberVideoQualityCompatibility.kt @@ -4,18 +4,7 @@ import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package @Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40" - ) - )] + [Package("com.google.android.youtube", arrayOf("18.08.37"))] ) @Target(AnnotationTarget.CLASS) internal annotation class RememberVideoQualityCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/annotation/RememberPlaybackSpeedCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/annotation/RememberPlaybackSpeedCompatibility.kt index ea47d1e68..39a5f7a9b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/annotation/RememberPlaybackSpeedCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/annotation/RememberPlaybackSpeedCompatibility.kt @@ -4,18 +4,7 @@ import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package @Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40" - ) - )] + [Package("com.google.android.youtube", arrayOf("18.08.37"))] ) @Target(AnnotationTarget.CLASS) internal annotation class RememberPlaybackSpeedCompatibility From 33f795350d44de4146fd363c49a801ca16d0e4cf Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Tue, 4 Apr 2023 11:00:13 +0400 Subject: [PATCH 11/34] refactor(youtube/video-information): include video speed (#1843) Co-authored-by: oSumAtrIX --- .../annotations/SponsorBlockCompatibility.kt | 14 +--- .../patch/SponsorBlockBytecodePatch.kt | 33 +++++----- .../VideoInformationCompatibility.kt | 14 +--- .../OnPlaybackSpeedItemClickFingerprint.kt | 2 +- .../patch/VideoInformationPatch.kt | 64 +++++++++++++++++-- ...nitializePlaybackSpeedValuesFingerprint.kt | 2 +- .../patch/RememberPlaybackSpeedPatch.kt | 60 ++++------------- 7 files changed, 93 insertions(+), 96 deletions(-) rename src/main/kotlin/app/revanced/patches/youtube/misc/video/{speed/remember/fingerprint => information/fingerprints}/OnPlaybackSpeedItemClickFingerprint.kt (83%) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt index da2bfffb4..c60f83030 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/annotations/SponsorBlockCompatibility.kt @@ -4,19 +4,7 @@ import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package @Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37" - ) - )] + [Package("com.google.android.youtube", arrayOf("18.08.37"))] ) @Target(AnnotationTarget.CLASS) internal annotation class SponsorBlockCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt index e82d50d5c..a73fc2060 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/bytecode/patch/SponsorBlockBytecodePatch.kt @@ -29,7 +29,6 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.playercontrols.bytecode.patch.PlayerControlsBytecodePatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch -import app.revanced.patches.youtube.misc.video.speed.remember.patch.RememberPlaybackSpeedPatch import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import org.jf.dexlib2.Opcode import org.jf.dexlib2.iface.instruction.* @@ -41,11 +40,13 @@ import org.jf.dexlib2.iface.reference.StringReference @Patch @DependsOn( dependencies = [ - VideoInformationPatch::class, // updates video information and adds method to seek in video - VideoIdPatch::class, - PlayerControlsBytecodePatch::class, - PlayerTypeHookPatch::class, IntegrationsPatch::class, + VideoIdPatch::class, + // Required to skip segments on time. + VideoInformationPatch::class, + // Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts. + PlayerTypeHookPatch::class, + PlayerControlsBytecodePatch::class, SponsorBlockResourcePatch::class, ] ) @@ -75,7 +76,7 @@ class SponsorBlockBytecodePatch : BytecodePatch( override fun execute(context: BytecodeContext): PatchResult { /* - Hook the video time methods + * Hook the video time methods */ with(VideoInformationPatch) { videoTimeHook( @@ -85,12 +86,12 @@ class SponsorBlockBytecodePatch : BytecodePatch( } /* - Set current video id + * Set current video id */ VideoIdPatch.injectCallBackgroundPlay("$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V") /* - Seekbar drawing + * Seekbar drawing */ val seekbarSignatureResult = SeekbarFingerprint.result!!.let { SeekbarOnDrawFingerprint.apply { resolve(context, it.mutableClass) } @@ -99,7 +100,7 @@ class SponsorBlockBytecodePatch : BytecodePatch( val seekbarMethodInstructions = seekbarMethod.implementation!!.instructions /* - Get the instance of the seekbar rectangle + * Get the instance of the seekbar rectangle */ for ((index, instruction) in seekbarMethodInstructions.withIndex()) { if (instruction.opcode != Opcode.MOVE_OBJECT_FROM16) continue @@ -127,8 +128,8 @@ class SponsorBlockBytecodePatch : BytecodePatch( } /* - Set rectangle absolute left and right positions - */ + * Set rectangle absolute left and right positions + */ val drawRectangleInstructions = seekbarMethodInstructions.withIndex().filter { (_, instruction) -> instruction is ReferenceInstruction && (instruction.reference as? MethodReference)?.name == "drawRect" }.map { (index, instruction) -> // TODO: improve code @@ -150,8 +151,8 @@ class SponsorBlockBytecodePatch : BytecodePatch( ) /* - Draw segment - */ + * Draw segment + */ val drawSegmentInstructionInsertIndex = (seekbarMethodInstructions.size - 1 - 2) val (canvasInstance, centerY) = (seekbarMethodInstructions[drawSegmentInstructionInsertIndex] as FiveRegisterInstruction).let { it.registerC to it.registerE @@ -162,7 +163,7 @@ class SponsorBlockBytecodePatch : BytecodePatch( ) /* - Voting & Shield button + * Voting & Shield button */ val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult @@ -268,7 +269,9 @@ class SponsorBlockBytecodePatch : BytecodePatch( } ?: return PatchResultError("Could not find the method which contains the replaceMeWith* strings") - // detect end of the video has been reached + // The vote and create segment buttons automatically change their visibility when appropriate, + // but if buttons are showing when the end of the video is reached then they will not automatically hide. + // Add a hook to forcefully hide when the end of the video is reached. AutoRepeatParentFingerprint.result ?: return AutoRepeatParentFingerprint.toErrorResult() AutoRepeatFingerprint.also { it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt index aeaec2de8..d90f70008 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/annotation/VideoInformationCompatibility.kt @@ -4,19 +4,7 @@ import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package @Compatibility( - [Package( - "com.google.android.youtube", arrayOf( - "17.49.37", - "18.03.36", - "18.03.42", - "18.04.35", - "18.04.41", - "18.05.32", - "18.05.35", - "18.05.40", - "18.08.37" - ) - )] + [Package("com.google.android.youtube", arrayOf("18.08.37"))] ) @Target(AnnotationTarget.CLASS) internal annotation class VideoInformationCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/OnPlaybackSpeedItemClickFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt similarity index 83% rename from src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/OnPlaybackSpeedItemClickFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt index e92afa1c9..648f1a7e3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/OnPlaybackSpeedItemClickFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/fingerprints/OnPlaybackSpeedItemClickFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.video.speed.remember.fingerprint +package app.revanced.patches.youtube.misc.video.information.fingerprints import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import org.jf.dexlib2.Opcode diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt index 7ae872218..77f44a9ed 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/information/patch/VideoInformationPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.misc.video.information.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version @@ -20,10 +21,16 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.video.information.annotation.VideoInformationCompatibility import app.revanced.patches.youtube.misc.video.information.fingerprints.* +import app.revanced.patches.youtube.misc.video.speed.remember.patch.RememberPlaybackSpeedPatch import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.builder.BuilderInstruction import org.jf.dexlib2.builder.MutableMethodImplementation +import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction +import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction +import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.immutable.ImmutableMethod import org.jf.dexlib2.immutable.ImmutableMethodParameter import org.jf.dexlib2.util.MethodUtil @@ -39,6 +46,7 @@ class VideoInformationPatch : BytecodePatch( CreateVideoPlayerSeekbarFingerprint, PlayerControllerSetTimeReferenceFingerprint, VideoTimeFingerprint, + OnPlaybackSpeedItemClickFingerprint, ) ) { override fun execute(context: BytecodeContext): PatchResult { @@ -96,15 +104,15 @@ class VideoInformationPatch : BytecodePatch( } /* - Inject call for video id + * Inject call for video id */ val videoIdMethodDescriptor = "$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V" VideoIdPatch.injectCall(videoIdMethodDescriptor) VideoIdPatch.injectCallBackgroundPlay(videoIdMethodDescriptor) /* - Set the video time method - */ + * Set the video time method + */ with(PlayerControllerSetTimeReferenceFingerprint.result!!) { timeMethod = context.toMethodWalker(method) .nextMethod(scanResult.patternScanResult!!.startIndex, true) @@ -112,7 +120,7 @@ class VideoInformationPatch : BytecodePatch( } /* - Set the high precision video time method + * Set the high precision video time method */ highPrecisionTimeMethod = (object : MethodFingerprint("V", null, listOf("J", "J", "J", "J", "I", "L"), null) {}).also { @@ -120,10 +128,31 @@ class VideoInformationPatch : BytecodePatch( }.result!!.mutableMethod /* - Hook the methods which set the time + * Hook the methods which set the time */ highPrecisionTimeHook(INTEGRATIONS_CLASS_DESCRIPTOR, "setVideoTimeHighPrecision") + + /* + * Hook the user playback speed selection + */ + OnPlaybackSpeedItemClickFingerprint.result?.apply { + speedSelectionInsertMethod = mutableMethod + speedSelectionInsertIndex = scanResult.patternScanResult!!.startIndex - 3 + speedSelectionValueRegister = + (mutableMethod.instruction(speedSelectionInsertIndex) as FiveRegisterInstruction).registerD + + val speedSelectionMethodInstructions = mutableMethod.implementation!!.instructions + setPlaybackSpeedContainerClassFieldReference = + getReference(speedSelectionMethodInstructions, -1, Opcode.IF_EQZ) + setPlaybackSpeedClassFieldReference = + getReference(speedSelectionMethodInstructions, 1, Opcode.IGET) + setPlaybackSpeedMethodReference = + getReference(speedSelectionMethodInstructions, 2, Opcode.IGET) + } ?: return OnPlaybackSpeedItemClickFingerprint.toErrorResult() + + userSelectedPlaybackSpeedHook(INTEGRATIONS_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed") + return PatchResultSuccess() } @@ -185,5 +214,30 @@ class VideoInformationPatch : BytecodePatch( TIME(2), HIGH_PRECISION_TIME(0), } + + private fun getReference(instructions: List, offset: Int, opcode: Opcode) = + instructions[instructions.indexOfFirst { it.opcode == opcode } + offset].reference + + val Instruction.reference get() = (this as ReferenceInstruction).reference.toString() + + private lateinit var speedSelectionInsertMethod: MutableMethod + private var speedSelectionInsertIndex = 0 + private var speedSelectionValueRegister = 0 + + /** + * Hook the video speed selected by the user. + */ + internal fun userSelectedPlaybackSpeedHook(targetMethodClass: String, targetMethodName: String) = + speedSelectionInsertMethod.addInstruction( + speedSelectionInsertIndex++, + "invoke-static {v$speedSelectionValueRegister}, $targetMethodClass->$targetMethodName(F)V" + ) + + /** + * Used by [RememberPlaybackSpeedPatch] + */ + internal lateinit var setPlaybackSpeedContainerClassFieldReference: String + internal lateinit var setPlaybackSpeedClassFieldReference: String + internal lateinit var setPlaybackSpeedMethodReference: String } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt index e244a298e..ead76aa8d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.video.speed.remember.fingerprint +package app.revanced.patches.youtube.misc.video.speed.current.fingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt index ca2260853..2dfd34fa0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt @@ -5,7 +5,6 @@ import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.instruction import app.revanced.patcher.patch.* @@ -16,24 +15,20 @@ import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.SwitchPreference 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.video.information.patch.VideoInformationPatch +import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch.Companion.reference +import app.revanced.patches.youtube.misc.video.speed.current.fingerprint.InitializePlaybackSpeedValuesFingerprint import app.revanced.patches.youtube.misc.video.speed.remember.annotation.RememberPlaybackSpeedCompatibility -import app.revanced.patches.youtube.misc.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint -import app.revanced.patches.youtube.misc.video.speed.remember.fingerprint.OnPlaybackSpeedItemClickFingerprint import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction -import org.jf.dexlib2.iface.instruction.Instruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction @Patch @Name("remember-playback-speed") @Description("Adds the ability to remember the playback speed you chose in the video playback speed flyout.") -@DependsOn([IntegrationsPatch::class, SettingsPatch::class, VideoIdPatch::class]) +@DependsOn([IntegrationsPatch::class, SettingsPatch::class, VideoIdPatch::class, VideoInformationPatch::class]) @RememberPlaybackSpeedCompatibility @Version("0.0.1") class RememberPlaybackSpeedPatch : BytecodePatch( listOf( - OnPlaybackSpeedItemClickFingerprint, InitializePlaybackSpeedValuesFingerprint ) ) { @@ -59,38 +54,21 @@ class RememberPlaybackSpeedPatch : BytecodePatch( VideoIdPatch.injectCall("${INTEGRATIONS_CLASS_DESCRIPTOR}->newVideoLoaded(Ljava/lang/String;)V") + VideoInformationPatch.userSelectedPlaybackSpeedHook( + INTEGRATIONS_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed") + /* - * The following code works by hooking the method which is called when the user selects a playback speed - * to remember the last selected playback speed. - * - * It also hooks the method which is called when the playback speeds are initialized. - * Conveniently, at this point the playback speed is set to the remembered playback speed. + * Hook the code that is called when the playback speeds are initialized, and sets the playback speed */ - - - // Set the remembered playback speed. InitializePlaybackSpeedValuesFingerprint.result?.apply { // Infer everything necessary for calling the method setPlaybackSpeed(). - val instructions = OnPlaybackSpeedItemClickFingerprint.result!!.mutableMethod.implementation!!.instructions - fun getReference(offset: Int = 0, opcode: Opcode) = - instructions[instructions.indexOfFirst { it.opcode == opcode } + offset].reference - - val setPlaybackSpeedContainerClassFieldReference = - getReference(-1, Opcode.IF_EQZ) - - val setPlaybackSpeedClassFieldReference = - getReference(1, Opcode.IGET) - - val setPlaybackSpeedMethodReference = - getReference(2, Opcode.IGET) - val onItemClickListenerClassFieldReference = mutableMethod.instruction(0).reference // Registers are not used at index 0, so they can be freely used. mutableMethod.addInstructions( 0, """ - invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->getCurrentPlaybackSpeed()F + invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->getPlaybackSpeedOverride()F move-result v0 # Check if the playback speed is not 1.0x. @@ -102,30 +80,18 @@ class RememberPlaybackSpeedPatch : BytecodePatch( iget-object v1, p0, $onItemClickListenerClassFieldReference # Get the container class field. - iget-object v1, v1, $setPlaybackSpeedContainerClassFieldReference + iget-object v1, v1, ${VideoInformationPatch.setPlaybackSpeedContainerClassFieldReference} # Get the field from its class. - iget-object v2, v1, $setPlaybackSpeedClassFieldReference + iget-object v2, v1, ${VideoInformationPatch.setPlaybackSpeedClassFieldReference} # Invoke setPlaybackSpeed on that class. - invoke-virtual {v2, v0}, $setPlaybackSpeedMethodReference + invoke-virtual {v2, v0}, ${VideoInformationPatch.setPlaybackSpeedMethodReference} """.trimIndent(), listOf(ExternalLabel("do_not_override", mutableMethod.instruction(0))) ) } ?: return InitializePlaybackSpeedValuesFingerprint.toErrorResult() - // Remember the selected playback speed. - OnPlaybackSpeedItemClickFingerprint.result?.apply { - val setPlaybackSpeedIndex = scanResult.patternScanResult!!.startIndex - 3 - - val selectedPlaybackSpeedRegister = - (mutableMethod.instruction(setPlaybackSpeedIndex) as FiveRegisterInstruction).registerD - - mutableMethod.addInstruction( - setPlaybackSpeedIndex, - "invoke-static { v$selectedPlaybackSpeedRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->setPlaybackSpeed(F)V" - ) - } ?: return OnPlaybackSpeedItemClickFingerprint.toErrorResult() return PatchResultSuccess() } @@ -133,7 +99,5 @@ class RememberPlaybackSpeedPatch : BytecodePatch( private companion object { const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch;" - - val Instruction.reference get() = (this as ReferenceInstruction).reference.toString() } } \ No newline at end of file From 05023bab1d94e04553ac274468bdba7a19ad9180 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Wed, 5 Apr 2023 12:25:12 +0400 Subject: [PATCH 12/34] feat(youtube/settings): disable preferences and add dialog messages to preferences (#1801) Co-authored-by: oSumAtrIX --- .../settings/preference/impl/SwitchPreference.kt | 14 ++++++++------ .../bytecode/patch/SpoofAppVersionPatch.kt | 7 +++++-- .../youtube/misc/debugging/patch/DebuggingPatch.kt | 7 ++++++- .../patch/SpoofSignatureVerificationPatch.kt | 4 +++- .../resource/patch/SettingsResourcePatch.kt | 3 +++ .../resources/settings/host/values/strings.xml | 4 ++++ 6 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 src/main/resources/settings/host/values/strings.xml diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/SwitchPreference.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/SwitchPreference.kt index 78d9f1d38..2845849bc 100644 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/SwitchPreference.kt +++ b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/SwitchPreference.kt @@ -1,10 +1,7 @@ package app.revanced.patches.shared.settings.preference.impl -import app.revanced.patches.shared.settings.preference.BasePreference -import app.revanced.patches.shared.settings.preference.IResource -import app.revanced.patches.shared.settings.preference.addDefault -import app.revanced.patches.shared.settings.preference.addSummary -import app.revanced.patches.shared.settings.preference.SummaryType +import app.revanced.patches.shared.settings.preference.* +import app.revanced.patches.shared.settings.resource.patch.AbstractSettingsResourcePatch.Companion.include import org.w3c.dom.Document import org.w3c.dom.Element @@ -16,16 +13,21 @@ import org.w3c.dom.Element * @param default The default value of the switch. * @param summaryOn The summary to show when the preference is enabled. * @param summaryOff The summary to show when the preference is disabled. + * @param userDialogMessage The message to show in a dialog when the user toggles the preference. */ internal class SwitchPreference( key: String, title: StringResource, val default: Boolean = false, val summaryOn: StringResource? = null, - val summaryOff: StringResource? = null + val summaryOff: StringResource? = null, + val userDialogMessage: StringResource? = null ) : BasePreference(key, title) { override val tag: String = "SwitchPreference" override fun serialize(ownerDocument: Document, resourceCallback: ((IResource) -> Unit)?): Element { + // dialog message is stored as a regular string and later referenced by SettingsEnum + userDialogMessage?.include() + return super.serialize(ownerDocument, resourceCallback).apply { addDefault(default) addSummary(summaryOn?.also { resourceCallback?.invoke(it) }, SummaryType.ON) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt index 8c071d31a..573ed5cb2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/bytecode/patch/SpoofAppVersionPatch.kt @@ -36,8 +36,11 @@ class SpoofAppVersionPatch : BytecodePatch( "revanced_spoof_app_version", StringResource("revanced_spoof_app_version_title", "Spoof app version"), false, - StringResource("revanced_spoof_app_version_summary_on", "Version spoofed to 17.30.34. If switched off, the old UI layout may remain until logging out or clearing app data"), - StringResource("revanced_spoof_app_version_summary_off", "Version not spoofed") + StringResource("revanced_spoof_app_version_summary_on", "Version spoofed to 17.30.34"), + StringResource("revanced_spoof_app_version_summary_off", "Version not spoofed"), + StringResource("revanced_spoof_app_version_user_dialog_message", + "App version will be spoofed to 17.30.34. This will give the old UI layout, but unknown side effects may occur." + + " If later turned off, the old UI layout may remain until you log out or clear the app data.") ) ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt index b3946737b..f25fdd0c4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt @@ -52,7 +52,12 @@ class DebuggingPatch : ResourcePatch { ), true, StringResource("revanced_debug_toast_on_error_summary_on", "Toast shown if error occurs"), - StringResource("revanced_debug_toast_on_error_summary_off", "Toast not shown if error occurs") + StringResource("revanced_debug_toast_on_error_summary_off", "Toast not shown if error occurs"), + StringResource("revanced_debug_toast_on_error_user_dialog_message", + "Turning off error toasts hides all ReVanced error notifications." + + " This includes hiding normal network connection timeouts, " + + "but also hides notification of any unexpected and more serious errors." + ) ), ), StringResource("revanced_debug_summary", "Enable or disable debugging options") diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt index d40cf2281..cc5cbe780 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt @@ -45,7 +45,9 @@ class SpoofSignatureVerificationPatch : BytecodePatch( StringResource("revanced_spoof_signature_verification_title", "Spoof app signature"), true, StringResource("revanced_spoof_signature_verification_summary_on", "App signature spoofed"), - StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed") + StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed"), + StringResource("revanced_spoof_signature_verification_user_dialog_message", + "Signature spoofing can fix playback issues, but may causes side effects.") ) ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/resource/patch/SettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/resource/patch/SettingsResourcePatch.kt index eee608081..4248b6778 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/resource/patch/SettingsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/resource/patch/SettingsResourcePatch.kt @@ -18,6 +18,7 @@ import app.revanced.patches.shared.settings.resource.patch.AbstractSettingsResou import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.util.resources.ResourceUtils import app.revanced.util.resources.ResourceUtils.copyResources +import app.revanced.util.resources.ResourceUtils.mergeStrings import org.w3c.dom.Node @Name("settings-resource-patch") @@ -77,6 +78,8 @@ class SettingsResourcePatch : AbstractSettingsResourcePatch( ) ) + context.mergeStrings("settings/host/values/strings.xml") + return PatchResultSuccess() } diff --git a/src/main/resources/settings/host/values/strings.xml b/src/main/resources/settings/host/values/strings.xml new file mode 100644 index 000000000..c0740672f --- /dev/null +++ b/src/main/resources/settings/host/values/strings.xml @@ -0,0 +1,4 @@ + + + Do you wish to proceed? + From e3666e68ed4816c85fbb110cb098f53fddf135f1 Mon Sep 17 00:00:00 2001 From: EvadeMaster <93124920+EvadeMaster@users.noreply.github.com> Date: Sat, 1 Apr 2023 07:35:13 +0700 Subject: [PATCH 13/34] feat(reddit): bump compatibility to `2023.12.0` (#1825) (cherry picked from commit 02ece35fadd1288c36adea502363a7284552e6f6) --- .../reddit/ad/banner/annotations/HideBannerCompatibility.kt | 4 +++- .../reddit/ad/general/annotations/GeneralAdsCompatibility.kt | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/annotations/HideBannerCompatibility.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/annotations/HideBannerCompatibility.kt index c1043935e..ffac6ed55 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/ad/banner/annotations/HideBannerCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/banner/annotations/HideBannerCompatibility.kt @@ -13,7 +13,9 @@ import app.revanced.patcher.annotation.Package "2023.08.0", "2023.09.0", "2023.09.1", - "2023.10.0" + "2023.10.0", + "2023.11.0", + "2023.12.0" ) )] ) diff --git a/src/main/kotlin/app/revanced/patches/reddit/ad/general/annotations/GeneralAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/reddit/ad/general/annotations/GeneralAdsCompatibility.kt index 7703e68d2..e513e941e 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/ad/general/annotations/GeneralAdsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/ad/general/annotations/GeneralAdsCompatibility.kt @@ -15,7 +15,9 @@ import app.revanced.patcher.annotation.Package "2023.08.0", "2023.09.0", "2023.09.1", - "2023.10.0" + "2023.10.0", + "2023.11.0", + "2023.12.0" ) )] ) From e58038f48069642f32078f94c89da9813f50db01 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 6 Apr 2023 13:44:42 +0200 Subject: [PATCH 14/34] ci: use correct checkmark syntax in PR body --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f36d1d2a1..8b208066e 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -26,5 +26,5 @@ jobs: ## Dependencies before merge - - [] https://github.com/revanced/revanced-integrations + - [ ] https://github.com/revanced/revanced-integrations pr_draft: true From f9a6672122eb28fe06c9f5e137906ad868a491d6 Mon Sep 17 00:00:00 2001 From: Sebok Andras Date: Thu, 6 Apr 2023 14:52:45 +0200 Subject: [PATCH 15/34] feat: `change-package-name` patch (#1864) Co-authored-by: oSumAtrIX --- .../patch/ChangePackageNamePatch.kt | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/all/misc/packagename/patch/ChangePackageNamePatch.kt diff --git a/src/main/kotlin/app/revanced/patches/all/misc/packagename/patch/ChangePackageNamePatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/packagename/patch/ChangePackageNamePatch.kt new file mode 100644 index 000000000..f94fdf331 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/all/misc/packagename/patch/ChangePackageNamePatch.kt @@ -0,0 +1,50 @@ +package app.revanced.patches.all.misc.packagename.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.* +import app.revanced.patcher.patch.annotations.Patch +import org.w3c.dom.Element + +@Patch(false) +@Name("change-package-name") +@Description("Changes the package name.") +@Version("0.0.1") +class ChangePackageNamePatch : ResourcePatch { + override fun execute(context: ResourceContext): PatchResult { + packageName?.let { packageName -> + val packageNameRegex = Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$") + if (!packageName.matches(packageNameRegex)) + return PatchResultError("Invalid package name") + + var originalPackageName = "" + context.xmlEditor["AndroidManifest.xml"].use { editor -> + val manifest = editor.file.getElementsByTagName("manifest").item(0) as Element + originalPackageName = manifest.getAttribute("package") + } + + if (!originalPackageName.matches(packageNameRegex)) + return PatchResultError("Failed to get the original package name") + + context["AndroidManifest.xml"].apply { + readText().replace(originalPackageName, packageName).let(::writeText) + } + + } ?: return PatchResultError("No package name provided") + + return PatchResultSuccess() + } + + companion object : OptionsContainer() { + var packageName: String? by option( + PatchOption.StringOption( + key = "packageName", + default = "", + title = "Package name", + description = "The name of the package to rename of the app.", + ) + ) + } +} \ No newline at end of file From 5e148d9384e8f9f1bc8f5daa7e68a05574810329 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Fri, 7 Apr 2023 11:54:37 +0400 Subject: [PATCH 16/34] fix(youtube/sponsorblock): fix autorepeat button layout (#1868) --- .../sponsorblock/resource/patch/SponsorBlockResourcePatch.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt index fb6f903cd..7c59a9ace 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/resource/patch/SponsorBlockResourcePatch.kt @@ -95,7 +95,7 @@ class SponsorBlockResourcePatch : ResourcePatch { if (!(view.hasAttributes() && view.attributes.getNamedItem("android:id").nodeValue.endsWith("live_chat_overlay_button"))) continue // voting button id from the voting button view from the youtube_controls_layout.xml host file - val votingButtonId = "@+id/voting_button" + val votingButtonId = "@+id/sb_voting_button" view.attributes.getNamedItem("android:layout_toStartOf").nodeValue = votingButtonId From d86b6a4a659172c3f1db8eb883f28dfee4e83e4c Mon Sep 17 00:00:00 2001 From: Linus <23507341+Linus789@users.noreply.github.com> Date: Tue, 11 Apr 2023 19:09:59 +0000 Subject: [PATCH 17/34] fix: add missing annotation to patches (#1882) Co-authored-by: Linus789 --- .../patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt | 2 ++ .../removerestriction/patch/RemoveScreenshotRestrictionPatch.kt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt b/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt index 0c6bdeae8..ecdfc0e37 100644 --- a/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/connectivity/wifi/spoof/patch/SpoofWifiPatch.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.annotations.RequiresIntegrations import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.util.patch.* import org.jf.dexlib2.iface.ClassDef @@ -15,6 +16,7 @@ import java.util.* @Name("spoof-wifi-connection") @Description("Spoofs an existing Wi-Fi connection.") @Version("0.0.1") +@RequiresIntegrations internal class SpoofWifiPatch : AbstractTransformInstructionsPatch() { private companion object { diff --git a/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt b/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt index b9f26c99b..8f4c71a31 100644 --- a/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/all/screenshot/removerestriction/patch/RemoveScreenshotRestrictionPatch.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.annotations.RequiresIntegrations import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.util.patch.* import org.jf.dexlib2.iface.ClassDef @@ -15,6 +16,7 @@ import java.util.* @Name("remove-screenshot-restriction") @Description("Removes the restriction of taking screenshots in apps that normally wouldn't allow it.") @Version("0.0.1") +@RequiresIntegrations internal class RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch() { private companion object { From 43464fd6ffe6f097c574156146aeb23f8f026840 Mon Sep 17 00:00:00 2001 From: badawoll <129878899+badawoll@users.noreply.github.com> Date: Wed, 12 Apr 2023 13:52:14 +0000 Subject: [PATCH 18/34] feat(photomath): bump compatibility up to `8.21.0` (#1886) --- .../DisableSignatureDetectionCompatibility.kt | 26 +++++++++++++++++-- .../fingerprints/CheckSignatureFingerprint.kt | 11 +++++++- .../fingerprints/MainOnCreateFingerprint.kt | 13 ---------- .../patch/SignatureDetectionPatch.kt | 23 ++++++---------- 4 files changed, 42 insertions(+), 31 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/MainOnCreateFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/annotations/DisableSignatureDetectionCompatibility.kt b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/annotations/DisableSignatureDetectionCompatibility.kt index 38ecde594..cd1eb5cce 100644 --- a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/annotations/DisableSignatureDetectionCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/annotations/DisableSignatureDetectionCompatibility.kt @@ -3,6 +3,28 @@ package app.revanced.patches.photomath.detection.signature.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.microblink.photomath")]) +@Compatibility( + [Package( + "com.microblink.photomath", arrayOf( + "8.6.0", + "8.7.0", + "8.8.0", + "8.9.0", + "8.10.0", + "8.11.0", + "8.12.0", + "8.13.0", + "8.14.0", + "8.15.0", + "8.16.0", + "8.17.0", + "8.18.0", + "8.18.1", + "8.19.0", + "8.20.0", + "8.21.0", + ) + )] +) @Target(AnnotationTarget.CLASS) -internal annotation class DisableSignatureDetectionCompatibility \ No newline at end of file +internal annotation class DisableSignatureDetectionCompatibility diff --git a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/CheckSignatureFingerprint.kt b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/CheckSignatureFingerprint.kt index 26fb72655..2f460c694 100644 --- a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/CheckSignatureFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/CheckSignatureFingerprint.kt @@ -1,9 +1,18 @@ package app.revanced.patches.photomath.detection.signature.fingerprints +import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode object CheckSignatureFingerprint : MethodFingerprint( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + customFingerprint = { + (it.definingClass == "Lcom/microblink/photomath/main/activity/LauncherActivity;" || + it.definingClass == "Lcom/microblink/photomath/PhotoMath;") && + it.name == "onCreate" + }, strings = listOf( "currentSignature" ), @@ -18,4 +27,4 @@ object CheckSignatureFingerprint : MethodFingerprint( Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, ) -) \ No newline at end of file +) diff --git a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/MainOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/MainOnCreateFingerprint.kt deleted file mode 100644 index f263f0b73..000000000 --- a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/fingerprints/MainOnCreateFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.photomath.detection.signature.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object MainOnCreateFingerprint : MethodFingerprint( - returnType = "V", - access = AccessFlags.PUBLIC or AccessFlags.FINAL, - customFingerprint = { methodDef -> - methodDef.definingClass == "Lcom/microblink/photomath/PhotoMath;" && methodDef.name == "onCreate" - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt index f8a07bd9e..25d77a391 100644 --- a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt @@ -1,42 +1,35 @@ package app.revanced.patches.photomath.detection.signature.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.instruction import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patches.photomath.detection.signature.annotations.DisableSignatureDetectionCompatibility import app.revanced.patches.photomath.detection.signature.fingerprints.CheckSignatureFingerprint -import app.revanced.patches.photomath.detection.signature.fingerprints.MainOnCreateFingerprint import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Description("Disables detection of incorrect signature.") @DisableSignatureDetectionCompatibility -@Version("0.0.1") +@Version("0.0.2") class SignatureDetectionPatch : BytecodePatch( listOf( - MainOnCreateFingerprint + CheckSignatureFingerprint ) ) { override fun execute(context: BytecodeContext): PatchResult { - val mainOnCreate = MainOnCreateFingerprint.result!! - - val patternResult = CheckSignatureFingerprint.also { - it.resolve(context, mainOnCreate.method, mainOnCreate.classDef) - }.result!!.scanResult.patternScanResult!! - - mainOnCreate.mutableMethod.apply { - val signatureCheckInstruction = instruction(patternResult.endIndex) + CheckSignatureFingerprint.result?.apply { + val signatureCheckInstruction = mutableMethod.instruction(scanResult.patternScanResult!!.endIndex) val checkRegister = (signatureCheckInstruction as OneRegisterInstruction).registerA - replaceInstruction(signatureCheckInstruction.location.index, "const/4 v$checkRegister, 0x1") - } + mutableMethod.replaceInstruction(signatureCheckInstruction.location.index, "const/4 v$checkRegister, 0x1") + } ?: throw CheckSignatureFingerprint.toErrorResult() return PatchResultSuccess() } -} \ No newline at end of file +} From 2cfc9829e119884ca566d6ad90fd0542317891d7 Mon Sep 17 00:00:00 2001 From: badawoll <129878899+badawoll@users.noreply.github.com> Date: Thu, 13 Apr 2023 15:24:44 +0000 Subject: [PATCH 19/34] feat(facebook): `hide-inbox-ads` patch (#1893) Signed-off-by: badawoll <129878899+badawoll@users.noreply.github.com> --- .../fingerprints/LoadInboxAdsFingerprint.kt | 18 ++++++++++++ .../ads/inbox/patch/HideInboxAdsPatch.kt | 29 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/messenger/ads/inbox/fingerprints/LoadInboxAdsFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/messenger/ads/inbox/patch/HideInboxAdsPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/fingerprints/LoadInboxAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/fingerprints/LoadInboxAdsFingerprint.kt new file mode 100644 index 000000000..c29b94448 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/fingerprints/LoadInboxAdsFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.messenger.ads.inbox.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags + +object LoadInboxAdsFingerprint : MethodFingerprint( + returnType = "V", + strings = listOf( + "ads_load_begin", + "inbox_ads_fetch_start" + ), + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + customFingerprint = { + it.definingClass == "Lcom/facebook/messaging/business/inboxads/plugins/inboxads/itemsupplier/InboxAdsItemSupplierImplementation;" + } +) + diff --git a/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/patch/HideInboxAdsPatch.kt b/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/patch/HideInboxAdsPatch.kt new file mode 100644 index 000000000..f18a78d5f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/messenger/ads/inbox/patch/HideInboxAdsPatch.kt @@ -0,0 +1,29 @@ +package app.revanced.patches.messenger.ads.inbox.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.* +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.messenger.ads.inbox.fingerprints.LoadInboxAdsFingerprint + +@Patch +@Name("hide-inbox-ads") +@Description("Hides ads in inbox.") +@Compatibility([Package("com.facebook.orca")]) +@Version("0.0.1") +class HideInboxAdsPatch : BytecodePatch( + listOf(LoadInboxAdsFingerprint) +) { + override fun execute(context: BytecodeContext): PatchResult { + LoadInboxAdsFingerprint.result?.mutableMethod?.apply { + this.replaceInstruction(0, "return-void") + } ?: return LoadInboxAdsFingerprint.toErrorResult() + + return PatchResultSuccess() + } +} + From bd224d90deb838ee3e7bd0c16860023ebf113e96 Mon Sep 17 00:00:00 2001 From: Sebok Andras Date: Thu, 13 Apr 2023 19:36:42 +0200 Subject: [PATCH 20/34] feat: `enable-android-debugging` patch (#1876) --- .../all/misc/debugging/patch/DebuggingPatc.kt | 43 +++++++++++++++++++ .../misc/debugging/patch/DebuggingPatch.kt | 30 ++----------- 2 files changed, 47 insertions(+), 26 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/DebuggingPatc.kt diff --git a/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/DebuggingPatc.kt b/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/DebuggingPatc.kt new file mode 100644 index 000000000..a5b9942a2 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/all/misc/debugging/patch/DebuggingPatc.kt @@ -0,0 +1,43 @@ +package app.revanced.patches.all.misc.debugging.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.* +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import org.w3c.dom.Element + +@Patch +@Name("enable-android-debugging") +@Description("Enables Android debugging capabilities.") +@Version("0.0.1") +class EnableAndroidDebuggingPatch : ResourcePatch { + override fun execute(context: ResourceContext): PatchResult { + if (debuggable == true) { + context.xmlEditor["AndroidManifest.xml"].use { dom -> + val applicationNode = dom + .file + .getElementsByTagName("application") + .item(0) as Element + + // set application as debuggable + applicationNode.setAttribute("android:debuggable", "true") + } + } + + return PatchResultSuccess() + } + + companion object : OptionsContainer() { + var debuggable: Boolean? by option( + PatchOption.BooleanOption( + key = "debuggable", + default = true, + title = "App debugging", + description = "Whether to make the app debuggable on Android.", + ) + ) + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt index f25fdd0c4..8a2a8c88e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/patch/DebuggingPatch.kt @@ -11,15 +11,16 @@ import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.youtube.misc.debugging.annotations.DebuggingCompatibility import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch +import app.revanced.patches.all.misc.debugging.patch.EnableAndroidDebuggingPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import org.w3c.dom.Element @Patch -@Name("debugging") -@DependsOn([IntegrationsPatch::class, SettingsPatch::class]) +@Name("enable-debugging") +@DependsOn([IntegrationsPatch::class, SettingsPatch::class, EnableAndroidDebuggingPatch::class]) @Description("Adds debugging options.") @DebuggingCompatibility -@Version("0.0.1") +@Version("0.0.2") class DebuggingPatch : ResourcePatch { override fun execute(context: ResourceContext): PatchResult { SettingsPatch.PreferenceScreen.MISC.addPreferences( @@ -64,29 +65,6 @@ class DebuggingPatch : ResourcePatch { ) ) - if (debuggable == true) { - context.xmlEditor["AndroidManifest.xml"].use { dom -> - val applicationNode = dom - .file - .getElementsByTagName("application") - .item(0) as Element - - // set application as debuggable - applicationNode.setAttribute("android:debuggable", "true") - } - } - return PatchResultSuccess() } - - companion object : OptionsContainer() { - var debuggable: Boolean? by option( - PatchOption.BooleanOption( - key = "debuggable", - default = false, - title = "App debugging", - description = "Whether to make the app debuggable on Android.", - ) - ) - } } From fbb17636d8ab9f2a43ead896451804b04464527c Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Fri, 14 Apr 2023 05:50:41 +0400 Subject: [PATCH 21/34] feat(youtube): change default video speed and quality inside the settings menu (#1880) Co-authored-by: johnconner122 <107796137+johnconner122@users.noreply.github.com> Co-authored-by: oSumAtrIX --- .../settings/preference/impl/ArrayResource.kt | 1 + .../patch/RememberVideoQualityPatch.kt | 48 +++++++++++++++++++ .../custom/patch/CustomVideoSpeedPatch.kt | 2 +- ...nitializePlaybackSpeedValuesFingerprint.kt | 2 +- .../patch/RememberPlaybackSpeedPatch.kt | 26 +++++++++- 5 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ArrayResource.kt b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ArrayResource.kt index 608dccca4..90795e1f7 100644 --- a/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ArrayResource.kt +++ b/src/main/kotlin/app/revanced/patches/shared/settings/preference/impl/ArrayResource.kt @@ -11,6 +11,7 @@ import org.w3c.dom.Element * @param name The name of the array resource. * @param items The items of the array resource. */ +// TODO: allow specifying an array resource file instead of using a list of StringResources internal data class ArrayResource( override val name: String, val items: List diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt index 28b382d76..d5a03e33b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/quality/patch/RememberVideoQualityPatch.kt @@ -14,6 +14,8 @@ import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.shared.settings.preference.impl.ArrayResource +import app.revanced.patches.shared.settings.preference.impl.ListPreference import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch @@ -58,6 +60,52 @@ class RememberVideoQualityPatch : BytecodePatch( ) ) + // This is bloated as each value has it's own String key/value + // ideally the entries would be raw values (and not a key to a String resource) + val entries = listOf( + StringResource("revanced_default_quality_entry_1", "Automatic quality"), + StringResource("revanced_default_quality_entry_2", "2160p"), + StringResource("revanced_default_quality_entry_3", "1440p"), + StringResource("revanced_default_quality_entry_4", "1080p"), + StringResource("revanced_default_quality_entry_5", "720p"), + StringResource("revanced_default_quality_entry_6", "480p"), + StringResource("revanced_default_quality_entry_7", "360p"), + StringResource("revanced_default_quality_entry_8", "280p"), + StringResource("revanced_default_quality_entry_9", "144p"), + ) + val entryValues = listOf( + StringResource("revanced_default_quality_entry_value_1", "-2"), + StringResource("revanced_default_quality_entry_value_2", "2160"), + StringResource("revanced_default_quality_entry_value_3", "1440"), + StringResource("revanced_default_quality_entry_value_4", "1080"), + StringResource("revanced_default_quality_entry_value_5", "720"), + StringResource("revanced_default_quality_entry_value_6", "480"), + StringResource("revanced_default_quality_entry_value_7", "360"), + StringResource("revanced_default_quality_entry_value_8", "280"), + StringResource("revanced_default_quality_entry_value_9", "144"), + ) + SettingsPatch.PreferenceScreen.MISC.addPreferences( + ListPreference( + "revanced_default_video_quality_wifi", + StringResource( + "revanced_default_video_quality_wifi_title", + "Default video quality on Wi-Fi network" + ), + ArrayResource("revanced_video_quality_wifi_entry", entries), + ArrayResource("revanced_video_quality_wifi_entry_values", entryValues) + // default value and summary are set by integrations after loading + ), + ListPreference( + "revanced_default_video_quality_mobile", + StringResource( + "revanced_default_video_quality_mobile_title", + "Default video quality on mobile network" + ), + ArrayResource("revanced_video_quality_mobile_entries", entries), + ArrayResource("revanced_video_quality_mobile_entry_values", entryValues) + ) + ) + /* * The following code works by hooking the method which is called when the user selects a video quality * to remember the last selected video quality. diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/patch/CustomVideoSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/patch/CustomVideoSpeedPatch.kt index 1b76883b7..c038ba497 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/patch/CustomVideoSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/custom/patch/CustomVideoSpeedPatch.kt @@ -9,11 +9,11 @@ import app.revanced.patcher.extensions.replaceInstruction import app.revanced.patcher.patch.* import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.video.speed.custom.annotations.CustomPlaybackSpeedCompatibility import app.revanced.patches.youtube.misc.video.speed.custom.fingerprints.SpeedArrayGeneratorFingerprint import app.revanced.patches.youtube.misc.video.speed.custom.fingerprints.SpeedLimiterFingerprint import app.revanced.patches.youtube.misc.video.speed.custom.fingerprints.VideoSpeedPatchFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import org.jf.dexlib2.builder.instruction.BuilderArrayPayload import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt index ead76aa8d..e244a298e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/fingerprint/InitializePlaybackSpeedValuesFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.misc.video.speed.current.fingerprint +package app.revanced.patches.youtube.misc.video.speed.remember.fingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt index 2dfd34fa0..4895e665a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/video/speed/remember/patch/RememberPlaybackSpeedPatch.kt @@ -11,14 +11,16 @@ import app.revanced.patcher.patch.* import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.shared.settings.preference.impl.ArrayResource +import app.revanced.patches.shared.settings.preference.impl.ListPreference import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.SwitchPreference 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.video.information.patch.VideoInformationPatch import app.revanced.patches.youtube.misc.video.information.patch.VideoInformationPatch.Companion.reference -import app.revanced.patches.youtube.misc.video.speed.current.fingerprint.InitializePlaybackSpeedValuesFingerprint import app.revanced.patches.youtube.misc.video.speed.remember.annotation.RememberPlaybackSpeedCompatibility +import app.revanced.patches.youtube.misc.video.speed.remember.fingerprint.InitializePlaybackSpeedValuesFingerprint import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch @Patch @@ -52,6 +54,27 @@ class RememberPlaybackSpeedPatch : BytecodePatch( ) ) + SettingsPatch.PreferenceScreen.MISC.addPreferences( + ListPreference( + "revanced_default_playback_speed", + StringResource( + "revanced_default_playback_speed_title", + "Default playback speed" + ), + // Dummy data: + // Entries and values are set by Integrations code based on the actual speeds available, + // and the values set here are ignored and do nothing. + ArrayResource( + "revanced_default_playback_speed_entries", + listOf(StringResource("revanced_default_playback_speed_entry", "1.0x")) + ), + ArrayResource( + "revanced_default_playback_speed_entry_values", + listOf(StringResource("revanced_default_playback_speed_entry_value", "1.0")) + ) + ) + ) + VideoIdPatch.injectCall("${INTEGRATIONS_CLASS_DESCRIPTOR}->newVideoLoaded(Ljava/lang/String;)V") VideoInformationPatch.userSelectedPlaybackSpeedHook( @@ -92,7 +115,6 @@ class RememberPlaybackSpeedPatch : BytecodePatch( ) } ?: return InitializePlaybackSpeedValuesFingerprint.toErrorResult() - return PatchResultSuccess() } From 83747b7aea33d8fe4b4b9514fdf7c9081c357410 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 16 Apr 2023 22:18:16 +0400 Subject: [PATCH 22/34] feat(youtube/sponsorblock): skip to video highlight (#1874) --- .../sponsorblock/host/values/strings.xml | 8 ++++- .../layout/inline_sponsor_overlay.xml | 32 +++++++++++++------ .../layout/skip_sponsor_button.xml | 1 - 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/main/resources/sponsorblock/host/values/strings.xml b/src/main/resources/sponsorblock/host/values/strings.xml index 3d6ef38c7..6ea734421 100644 --- a/src/main/resources/sponsorblock/host/values/strings.xml +++ b/src/main/resources/sponsorblock/host/values/strings.xml @@ -44,6 +44,8 @@ Similar to \'Sponsor\' except for unpaid or self promotion. Includes sections about merchandise, donations, or information about who they collaborated with Interaction Reminder (Subscribe) A short reminder to like, subscribe or follow them in the middle of content. If it is long or about something specific, it should instead be under self promotion + Highlight + The part of the video that most people are looking for Intermission/Intro Animation An interval without actual content. Could be a pause, static frame, or repeating animation. Does not include transitions containing information Endcards/Credits @@ -56,9 +58,11 @@ Only for use in music videos. Sections of music videos without music, that aren\'t already covered by another category Skip + Highlight Skip sponsor Skip promo Skip interact + Skip to highlight Skip intro Skip intermission Skip intermission @@ -73,6 +77,7 @@ Skipped sponsor Skipped self promotion Skipped annoying reminder + Skipped to highlight Skipped intro Skipped intermission Skipped intermission @@ -119,7 +124,7 @@ Choose the segment category Category is disabled in settings. Enable category to submit. New SponsorBlock segment - Set %02d:%02d:%04d as the start or end of a new segment? + Set %02d:%02d:%03d as the start or end of a new segment? start end now @@ -127,6 +132,7 @@ Time the segment ends at Are the times correct? The segment lasts from %02d:%02d to %02d:%02d (%d minutes %02d seconds)\nIs it ready to submit? + Start must be before the end Mark two locations on the time bar first Preview the segment, and ensure it skips smoothly Edit timing of segment manually diff --git a/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml b/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml index 9f4221735..2c0385549 100644 --- a/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml +++ b/src/main/resources/sponsorblock/layout/inline_sponsor_overlay.xml @@ -1,6 +1,28 @@ + + + + - - \ No newline at end of file diff --git a/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml b/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml index 3a3167bb8..185960ec9 100644 --- a/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml +++ b/src/main/resources/sponsorblock/layout/skip_sponsor_button.xml @@ -7,7 +7,6 @@ android:layout_width="wrap_content" android:layout_height="32dp" android:layout_gravity="center_vertical" - android:contentDescription="@string/sb_skip_button_compact" android:orientation="horizontal" android:padding="8dp"> From 5b987e14e81a47691883a5b5196c7ffee03941d0 Mon Sep 17 00:00:00 2001 From: johnconner122 <107796137+johnconner122@users.noreply.github.com> Date: Wed, 19 Apr 2023 04:45:47 +0500 Subject: [PATCH 23/34] fix(youtubevanced/hide-ads): remove broken ad filter (#1881) --- .../patches/youtubevanced/ad/general/patch/HideAdsPatch.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt index 105b9289e..09fd98117 100644 --- a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/patch/HideAdsPatch.kt @@ -47,8 +47,7 @@ class HideAdsPatch : BytecodePatch( "hero_promo_image", "statement_banner", "primetime_promo", - "carousel_footered_layout", - "feature_grid_interstitial" + "carousel_footered_layout" ).forEach { component -> addInstructions( insertIndex, """ From 7d3054178187bed294d156d3858613fa63a626ef Mon Sep 17 00:00:00 2001 From: badawoll <129878899+badawoll@users.noreply.github.com> Date: Tue, 18 Apr 2023 23:47:17 +0000 Subject: [PATCH 24/34] feat(memegenerator): `unlock-pro` patch (#1902) Co-authored-by: oSumAtrIX --- .../LicenseValidationFingerprint.kt | 24 ++++++++++ .../license/patch/LicenseValidationPatch.kt | 31 +++++++++++++ .../fingerprint/VerifySignatureFingerprint.kt | 35 +++++++++++++++ .../patch/SignatureVerificationPatch.kt | 31 +++++++++++++ .../pro/annotations/UnlockProCompatibility.kt | 8 ++++ .../fingerprint/IsFreeVersionFingerprint.kt | 22 +++++++++ .../misc/pro/patch/UnlockProVersionPatch.kt | 45 +++++++++++++++++++ 7 files changed, 196 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/memegenerator/detection/license/fingerprint/LicenseValidationFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/memegenerator/detection/license/patch/LicenseValidationPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/fingerprint/VerifySignatureFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/patch/SignatureVerificationPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/annotations/UnlockProCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/fingerprint/IsFreeVersionFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/patch/UnlockProVersionPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/fingerprint/LicenseValidationFingerprint.kt b/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/fingerprint/LicenseValidationFingerprint.kt new file mode 100644 index 000000000..205bca30a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/fingerprint/LicenseValidationFingerprint.kt @@ -0,0 +1,24 @@ +package app.revanced.patches.memegenerator.detection.license.fingerprint + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +object LicenseValidationFingerprint : MethodFingerprint( + returnType = "Z", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("Landroid/content/Context;"), + opcodes = listOf( + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_WIDE, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_WIDE, + Opcode.CMP_LONG, + Opcode.IF_GEZ, + Opcode.CONST_4, + Opcode.RETURN, + Opcode.CONST_4, + Opcode.RETURN + ) +) diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/patch/LicenseValidationPatch.kt b/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/patch/LicenseValidationPatch.kt new file mode 100644 index 000000000..6e514ff70 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/memegenerator/detection/license/patch/LicenseValidationPatch.kt @@ -0,0 +1,31 @@ +package app.revanced.patches.memegenerator.detection.license.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.replaceInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patches.memegenerator.detection.license.fingerprint.LicenseValidationFingerprint + +@Description("Disables Firebase license validation.") +@Version("0.0.1") +class LicenseValidationPatch : BytecodePatch( + listOf(LicenseValidationFingerprint) +) { + override fun execute(context: BytecodeContext): PatchResult { + LicenseValidationFingerprint.result?.apply { + mutableMethod.replaceInstructions( + 0, + """ + const/4 p0, 0x1 + return p0 + """ + ) + } ?: throw LicenseValidationFingerprint.toErrorResult() + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/fingerprint/VerifySignatureFingerprint.kt b/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/fingerprint/VerifySignatureFingerprint.kt new file mode 100644 index 000000000..7c0304ebb --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/fingerprint/VerifySignatureFingerprint.kt @@ -0,0 +1,35 @@ +package app.revanced.patches.memegenerator.detection.signature.fingerprint + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@FuzzyPatternScanMethod(2) +object VerifySignatureFingerprint : MethodFingerprint( + returnType = "Z", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("Landroid/app/Activity;"), + opcodes = listOf( + Opcode.SGET_OBJECT, + Opcode.IF_NEZ, + Opcode.INVOKE_STATIC, + Opcode.CONST_4, + Opcode.CONST_4, + Opcode.SGET_OBJECT, + Opcode.ARRAY_LENGTH, + Opcode.IF_GE, + Opcode.AGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.SGET_OBJECT, + Opcode.IF_EQZ, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.CONST_4, + Opcode.RETURN, + Opcode.ADD_INT_LIT8 + ), +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/patch/SignatureVerificationPatch.kt b/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/patch/SignatureVerificationPatch.kt new file mode 100644 index 000000000..1b9ca3064 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/memegenerator/detection/signature/patch/SignatureVerificationPatch.kt @@ -0,0 +1,31 @@ +package app.revanced.patches.memegenerator.detection.signature.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.replaceInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patches.memegenerator.detection.signature.fingerprint.VerifySignatureFingerprint + +@Description("Disables detection of incorrect signature.") +@Version("0.0.1") +class SignatureVerificationPatch : BytecodePatch( + listOf(VerifySignatureFingerprint) +) { + override fun execute(context: BytecodeContext): PatchResult { + VerifySignatureFingerprint.result?.apply { + mutableMethod.replaceInstructions( + 0, + """ + const/4 p0, 0x1 + return p0 + """ + ) + } ?: throw VerifySignatureFingerprint.toErrorResult() + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/annotations/UnlockProCompatibility.kt b/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/annotations/UnlockProCompatibility.kt new file mode 100644 index 000000000..bf92bccaa --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/annotations/UnlockProCompatibility.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.memegenerator.misc.pro.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility([Package("com.zombodroid.MemeGenerator", arrayOf("4.6364"))]) +@Target(AnnotationTarget.CLASS) +internal annotation class UnlockProCompatibility diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/fingerprint/IsFreeVersionFingerprint.kt b/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/fingerprint/IsFreeVersionFingerprint.kt new file mode 100644 index 000000000..be9b266ba --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/fingerprint/IsFreeVersionFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.memegenerator.misc.pro.fingerprint + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +object IsFreeVersionFingerprint : MethodFingerprint( + returnType = "Ljava/lang/Boolean;", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + strings = listOf("free"), + parameters = listOf("Landroid/content/Context;"), + opcodes = listOf( + Opcode.SGET, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CONST_STRING, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ + ) +) diff --git a/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/patch/UnlockProVersionPatch.kt b/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/patch/UnlockProVersionPatch.kt new file mode 100644 index 000000000..c0c928e24 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/memegenerator/misc/pro/patch/UnlockProVersionPatch.kt @@ -0,0 +1,45 @@ +package app.revanced.patches.memegenerator.misc.pro.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.replaceInstructions +import app.revanced.patcher.patch.BytecodePatch +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.patches.memegenerator.detection.license.patch.LicenseValidationPatch +import app.revanced.patches.memegenerator.detection.signature.patch.SignatureVerificationPatch +import app.revanced.patches.memegenerator.misc.pro.annotations.UnlockProCompatibility +import app.revanced.patches.memegenerator.misc.pro.fingerprint.IsFreeVersionFingerprint + +@Patch +@Name("unlock-pro") +@Description("Unlocks pro features.") +@DependsOn([ + SignatureVerificationPatch::class, + LicenseValidationPatch::class +]) +@UnlockProCompatibility +@Version("0.0.1") +class UnlockProVersionPatch : BytecodePatch( + listOf( + IsFreeVersionFingerprint + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + IsFreeVersionFingerprint.result?.apply { + mutableMethod.replaceInstructions(0, + """ + sget-object p0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean; + return-object p0 + """ + ) + } ?: throw IsFreeVersionFingerprint.toErrorResult() + + return PatchResultSuccess() + } +} \ No newline at end of file From 85675b800070de9752b2a4bfea3182381d4cfba4 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Wed, 19 Apr 2023 10:35:44 +0400 Subject: [PATCH 25/34] fix(youtube/return-youtube-dislike): render dislikes when scrolling into the screen (#1873) Co-authored-by: oSumAtrIX --- .../ShortsTextComponentParentFingerprint.kt | 11 +- ...TextComponentAtomicReferenceFingerprint.kt | 34 ++++++ .../TextComponentContextFingerprint.kt | 24 ++++ .../fingerprints/TextReferenceFingerprint.kt | 14 --- .../TextReferenceParamFingerprint.kt | 11 -- .../patch/ReturnYouTubeDislikePatch.kt | 107 +++++++++++------- 6 files changed, 129 insertions(+), 72 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceParamFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextComponentParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextComponentParentFingerprint.kt index 7179eb3ac..27e529824 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextComponentParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/ShortsTextComponentParentFingerprint.kt @@ -10,11 +10,12 @@ object ShortsTextComponentParentFingerprint : MethodFingerprint( access = AccessFlags.PROTECTED or AccessFlags.FINAL, parameters = listOf("L", "L"), opcodes = listOf( - Opcode.IF_EQZ, - Opcode.CONST_4, - Opcode.IF_EQ, - Opcode.CONST_4, - Opcode.IF_EQ, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.GOTO, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, Opcode.RETURN_VOID, Opcode.IGET_OBJECT, Opcode.CHECK_CAST, diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt new file mode 100644 index 000000000..c555cb827 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentAtomicReferenceFingerprint.kt @@ -0,0 +1,34 @@ +package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +/** + * Resolves against the same method that [TextComponentContextFingerprint] resolves to. + */ +object TextComponentAtomicReferenceFingerprint : MethodFingerprint( + returnType = "L", + access = AccessFlags.PROTECTED or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( + Opcode.MOVE_OBJECT, // available unused register + Opcode.MOVE_OBJECT_FROM16, + Opcode.MOVE_OBJECT_FROM16, + Opcode.MOVE_FROM16, + Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.MOVE_OBJECT, // CharSequence reference, and control flow label. Insert code here. + Opcode.INVOKE_VIRTUAL_RANGE, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.INVOKE_VIRTUAL_RANGE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.GOTO, + Opcode.CONST_4, + Opcode.INVOKE_VIRTUAL_RANGE, + Opcode.MOVE_RESULT_OBJECT, + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt new file mode 100644 index 000000000..1a23e7046 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextComponentContextFingerprint.kt @@ -0,0 +1,24 @@ +package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +/** + * Resolves against the same method that [TextComponentContextFingerprint] resolves to. + */ +object TextComponentContextFingerprint : MethodFingerprint( + returnType = "L", + access = AccessFlags.PROTECTED or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( + Opcode.IGET_OBJECT, // conversion context field name + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IGET_BOOLEAN, + Opcode.IGET, + Opcode.IGET, + Opcode.IGET, + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceFingerprint.kt deleted file mode 100644 index 763aef752..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object TextReferenceFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_STATIC_RANGE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_VIRTUAL - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceParamFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceParamFingerprint.kt deleted file mode 100644 index f81420fcb..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/TextReferenceParamFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.Opcode - -object TextReferenceParamFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16 // the first occurrence of this instruction uses the register for the text object - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt index b483afa1d..3796ee62b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt @@ -9,6 +9,7 @@ import app.revanced.patcher.data.toMethodWalker import app.revanced.patcher.extensions.MethodFingerprintExtensions.name import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.instruction +import app.revanced.patcher.extensions.replaceInstruction import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.BytecodePatch @@ -25,8 +26,8 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import org.jf.dexlib2.builder.instruction.BuilderInstruction35c -import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction +import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction @Patch @@ -52,13 +53,13 @@ class ReturnYouTubeDislikePatch : BytecodePatch( ) ) { override fun execute(context: BytecodeContext): PatchResult { - // region Inject newVideoLoaded event handler + // region Inject newVideoLoaded event handler to update dislikes when a new video is loaded. VideoIdPatch.injectCall("$INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V") // endregion - // region Hook interaction + // region Hook like/dislike/remove like button clicks to send votes to the API. listOf( LikeFingerprint.toPatch(Vote.LIKE), @@ -78,39 +79,56 @@ class ReturnYouTubeDislikePatch : BytecodePatch( // endregion - // region Hook components + // region Hook creation of Spans and the cached lookup of them. - TextReferenceFingerprint.also { + // Alternatively the hook can be made at the creation of Spans in TextComponentSpec, + // And it works in all situations except it fails to update the Span when the user dislikes, + // since the underlying (likes only) text did not change. + // This hook handles all situations, as it's where the created Spans are stored and later reused. + TextComponentContextFingerprint.also { it.resolve( context, TextComponentConstructorFingerprint.result!!.classDef ) - }.result?.let { result -> - val moveTextRefParamInstructionIndex = TextReferenceParamFingerprint.also { - if (!TextReferenceParamFingerprint.resolve(context, result.method, result.classDef)) - return TextReferenceParamFingerprint.toErrorResult() - }.result!!.scanResult.patternScanResult!!.endIndex + }.result?.also { result -> + if (!TextComponentAtomicReferenceFingerprint.resolve(context, result.method, result.classDef)) + throw TextComponentAtomicReferenceFingerprint.toErrorResult() + }?.let { textComponentContextFingerprintResult -> + val conversionContextIndex = textComponentContextFingerprintResult + .scanResult.patternScanResult!!.startIndex + val atomicReferenceStartIndex = TextComponentAtomicReferenceFingerprint.result!! + .scanResult.patternScanResult!!.startIndex - result.mutableMethod.apply { - val insertIndex = result.scanResult.patternScanResult!!.endIndex + textComponentContextFingerprintResult.mutableMethod.apply { + // Get the conversion context obfuscated field name, and the registers for the AtomicReference and CharSequence + val conversionContextFieldName = + (instruction(conversionContextIndex) as ReferenceInstruction).reference.toString() + val contextRegister = // any free register + (instruction(atomicReferenceStartIndex) as TwoRegisterInstruction).registerB + val atomicReferenceRegister = + (instruction(atomicReferenceStartIndex + 4) as BuilderInstruction35c).registerC - val atomicReferenceInstruction = (instruction(insertIndex - 1) as FiveRegisterInstruction) - val conversionContextParam = atomicReferenceInstruction.registerC - val textRefParam = (instruction(moveTextRefParamInstructionIndex) as TwoRegisterInstruction).registerA - - // Overwritten after injected code, which is why it can be used. - val clobberRegister = atomicReferenceInstruction.registerD + val insertIndex = atomicReferenceStartIndex + 7 + val moveCharSequenceInstruction = instruction(insertIndex) as TwoRegisterInstruction + val charSequenceRegister = moveCharSequenceInstruction.registerB + // Insert as first instructions at the control flow label. + // Must replace the existing instruction to preserve the label, and then insert the remaining instructions. + replaceInstruction(insertIndex, "move-object/from16 v$contextRegister, p0") addInstructions( - insertIndex, - """ - # required instruction, otherwise register might be out of range - move-object/from16 v$clobberRegister, v$textRefParam - invoke-static {v$clobberRegister, v$conversionContextParam}, $ON_COMPONENT_CREATED_DESCRIPTOR + insertIndex + 1, """ + iget-object v$contextRegister, v$contextRegister, $conversionContextFieldName # copy obfuscated context field into free register + invoke-static {v$contextRegister, v$atomicReferenceRegister, v$charSequenceRegister}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; + move-result-object v$charSequenceRegister + move-object v${moveCharSequenceInstruction.registerA}, v${moveCharSequenceInstruction.registerB} # original instruction at the insertion point """ ) } - } ?: return TextReferenceFingerprint.toErrorResult() + } ?: return TextComponentContextFingerprint.toErrorResult() + + // endregion + + // region Hook for Short videos. ShortsTextComponentParentFingerprint.result?.let { context @@ -123,22 +141,23 @@ class ReturnYouTubeDislikePatch : BytecodePatch( return PatchResultError("Method signature did not match: $this $parameterTypes") val insertIndex = implementation!!.instructions.size - 1 - val spannedParameterRegister = (instruction(insertIndex) as OneRegisterInstruction).registerA val parameter = (instruction(insertIndex - 2) as BuilderInstruction35c).reference if (!parameter.toString().endsWith("Landroid/text/Spanned;")) return PatchResultError("Method signature parameter did not match: $parameter") - addInstructions( - insertIndex, - """ - invoke-static {v$spannedParameterRegister}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onShortsComponentCreated(Landroid/text/Spanned;)Landroid/text/Spanned; - move-result-object v$spannedParameterRegister - """ - ) + insertShorts(insertIndex, spannedParameterRegister) } } + + // Additional hook, called after user dislikes. + with(it.mutableMethod) { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2 + val overwriteRegister = (implementation!!.instructions.elementAt(insertIndex - 1) + as OneRegisterInstruction).registerA + insertShorts(insertIndex, overwriteRegister) + } } ?: return ShortsTextComponentParentFingerprint.toErrorResult() // endregion @@ -150,17 +169,21 @@ class ReturnYouTubeDislikePatch : BytecodePatch( const val INTEGRATIONS_PATCH_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;" - const val ON_COMPONENT_CREATED_DESCRIPTOR = - "$INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onComponentCreated(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;)V" - private fun MethodFingerprint.toPatch(voteKind: Vote) = VotePatch(this, voteKind) - } + private data class VotePatch(val fingerprint: MethodFingerprint, val voteKind: Vote) + private enum class Vote(val value: Int) { + LIKE(1), + DISLIKE(-1), + REMOVE_LIKE(0) + } - private data class VotePatch(val fingerprint: MethodFingerprint, val voteKind: Vote) - - private enum class Vote(val value: Int) { - LIKE(1), - DISLIKE(-1), - REMOVE_LIKE(0) + private fun MutableMethod.insertShorts(index: Int, register: Int) { + addInstructions( + index, """ + invoke-static {v$register}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onShortsComponentCreated(Landroid/text/Spanned;)Landroid/text/Spanned; + move-result-object v$register + """ + ) + } } } From fc89c865f94fffd748809eaf0504cc91f6389500 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Wed, 19 Apr 2023 12:20:48 +0400 Subject: [PATCH 26/34] fix(youtube/hide-video-action-buttons): change 'Hide create, clip and thanks buttons' to default off (#1923) --- .../youtube/layout/buttons/action/patch/HideButtonsPatch.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt index 1fcb40917..8e7106423 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt @@ -61,7 +61,7 @@ class HideButtonsPatch : ResourcePatch { SwitchPreference( "revanced_hide_action_button", StringResource("revanced_hide_action_button_title", "Hide create, clip and thanks buttons"), - true, + false, StringResource("revanced_hide_action_button_summary_on", "Buttons are hidden"), StringResource("revanced_hide_action_button_summary_off", "Buttons are shown") ), From beb8d9cbf254b4a2b2207a307934be65507dcf80 Mon Sep 17 00:00:00 2001 From: badawoll <129878899+badawoll@users.noreply.github.com> Date: Thu, 20 Apr 2023 00:33:51 +0000 Subject: [PATCH 27/34] feat(photomath/unlock-plus): bump compatibility to `8.21.1` (#1926) --- .../DisableSignatureDetectionCompatibility.kt | 30 ------------------- .../patch/SignatureDetectionPatch.kt | 2 -- .../annotations/UnlockPlusCompatibilty.kt | 26 ++++++++++++++-- 3 files changed, 24 insertions(+), 34 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/photomath/detection/signature/annotations/DisableSignatureDetectionCompatibility.kt diff --git a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/annotations/DisableSignatureDetectionCompatibility.kt b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/annotations/DisableSignatureDetectionCompatibility.kt deleted file mode 100644 index cd1eb5cce..000000000 --- a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/annotations/DisableSignatureDetectionCompatibility.kt +++ /dev/null @@ -1,30 +0,0 @@ -package app.revanced.patches.photomath.detection.signature.annotations - -import app.revanced.patcher.annotation.Compatibility -import app.revanced.patcher.annotation.Package - -@Compatibility( - [Package( - "com.microblink.photomath", arrayOf( - "8.6.0", - "8.7.0", - "8.8.0", - "8.9.0", - "8.10.0", - "8.11.0", - "8.12.0", - "8.13.0", - "8.14.0", - "8.15.0", - "8.16.0", - "8.17.0", - "8.18.0", - "8.18.1", - "8.19.0", - "8.20.0", - "8.21.0", - ) - )] -) -@Target(AnnotationTarget.CLASS) -internal annotation class DisableSignatureDetectionCompatibility diff --git a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt index 25d77a391..d8c5beaae 100644 --- a/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/photomath/detection/signature/patch/SignatureDetectionPatch.kt @@ -9,12 +9,10 @@ import app.revanced.patcher.extensions.replaceInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.photomath.detection.signature.annotations.DisableSignatureDetectionCompatibility import app.revanced.patches.photomath.detection.signature.fingerprints.CheckSignatureFingerprint import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Description("Disables detection of incorrect signature.") -@DisableSignatureDetectionCompatibility @Version("0.0.2") class SignatureDetectionPatch : BytecodePatch( listOf( diff --git a/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/annotations/UnlockPlusCompatibilty.kt b/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/annotations/UnlockPlusCompatibilty.kt index e8d50c365..29f8379df 100644 --- a/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/annotations/UnlockPlusCompatibilty.kt +++ b/src/main/kotlin/app/revanced/patches/photomath/misc/unlockplus/annotations/UnlockPlusCompatibilty.kt @@ -3,6 +3,28 @@ package app.revanced.patches.photomath.misc.unlockplus.annotations import app.revanced.patcher.annotation.Compatibility import app.revanced.patcher.annotation.Package -@Compatibility([Package("com.microblink.photomath")]) +@Compatibility( + [Package( + "com.microblink.photomath", arrayOf( + "8.6.0", + "8.7.0", + "8.8.0", + "8.9.0", + "8.10.0", + "8.11.0", + "8.12.0", + "8.13.0", + "8.14.0", + "8.15.0", + "8.16.0", + "8.17.0", + "8.18.0", + "8.18.1", + "8.19.0", + "8.20.0", + "8.21.0", + ) + )] +) @Target(AnnotationTarget.CLASS) -internal annotation class UnlockPlusCompatibilty \ No newline at end of file +internal annotation class UnlockPlusCompatibilty From 9d62f7cd6c00863e7dc7138b584f4a4523a2c7bc Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 20 Apr 2023 03:18:44 +0200 Subject: [PATCH 28/34] refactor: apply Kotlin coding conventions --- .../misc/fix/spoof/patch/ClientSpoofPatch.kt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt index c58e71c93..584ec2dc4 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.shared.misc.fix.spoof.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version @@ -23,15 +24,19 @@ class ClientSpoofPatch : BytecodePatch( listOf(UserAgentHeaderBuilderFingerprint) ) { override fun execute(context: BytecodeContext): PatchResult { - val result = UserAgentHeaderBuilderFingerprint.result!! - val method = result.mutableMethod + UserAgentHeaderBuilderFingerprint.result?.let { result -> + val insertIndex = result.scanResult.patternScanResult!!.endIndex + result.mutableMethod.apply { + val packageNameRegister = (instruction(insertIndex) as FiveRegisterInstruction).registerD + addInstruction(insertIndex, "const-string v$packageNameRegister, \"$ORIGINAL_PACKAGE_NAME\"") + } - val insertIndex = result.scanResult.patternScanResult!!.endIndex - val packageNameRegister = (method.instruction(insertIndex) as FiveRegisterInstruction).registerD - - val originalPackageName = "com.google.android.youtube" - method.addInstruction(insertIndex, "const-string v$packageNameRegister, \"$originalPackageName\"") + } ?: return UserAgentHeaderBuilderFingerprint.toErrorResult() return PatchResultSuccess() } + + private companion object { + private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube" + } } From 3e0c45c2dff9f6336e42fdd3d1b5b5de5af1b1cb Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 20 Apr 2023 03:19:56 +0200 Subject: [PATCH 29/34] fix(youtube/microg-support): remove incorrect patch dependency --- .../youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt index 72b6135a6..9a4b14016 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt @@ -25,7 +25,6 @@ import app.revanced.util.microg.MicroGBytecodeHelper [ MicroGResourcePatch::class, HideCastButtonPatch::class, - ClientSpoofPatch::class ] ) @Name("microg-support") From 091a25d46145b1c27791245fca0933e9c8a68e9a Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 20 Apr 2023 03:20:35 +0200 Subject: [PATCH 30/34] fix(youtube/microg-support): rename patch correctly --- .../youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt index 9a4b14016..9a5926896 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/microg/patch/bytecode/MicroGBytecodePatch.kt @@ -27,7 +27,7 @@ import app.revanced.util.microg.MicroGBytecodeHelper HideCastButtonPatch::class, ] ) -@Name("microg-support") +@Name("vanced-microg-support") @Description("Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.") @MicroGPatchCompatibility @Version("0.0.1") From 32fcd258c6b00315265c09380550a2e98b5ec9e7 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 20 Apr 2023 03:23:20 +0200 Subject: [PATCH 31/34] feat: use better patch description --- .../patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt | 2 +- .../misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt index 584ec2dc4..49c91185d 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/fix/spoof/patch/ClientSpoofPatch.kt @@ -17,7 +17,7 @@ import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction @Patch @Name("client-spoof") -@Description("Spoofs the YouTube or Vanced client to prevent playback issues.") +@Description("Spoofs a patched client to allow playback.") @ClientSpoofCompatibility @Version("0.0.1") class ClientSpoofPatch : BytecodePatch( diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt index cc5cbe780..0ec8f7dd4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt @@ -27,7 +27,7 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Patch @Name("spoof-signature-verification") -@Description("Spoofs the client to prevent playback issues.") +@Description("Spoofs a patched client to prevent playback issues.") @ProtobufSpoofCompatibility @DependsOn([IntegrationsPatch::class, SettingsPatch::class, PlayerTypeHookPatch::class]) @Version("0.0.1") From 0d47375092639e3e5dad8d67991004fc2f103606 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 20 Apr 2023 03:23:45 +0200 Subject: [PATCH 32/34] fix(youtube/spoof-signature-verification): depend on `client-spoof` patch --- .../fix/playback/patch/SpoofSignatureVerificationPatch.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt index 0ec8f7dd4..32b094c14 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/patch/SpoofSignatureVerificationPatch.kt @@ -14,6 +14,7 @@ import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.shared.misc.fix.spoof.patch.ClientSpoofPatch import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.youtube.misc.fix.playback.annotation.ProtobufSpoofCompatibility @@ -29,7 +30,12 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Name("spoof-signature-verification") @Description("Spoofs a patched client to prevent playback issues.") @ProtobufSpoofCompatibility -@DependsOn([IntegrationsPatch::class, SettingsPatch::class, PlayerTypeHookPatch::class]) +@DependsOn([ + IntegrationsPatch::class, + SettingsPatch::class, + PlayerTypeHookPatch::class, + ClientSpoofPatch::class +]) @Version("0.0.1") class SpoofSignatureVerificationPatch : BytecodePatch( listOf( From bc05e4494d914f944a831bfb83a150ad93bb342f Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:41:43 +0400 Subject: [PATCH 33/34] fix(youtube/hide-video-action-buttons): fix 'hide share button' (#1924) --- .../buttons/action/patch/HideButtonsPatch.kt | 30 +++++-------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt index 8e7106423..6d6f9ef36 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/patch/HideButtonsPatch.kt @@ -31,18 +31,11 @@ class HideButtonsPatch : ResourcePatch { StringResource("revanced_hide_buttons_title", "Hide action buttons"), listOf( SwitchPreference( - "revanced_hide_like_button", - StringResource("revanced_hide_like_button_title", "Hide like button"), + "revanced_hide_like_dislike_button", + StringResource("revanced_hide_like_dislike_button_title", "Hide like and dislike buttons"), false, - StringResource("revanced_hide_like_button_summary_on", "Like button is hidden"), - StringResource("revanced_hide_like_button_summary_off", "Like button is shown") - ), - SwitchPreference( - "revanced_hide_dislike_button", - StringResource("revanced_hide_dislike_button_title", "Hide dislike button"), - false, - StringResource("revanced_hide_dislike_button_summary_on", "Dislike button is hidden"), - StringResource("revanced_hide_dislike_button_summary_off", "Dislike button is shown") + StringResource("revanced_hide_like_dislike_button_summary_on", "Like and dislike buttons are hidden"), + StringResource("revanced_hide_like_dislike_button_summary_off", "Like and dislike buttons are shown") ), SwitchPreference( "revanced_hide_download_button", @@ -59,18 +52,11 @@ class HideButtonsPatch : ResourcePatch { StringResource("revanced_hide_playlist_button_summary_off", "Playlist button is shown") ), SwitchPreference( - "revanced_hide_action_button", - StringResource("revanced_hide_action_button_title", "Hide create, clip and thanks buttons"), + "revanced_hide_action_buttons", + StringResource("revanced_hide_action_buttons_title", "Hide all other action buttons"), false, - StringResource("revanced_hide_action_button_summary_on", "Buttons are hidden"), - StringResource("revanced_hide_action_button_summary_off", "Buttons are shown") - ), - SwitchPreference( - "revanced_hide_share_button", - StringResource("revanced_hide_share_button_title", "Hide share button"), - false, - StringResource("revanced_hide_share_button_summary_on", "Share button is hidden"), - StringResource("revanced_hide_share_button_summaryoff", "Share button is shown") + StringResource("revanced_hide_action_buttons_summary_on", "Share, remix, clip, thanks, shop, live chat buttons are hidden"), + StringResource("revanced_hide_action_buttons_summary_off", "Share, remix, clip, thanks, shop, live chat buttons are shown") ) ), StringResource("revanced_hide_buttons_summary", "Hide or show buttons under videos") From cfa9da5a2cb71e83ad769c3fc87baa2c010335d4 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 21 Apr 2023 13:43:16 +0000 Subject: [PATCH 34/34] chore(release): 2.169.0-dev.1 [skip ci] # [2.169.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.168.0...v2.169.0-dev.1) (2023-04-21) ### Bug Fixes * add missing annotation to patches ([#1882](https://github.com/revanced/revanced-patches/issues/1882)) ([d86b6a4](https://github.com/revanced/revanced-patches/commit/d86b6a4a659172c3f1db8eb883f28dfee4e83e4c)) * **youtube/hide-video-action-buttons:** change 'Hide create, clip and thanks buttons' to default off ([#1923](https://github.com/revanced/revanced-patches/issues/1923)) ([fc89c86](https://github.com/revanced/revanced-patches/commit/fc89c865f94fffd748809eaf0504cc91f6389500)) * **youtube/hide-video-action-buttons:** fix 'hide share button' ([#1924](https://github.com/revanced/revanced-patches/issues/1924)) ([bc05e44](https://github.com/revanced/revanced-patches/commit/bc05e4494d914f944a831bfb83a150ad93bb342f)) * **youtube/microg-support:** remove incorrect patch dependency ([3e0c45c](https://github.com/revanced/revanced-patches/commit/3e0c45c2dff9f6336e42fdd3d1b5b5de5af1b1cb)) * **youtube/microg-support:** rename patch correctly ([091a25d](https://github.com/revanced/revanced-patches/commit/091a25d46145b1c27791245fca0933e9c8a68e9a)) * **youtube/return-youtube-dislike:** render dislikes when scrolling into the screen ([#1873](https://github.com/revanced/revanced-patches/issues/1873)) ([85675b8](https://github.com/revanced/revanced-patches/commit/85675b800070de9752b2a4bfea3182381d4cfba4)) * **youtube/sponsorblock:** do not depend on `remember-playback-speed` patch ([b0834fa](https://github.com/revanced/revanced-patches/commit/b0834faa69755a94f70ae5075a10cf15e8a6b857)) * **youtube/sponsorblock:** fix autorepeat button layout ([#1868](https://github.com/revanced/revanced-patches/issues/1868)) ([5e148d9](https://github.com/revanced/revanced-patches/commit/5e148d9384e8f9f1bc8f5daa7e68a05574810329)) * **youtube/spoof-signature-verification:** depend on `client-spoof` patch ([0d47375](https://github.com/revanced/revanced-patches/commit/0d47375092639e3e5dad8d67991004fc2f103606)) * **youtubevanced/hide-ads:** hide more types of ads ([#1781](https://github.com/revanced/revanced-patches/issues/1781)) ([47ff447](https://github.com/revanced/revanced-patches/commit/47ff447f8ec0e5bbc174f34bd7d61b3031276641)) * **youtubevanced/hide-ads:** remove broken ad filter ([#1881](https://github.com/revanced/revanced-patches/issues/1881)) ([5b987e1](https://github.com/revanced/revanced-patches/commit/5b987e14e81a47691883a5b5196c7ffee03941d0)) ### Features * `change-package-name` patch ([#1864](https://github.com/revanced/revanced-patches/issues/1864)) ([f9a6672](https://github.com/revanced/revanced-patches/commit/f9a6672122eb28fe06c9f5e137906ad868a491d6)) * `enable-android-debugging` patch ([#1876](https://github.com/revanced/revanced-patches/issues/1876)) ([bd224d9](https://github.com/revanced/revanced-patches/commit/bd224d90deb838ee3e7bd0c16860023ebf113e96)) * **facebook:** `hide-inbox-ads` patch ([#1893](https://github.com/revanced/revanced-patches/issues/1893)) ([2cfc982](https://github.com/revanced/revanced-patches/commit/2cfc9829e119884ca566d6ad90fd0542317891d7)) * **id-austria:** bump compatibility to `2.6.0` ([#1827](https://github.com/revanced/revanced-patches/issues/1827)) ([f48e794](https://github.com/revanced/revanced-patches/commit/f48e794eebf9ea44008c4c8a3967ad039d19180a)) * **inshorts:** `hide-ads` patch ([#1828](https://github.com/revanced/revanced-patches/issues/1828)) ([04a2acc](https://github.com/revanced/revanced-patches/commit/04a2accfe9f9254af9074ad0a309d485cedb01cb)) * **memegenerator:** `unlock-pro` patch ([#1902](https://github.com/revanced/revanced-patches/issues/1902)) ([7d30541](https://github.com/revanced/revanced-patches/commit/7d3054178187bed294d156d3858613fa63a626ef)) * **photomath/unlock-plus:** bump compatibility to `8.21.1` ([#1926](https://github.com/revanced/revanced-patches/issues/1926)) ([beb8d9c](https://github.com/revanced/revanced-patches/commit/beb8d9cbf254b4a2b2207a307934be65507dcf80)) * **photomath:** bump compatibility up to `8.21.0` ([#1886](https://github.com/revanced/revanced-patches/issues/1886)) ([43464fd](https://github.com/revanced/revanced-patches/commit/43464fd6ffe6f097c574156146aeb23f8f026840)) * **reddit:** bump compatibility to `2023.12.0` ([#1825](https://github.com/revanced/revanced-patches/issues/1825)) ([e3666e6](https://github.com/revanced/revanced-patches/commit/e3666e68ed4816c85fbb110cb098f53fddf135f1)) * use better patch description ([32fcd25](https://github.com/revanced/revanced-patches/commit/32fcd258c6b00315265c09380550a2e98b5ec9e7)) * **youtube-music:** `bypass-certificate-checks` patch ([#1810](https://github.com/revanced/revanced-patches/issues/1810)) ([ef8f26f](https://github.com/revanced/revanced-patches/commit/ef8f26fb976c3044039f9bff0496088763ab66cd)) * **youtube/settings:** disable preferences and add dialog messages to preferences ([#1801](https://github.com/revanced/revanced-patches/issues/1801)) ([05023ba](https://github.com/revanced/revanced-patches/commit/05023bab1d94e04553ac274468bdba7a19ad9180)) * **youtube/sponsorblock:** skip to video highlight ([#1874](https://github.com/revanced/revanced-patches/issues/1874)) ([83747b7](https://github.com/revanced/revanced-patches/commit/83747b7aea33d8fe4b4b9514fdf7c9081c357410)) * **youtube:** bump compatibility to `18.08.37` ([29561ec](https://github.com/revanced/revanced-patches/commit/29561eca10e18e11f2d4a7f9bab2f12303490b6f)) * **youtube:** change default video speed and quality inside the settings menu ([#1880](https://github.com/revanced/revanced-patches/issues/1880)) ([fbb1763](https://github.com/revanced/revanced-patches/commit/fbb17636d8ab9f2a43ead896451804b04464527c)) * **youtube:** constrain compatibility to `18.08.37` ([7403fc8](https://github.com/revanced/revanced-patches/commit/7403fc86ae7b7d756a2939fa0a507f237aaf6edf)) * **youtube:** sponsorblock improvements ([#1557](https://github.com/revanced/revanced-patches/issues/1557)) ([b5d712a](https://github.com/revanced/revanced-patches/commit/b5d712a3326d1e8cdb8d8642aa7bd1bee6e30ac1)) * **youtube:** support version `18.08.37` ([4f4ceab](https://github.com/revanced/revanced-patches/commit/4f4ceab2cc32a38dd3967fd4e81f690330c08f5c)) --- CHANGELOG.md | 39 ++++++++++++++ README.md | 133 +++++++++++++++++++++++++++------------------- gradle.properties | 2 +- patches.json | 2 +- 4 files changed, 120 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ab57c48e..839be08b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,42 @@ +# [2.169.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.168.0...v2.169.0-dev.1) (2023-04-21) + + +### Bug Fixes + +* add missing annotation to patches ([#1882](https://github.com/revanced/revanced-patches/issues/1882)) ([d86b6a4](https://github.com/revanced/revanced-patches/commit/d86b6a4a659172c3f1db8eb883f28dfee4e83e4c)) +* **youtube/hide-video-action-buttons:** change 'Hide create, clip and thanks buttons' to default off ([#1923](https://github.com/revanced/revanced-patches/issues/1923)) ([fc89c86](https://github.com/revanced/revanced-patches/commit/fc89c865f94fffd748809eaf0504cc91f6389500)) +* **youtube/hide-video-action-buttons:** fix 'hide share button' ([#1924](https://github.com/revanced/revanced-patches/issues/1924)) ([bc05e44](https://github.com/revanced/revanced-patches/commit/bc05e4494d914f944a831bfb83a150ad93bb342f)) +* **youtube/microg-support:** remove incorrect patch dependency ([3e0c45c](https://github.com/revanced/revanced-patches/commit/3e0c45c2dff9f6336e42fdd3d1b5b5de5af1b1cb)) +* **youtube/microg-support:** rename patch correctly ([091a25d](https://github.com/revanced/revanced-patches/commit/091a25d46145b1c27791245fca0933e9c8a68e9a)) +* **youtube/return-youtube-dislike:** render dislikes when scrolling into the screen ([#1873](https://github.com/revanced/revanced-patches/issues/1873)) ([85675b8](https://github.com/revanced/revanced-patches/commit/85675b800070de9752b2a4bfea3182381d4cfba4)) +* **youtube/sponsorblock:** do not depend on `remember-playback-speed` patch ([b0834fa](https://github.com/revanced/revanced-patches/commit/b0834faa69755a94f70ae5075a10cf15e8a6b857)) +* **youtube/sponsorblock:** fix autorepeat button layout ([#1868](https://github.com/revanced/revanced-patches/issues/1868)) ([5e148d9](https://github.com/revanced/revanced-patches/commit/5e148d9384e8f9f1bc8f5daa7e68a05574810329)) +* **youtube/spoof-signature-verification:** depend on `client-spoof` patch ([0d47375](https://github.com/revanced/revanced-patches/commit/0d47375092639e3e5dad8d67991004fc2f103606)) +* **youtubevanced/hide-ads:** hide more types of ads ([#1781](https://github.com/revanced/revanced-patches/issues/1781)) ([47ff447](https://github.com/revanced/revanced-patches/commit/47ff447f8ec0e5bbc174f34bd7d61b3031276641)) +* **youtubevanced/hide-ads:** remove broken ad filter ([#1881](https://github.com/revanced/revanced-patches/issues/1881)) ([5b987e1](https://github.com/revanced/revanced-patches/commit/5b987e14e81a47691883a5b5196c7ffee03941d0)) + + +### Features + +* `change-package-name` patch ([#1864](https://github.com/revanced/revanced-patches/issues/1864)) ([f9a6672](https://github.com/revanced/revanced-patches/commit/f9a6672122eb28fe06c9f5e137906ad868a491d6)) +* `enable-android-debugging` patch ([#1876](https://github.com/revanced/revanced-patches/issues/1876)) ([bd224d9](https://github.com/revanced/revanced-patches/commit/bd224d90deb838ee3e7bd0c16860023ebf113e96)) +* **facebook:** `hide-inbox-ads` patch ([#1893](https://github.com/revanced/revanced-patches/issues/1893)) ([2cfc982](https://github.com/revanced/revanced-patches/commit/2cfc9829e119884ca566d6ad90fd0542317891d7)) +* **id-austria:** bump compatibility to `2.6.0` ([#1827](https://github.com/revanced/revanced-patches/issues/1827)) ([f48e794](https://github.com/revanced/revanced-patches/commit/f48e794eebf9ea44008c4c8a3967ad039d19180a)) +* **inshorts:** `hide-ads` patch ([#1828](https://github.com/revanced/revanced-patches/issues/1828)) ([04a2acc](https://github.com/revanced/revanced-patches/commit/04a2accfe9f9254af9074ad0a309d485cedb01cb)) +* **memegenerator:** `unlock-pro` patch ([#1902](https://github.com/revanced/revanced-patches/issues/1902)) ([7d30541](https://github.com/revanced/revanced-patches/commit/7d3054178187bed294d156d3858613fa63a626ef)) +* **photomath/unlock-plus:** bump compatibility to `8.21.1` ([#1926](https://github.com/revanced/revanced-patches/issues/1926)) ([beb8d9c](https://github.com/revanced/revanced-patches/commit/beb8d9cbf254b4a2b2207a307934be65507dcf80)) +* **photomath:** bump compatibility up to `8.21.0` ([#1886](https://github.com/revanced/revanced-patches/issues/1886)) ([43464fd](https://github.com/revanced/revanced-patches/commit/43464fd6ffe6f097c574156146aeb23f8f026840)) +* **reddit:** bump compatibility to `2023.12.0` ([#1825](https://github.com/revanced/revanced-patches/issues/1825)) ([e3666e6](https://github.com/revanced/revanced-patches/commit/e3666e68ed4816c85fbb110cb098f53fddf135f1)) +* use better patch description ([32fcd25](https://github.com/revanced/revanced-patches/commit/32fcd258c6b00315265c09380550a2e98b5ec9e7)) +* **youtube-music:** `bypass-certificate-checks` patch ([#1810](https://github.com/revanced/revanced-patches/issues/1810)) ([ef8f26f](https://github.com/revanced/revanced-patches/commit/ef8f26fb976c3044039f9bff0496088763ab66cd)) +* **youtube/settings:** disable preferences and add dialog messages to preferences ([#1801](https://github.com/revanced/revanced-patches/issues/1801)) ([05023ba](https://github.com/revanced/revanced-patches/commit/05023bab1d94e04553ac274468bdba7a19ad9180)) +* **youtube/sponsorblock:** skip to video highlight ([#1874](https://github.com/revanced/revanced-patches/issues/1874)) ([83747b7](https://github.com/revanced/revanced-patches/commit/83747b7aea33d8fe4b4b9514fdf7c9081c357410)) +* **youtube:** bump compatibility to `18.08.37` ([29561ec](https://github.com/revanced/revanced-patches/commit/29561eca10e18e11f2d4a7f9bab2f12303490b6f)) +* **youtube:** change default video speed and quality inside the settings menu ([#1880](https://github.com/revanced/revanced-patches/issues/1880)) ([fbb1763](https://github.com/revanced/revanced-patches/commit/fbb17636d8ab9f2a43ead896451804b04464527c)) +* **youtube:** constrain compatibility to `18.08.37` ([7403fc8](https://github.com/revanced/revanced-patches/commit/7403fc86ae7b7d756a2939fa0a507f237aaf6edf)) +* **youtube:** sponsorblock improvements ([#1557](https://github.com/revanced/revanced-patches/issues/1557)) ([b5d712a](https://github.com/revanced/revanced-patches/commit/b5d712a3326d1e8cdb8d8642aa7bd1bee6e30ac1)) +* **youtube:** support version `18.08.37` ([4f4ceab](https://github.com/revanced/revanced-patches/commit/4f4ceab2cc32a38dd3967fd4e81f690330c08f5c)) + # [2.168.0](https://github.com/revanced/revanced-patches/compare/v2.167.1...v2.168.0) (2023-04-13) diff --git a/README.md b/README.md index 12bc437ad..542599e94 100644 --- a/README.md +++ b/README.md @@ -9,60 +9,60 @@ The official Patch bundle provided by ReVanced and the community. | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `always-autorepeat` | Always repeats the playing video again. | 18.05.40 | -| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all | -| `comments` | Hides components related to comments. | 18.05.40 | -| `copy-video-url` | Adds buttons in player to copy video links. | 18.05.40 | +| `always-autorepeat` | Always repeats the playing video again. | 18.08.37 | +| `client-spoof` | Spoofs a patched client to allow playback. | all | +| `comments` | Hides components related to comments. | 18.08.37 | +| `copy-video-url` | Adds buttons in player to copy video links. | 18.08.37 | | `custom-branding` | Changes the YouTube launcher icon and name to your choice (defaults to ReVanced). | all | -| `custom-video-buffer` | Lets you change the buffers of videos. | 18.05.40 | -| `custom-video-speed` | Adds more video speed options. | 18.05.40 | -| `debugging` | Adds debugging options. | all | -| `disable-auto-captions` | Disable forced captions from being automatically enabled. | 18.05.40 | -| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 18.05.40 | -| `disable-player-popup-panels` | Disables panels from appearing automatically when going into fullscreen (playlist or live chat). | 18.05.40 | -| `disable-shorts-on-startup` | Disables playing YouTube Shorts when launching YouTube. | 18.05.40 | +| `custom-video-buffer` | Lets you change the buffers of videos. | 18.08.37 | +| `custom-video-speed` | Adds more video speed options. | 18.08.37 | +| `disable-auto-captions` | Disable forced captions from being automatically enabled. | 18.08.37 | +| `disable-fullscreen-panels` | Disables video description and comments panel in fullscreen view. | 18.08.37 | +| `disable-player-popup-panels` | Disables panels from appearing automatically when going into fullscreen (playlist or live chat). | 18.08.37 | +| `disable-shorts-on-startup` | Disables playing YouTube Shorts when launching YouTube. | 18.08.37 | | `disable-zoom-haptics` | Disables haptics when zooming. | all | -| `downloads` | Enables downloading music and videos from YouTube. | 18.05.40 | -| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 18.05.40 | -| `general-ads` | Removes general ads. | 18.05.40 | -| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 18.05.40 | -| `hide-album-cards` | Hides the album cards below the artist description. | 18.05.40 | -| `hide-artist-card` | Hides the artist card below the searchbar. | 18.05.40 | -| `hide-autoplay-button` | Hides the autoplay button in the video player. | 18.05.40 | -| `hide-breaking-news-shelf` | Hides the breaking news shelf on the homepage tab. | 18.05.40 | -| `hide-captions-button` | Hides the captions button on video player. | 18.05.40 | +| `downloads` | Enables downloading music and videos from YouTube. | 18.08.37 | +| `enable-debugging` | Adds debugging options. | all | +| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 18.08.37 | +| `general-ads` | Removes general ads. | 18.08.37 | +| `hdr-auto-brightness` | Makes the brightness of HDR videos follow the system default. | 18.08.37 | +| `hide-album-cards` | Hides the album cards below the artist description. | 18.08.37 | +| `hide-artist-card` | Hides the artist card below the searchbar. | 18.08.37 | +| `hide-autoplay-button` | Hides the autoplay button in the video player. | 18.08.37 | +| `hide-breaking-news-shelf` | Hides the breaking news shelf on the homepage tab. | 18.08.37 | +| `hide-captions-button` | Hides the captions button on video player. | 18.08.37 | | `hide-cast-button` | Hides the cast button in the video player. | all | -| `hide-create-button` | Hides the create button in the navigation bar. | 18.05.40 | -| `hide-crowdfunding-box` | Hides the crowdfunding box between the player and video description. | 18.05.40 | -| `hide-email-address` | Hides the email address in the account switcher. | 18.05.40 | -| `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 18.05.40 | -| `hide-floating-microphone-button` | Hides the floating microphone button which appears in search. | 18.05.40 | -| `hide-info-cards` | Hides info cards in videos. | 18.05.40 | -| `hide-my-mix` | Hides mix playlists. | 18.05.40 | +| `hide-create-button` | Hides the create button in the navigation bar. | 18.08.37 | +| `hide-crowdfunding-box` | Hides the crowdfunding box between the player and video description. | 18.08.37 | +| `hide-email-address` | Hides the email address in the account switcher. | 18.08.37 | +| `hide-endscreen-cards` | Hides the suggested video cards at the end of a video in fullscreen. | 18.08.37 | +| `hide-floating-microphone-button` | Hides the floating microphone button which appears in search. | 18.08.37 | +| `hide-info-cards` | Hides info cards in videos. | 18.08.37 | +| `hide-my-mix` | Hides mix playlists. | 18.08.37 | | `hide-player-buttons` | Adds the option to hide video player previous and next buttons. | all | -| `hide-seekbar` | Hides the seekbar. | 18.05.40 | -| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 18.05.40 | -| `hide-timestamp` | Hides timestamp in video player. | 18.05.40 | -| `hide-video-action-buttons` | Adds the options to hide action buttons under a video. | 18.05.40 | -| `hide-watch-in-vr` | Hides the option to watch in VR from the player settings flyout panel. | 18.05.40 | -| `hide-watermark` | Hides creator's watermarks on videos. | 18.05.40 | -| `microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 18.05.40 | -| `minimized-playback` | Enables minimized and background playback. | 18.05.40 | -| `old-quality-layout` | Enables the original video quality flyout in the video player settings | 18.05.40 | -| `open-links-externally` | Open links outside of the app directly in your browser. | 18.05.40 | +| `hide-seekbar` | Hides the seekbar. | 18.08.37 | +| `hide-shorts-button` | Hides the shorts button on the navigation bar. | 18.08.37 | +| `hide-timestamp` | Hides timestamp in video player. | 18.08.37 | +| `hide-video-action-buttons` | Adds the options to hide action buttons under a video. | 18.08.37 | +| `hide-watch-in-vr` | Hides the option to watch in VR from the player settings flyout panel. | 18.08.37 | +| `hide-watermark` | Hides creator's watermarks on videos. | 18.08.37 | +| `minimized-playback` | Enables minimized and background playback. | 18.08.37 | +| `old-quality-layout` | Enables the original video quality flyout in the video player settings | 18.08.37 | +| `open-links-externally` | Open links outside of the app directly in your browser. | 18.08.37 | | `premium-heading` | Shows premium branding on the home screen. | all | -| `remember-playback-speed` | Adds the ability to remember the playback speed you chose in the video playback speed flyout. | 18.05.40 | -| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 18.05.40 | -| `remove-player-button-background` | Removes the background from the video player buttons. | 18.05.40 | -| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 18.05.40 | -| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 18.05.40 | -| `sponsorblock` | Integrates SponsorBlock which allows skipping video segments such as sponsored content. | 18.05.40 | -| `spoof-app-version` | Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI. | 18.05.40 | -| `spoof-signature-verification` | Spoofs the client to prevent playback issues. | 18.05.40 | -| `swipe-controls` | Adds volume and brightness swipe controls. | 18.05.40 | -| `tablet-mini-player` | Enables the tablet mini player layout. | 18.05.40 | +| `remember-playback-speed` | Adds the ability to remember the playback speed you chose in the video playback speed flyout. | 18.08.37 | +| `remember-video-quality` | Adds the ability to remember the video quality you chose in the video quality flyout. | 18.08.37 | +| `remove-player-button-background` | Removes the background from the video player buttons. | 18.08.37 | +| `return-youtube-dislike` | Shows the dislike count of videos using the Return YouTube Dislike API. | 18.08.37 | +| `seekbar-tapping` | Enables tap-to-seek on the seekbar of the video player. | 18.08.37 | +| `sponsorblock` | Integrates SponsorBlock which allows skipping video segments such as sponsored content. | 18.08.37 | +| `spoof-app-version` | Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI. | 18.08.37 | +| `spoof-signature-verification` | Spoofs a patched client to prevent playback issues. | 18.08.37 | +| `swipe-controls` | Adds volume and brightness swipe controls. | 18.08.37 | +| `tablet-mini-player` | Enables the tablet mini player layout. | 18.08.37 | | `theme` | Applies a custom theme. | all | -| `video-ads` | Removes ads in the video player. | 18.05.40 | +| `vanced-microg-support` | Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG. | 18.08.37 | +| `video-ads` | Removes ads in the video player. | 18.08.37 | ### [📦 `com.google.android.apps.youtube.music`](https://play.google.com/store/apps/details?id=com.google.android.apps.youtube.music) @@ -71,6 +71,7 @@ The official Patch bundle provided by ReVanced and the community. | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| | `background-play` | Enables playing music in the background. | all | +| `bypass-certificate-checks` | Bypasses certificate checks which prevent YouTube Music from working on Android Auto. | 5.39.52 | | `codecs-unlock` | Adds more audio codec options. The new audio codecs usually result in better audio quality. | all | | `compact-header` | Hides the music category bar at the top of the homepage. | all | | `exclusive-audio-playback` | Enables the option to play music without video. | all | @@ -153,8 +154,8 @@ The official Patch bundle provided by ReVanced and the community. | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `general-reddit-ads` | Removes general ads from the Reddit frontpage and subreddits. | 2023.10.0 | -| `hide-subreddit-banner` | Hides banner ads from comments on subreddits. | 2023.10.0 | +| `general-reddit-ads` | Removes general ads from the Reddit frontpage and subreddits. | 2023.12.0 | +| `hide-subreddit-banner` | Hides banner ads from comments on subreddits. | 2023.12.0 | | `premium-icon-reddit` | Unlocks premium Reddit app icons. | all | @@ -163,7 +164,7 @@ The official Patch bundle provided by ReVanced and the community. | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `client-spoof` | Spoofs the YouTube or Vanced client to prevent playback issues. | all | +| `client-spoof` | Spoofs a patched client to allow playback. | all | | `hide-ads` | Removes general ads. | all | @@ -181,8 +182,8 @@ The official Patch bundle provided by ReVanced and the community. | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `remove-root-detection` | Removes the check for root permissions and unlocked bootloader. | 2.5.2 | -| `spoof-signature` | Spoofs the signature of the app. | 2.5.2 | +| `remove-root-detection` | Removes the check for root permissions and unlocked bootloader. | 2.6.0 | +| `spoof-signature` | Spoofs the signature of the app. | 2.6.0 | ### [📦 `com.myprog.hexedit`](https://play.google.com/store/apps/details?id=com.myprog.hexedit) @@ -201,6 +202,22 @@ The official Patch bundle provided by ReVanced and the community. | `enable-on-demand` | Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads. | all | +### [📦 `com.nis.app`](https://play.google.com/store/apps/details?id=com.nis.app) +
+ +| 💊 Patch | 📜 Description | 🏹 Target Version | +|:--------:|:--------------:|:-----------------:| +| `hide-ads` | Removes ads from Inshorts. | all | +
+ +### [📦 `com.facebook.orca`](https://play.google.com/store/apps/details?id=com.facebook.orca) +
+ +| 💊 Patch | 📜 Description | 🏹 Target Version | +|:--------:|:--------------:|:-----------------:| +| `hide-inbox-ads` | Hides ads in inbox. | all | +
+ ### [📦 `com.instagram.android`](https://play.google.com/store/apps/details?id=com.instagram.android)
@@ -270,7 +287,7 @@ The official Patch bundle provided by ReVanced and the community. | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `unlock-plus` | Unlocks plus features. | all | +| `unlock-plus` | Unlocks plus features. | 8.9.0 |
### [📦 `io.yuka.android`](https://play.google.com/store/apps/details?id=io.yuka.android) @@ -321,6 +338,14 @@ The official Patch bundle provided by ReVanced and the community. | `unlock-pro` | Unlocks all professional features. | 3.4.9 | +### [📦 `com.zombodroid.MemeGenerator`](https://play.google.com/store/apps/details?id=com.zombodroid.MemeGenerator) +
+ +| 💊 Patch | 📜 Description | 🏹 Target Version | +|:--------:|:--------------:|:-----------------:| +| `unlock-pro` | Unlocks pro features. | 4.6364 | +
+ ### [📦 `com.awedea.nyx`](https://play.google.com/store/apps/details?id=com.awedea.nyx)
diff --git a/gradle.properties b/gradle.properties index 07774b7fa..244230232 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ kotlin.code.style = official -version = 2.168.0 +version = 2.169.0-dev.1 diff --git a/patches.json b/patches.json index 0e6cf82ab..db1e2a2cc 100644 --- a/patches.json +++ b/patches.json @@ -1 +1 @@ -[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["14.3.3","14.4.0","14.5.0","14.5.2","14.6.0","14.6.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded steam ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["14.3.3","14.4.0","14.5.0","14.5.2","14.6.0","14.6.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["14.3.3","14.4.0","14.5.0","14.5.2","14.6.0","14.6.1"]}]},{"name":"client-spoof","description":"Spoofs the YouTube or Vanced client to prevent playback issues.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]},{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","comments-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"custom-video-speed","description":"Adds more video speed options.","version":"0.0.1","excluded":false,"options":[{"key":"granularity","title":"Video speed granularity","description":"The granularity of the video speeds. The higher the value, the more speeds will be available.","required":true,"choices":null},{"key":"min","title":"Minimum video speed","description":"The minimum video speed.","required":true,"choices":null},{"key":"max","title":"Maximum video speed","description":"The maximum video speed. Must be greater than the minimum video speed and smaller than 5.","required":true,"choices":null}],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"debugging","description":"Adds debugging options.","version":"0.0.1","excluded":false,"options":[{"key":"debuggable","title":"App debugging","description":"Whether to make the app debuggable on Android.","required":false,"choices":null}],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"disable-capture-restriction","description":"Allows capturing Spotify\u0027s audio output while screen sharing or screen recording.","version":"0.0.2","excluded":false,"options":[],"dependencies":["disable-capture-restriction-resource-patch"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Enables downloading music and videos from YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"enable-wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"general-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["GeneralAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"general-reddit-ads","description":"Removes general ads from the Reddit frontpage and subreddits.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":["2021.45.0","2022.43.0","2023.05.0","2023.06.0","2023.07.0","2023.07.1","2023.08.0","2023.09.0","2023.09.1","2023.10.0"]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-artist-card","description":"Hides the artist card below the searchbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-create-button","description":"Hides the create button in the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","resource-mapping","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52"]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-my-mix","description":"Hides mix playlists.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-shorts-button","description":"Hides the shorts button on the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-subreddit-banner","description":"Hides banner ads from comments on subreddits.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":["2023.05.0","2023.06.0","2023.07.0","2023.07.1","2023.08.0","2023.09.0","2023.09.1","2023.10.0"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":[]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["music-microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"premium-unlock","description":"Unlocks premium functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.citra.citra_emu","versions":[]},{"name":"org.citra.citra_emu.canary","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-playback-speed","description":"Adds the ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","video-id-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-player-button-background","description":"Removes the background from the video player buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":["2.5.2"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["video-information","player-controls-bytecode-patch","player-type-hook","integrations","sponsorblock-resource-patch","video-id-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":["2.5.2"]}]},{"name":"spoof-signature-verification","description":"Spoofs the client to prevent playback issues.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]},{"name":"tasteBuilder-remover","description":"Removes the \"Tell us which artists you like\" card from the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"darkThemeSeekbarColor","title":"Dark theme seekbar color","description":"The background color of the seekbar of the dark theme. Leave empty for default color.","required":false,"choices":null}],"dependencies":["litho-components-theme"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":[]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40"]}]}] \ No newline at end of file +[{"name":"always-autorepeat","description":"Always repeats the playing video again.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"background-play","description":"Enables playing music in the background.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"block-audio-ads","description":"Blocks audio ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["14.3.3","14.4.0","14.5.0","14.5.2","14.6.0","14.6.1"]}]},{"name":"block-embedded-ads","description":"Blocks embedded steam ads using services like TTV.lol or PurpleAdBlocker.","version":"0.0.1","excluded":false,"options":[],"dependencies":["block-video-ads","integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["14.3.3","14.4.0","14.5.0","14.5.2","14.6.0","14.6.1"]}]},{"name":"block-video-ads","description":"Blocks video ads in streams and VODs.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":["14.3.3","14.4.0","14.5.0","14.5.2","14.6.0","14.6.1"]}]},{"name":"bypass-certificate-checks","description":"Bypasses certificate checks which prevent YouTube Music from working on Android Auto.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52","5.40.51","5.41.50","5.48.52"]}]},{"name":"change-package-name","description":"Changes the package name.","version":"0.0.1","excluded":true,"options":[{"key":"packageName","title":"Package name","description":"The name of the package to rename of the app.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"client-spoof","description":"Spoofs a patched client to allow playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]},{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"codecs-unlock","description":"Adds more audio codec options. The new audio codecs usually result in better audio quality.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"comments","description":"Hides components related to comments.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","comments-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"compact-header","description":"Hides the music category bar at the top of the homepage.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"copy-video-url","description":"Adds buttons in player to copy video links.","version":"0.0.1","excluded":false,"options":[],"dependencies":["copy-video-url-resource","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"custom-branding","description":"Changes the YouTube launcher icon and name to your choice (defaults to ReVanced).","version":"0.0.1","excluded":false,"options":[{"key":"appName","title":"Application Name","description":"The name of the application it will show on your home screen.","required":true,"choices":null},{"key":"iconPath","title":"App Icon Path","description":"A path containing mipmap resource folders with icons.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"custom-video-buffer","description":"Lets you change the buffers of videos.","version":"0.0.1","excluded":true,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"custom-video-speed","description":"Adds more video speed options.","version":"0.0.1","excluded":false,"options":[{"key":"granularity","title":"Video speed granularity","description":"The granularity of the video speeds. The higher the value, the more speeds will be available.","required":true,"choices":null},{"key":"min","title":"Minimum video speed","description":"The minimum video speed.","required":true,"choices":null},{"key":"max","title":"Maximum video speed","description":"The maximum video speed. Must be greater than the minimum video speed and smaller than 5.","required":true,"choices":null}],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"debug-mode","description":"Enables Twitch\u0027s internal debugging mode.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"disable-ads","description":"Disables ads in HexEditor.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.myprog.hexedit","versions":[]}]},{"name":"disable-auto-captions","description":"Disable forced captions from being automatically enabled.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"disable-capture-restriction","description":"Allows capturing Spotify\u0027s audio output while screen sharing or screen recording.","version":"0.0.2","excluded":false,"options":[],"dependencies":["disable-capture-restriction-resource-patch"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"disable-fullscreen-panels","description":"Disables video description and comments panel in fullscreen view.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"disable-login-requirement","description":"Do not force login.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"disable-player-popup-panels","description":"Disables panels from appearing automatically when going into fullscreen (playlist or live chat).","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"disable-shorts-on-startup","description":"Disables playing YouTube Shorts when launching YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"disable-zoom-haptics","description":"Disables haptics when zooming.","version":"0.0.1","excluded":false,"options":[],"dependencies":["settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"downloads","description":"Enables downloading music and videos from YouTube.","version":"0.0.1","excluded":false,"options":[],"dependencies":["downloads-resource-patch","player-controls-bytecode-patch","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"downloads","description":"Removes download restrictions and changes the default path to download to.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"dynamic-color","description":"Replaces the default Twitter Blue with the users Material You palette.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"enable-android-debugging","description":"Enables Android debugging capabilities.","version":"0.0.1","excluded":false,"options":[{"key":"debuggable","title":"App debugging","description":"Whether to make the app debuggable on Android.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[]},{"name":"enable-debugging","description":"Adds debugging options.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings","enable-android-debugging"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"enable-on-demand","description":"Enables listening to songs on-demand, allowing to play any song from playlists, albums or artists without limitations. This does not remove ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.lite","versions":[]}]},{"name":"enable-wide-searchbar","description":"Replaces the search icon with a wide search bar. This will hide the YouTube logo when active.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"exclusive-audio-playback","description":"Enables the option to play music without video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"export-all-activities","description":"Makes all app activities exportable.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"feed-filter","description":"Filters tiktok videos: removing ads, removing livestreams.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"fix-google-login","description":"Allows logging in with a Google account.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"general-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["GeneralAdsResourcePatch","VerticalScrollPatch","FixBackToExitGesturePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"general-reddit-ads","description":"Removes general ads from the Reddit frontpage and subreddits.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":["2021.45.0","2022.43.0","2023.05.0","2023.06.0","2023.07.0","2023.07.1","2023.08.0","2023.09.0","2023.09.1","2023.10.0","2023.11.0","2023.12.0"]}]},{"name":"hdr-auto-brightness","description":"Makes the brightness of HDR videos follow the system default.","version":"0.0.2","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-ads","description":"Removes ads from TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"hide-ads","description":"Hides ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-ads","description":"Removes general ads.","version":"0.0.1","excluded":false,"options":[],"dependencies":["VerticalScrollPatch"],"compatiblePackages":[{"name":"com.vanced.android.youtube","versions":[]}]},{"name":"hide-ads","description":"Removes ads from Inshorts.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.nis.app","versions":[]}]},{"name":"hide-album-cards","description":"Hides the album cards below the artist description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-album-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-artist-card","description":"Hides the artist card below the searchbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-autoplay-button","description":"Hides the autoplay button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","resource-mapping"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-breaking-news-shelf","description":"Hides the breaking news shelf on the homepage tab.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","breaking-news-shelf-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-captions-button","description":"Hides the captions button on video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-cast-button","description":"Hides the cast button in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-create-button","description":"Hides the create button in the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","resource-mapping","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-crowdfunding-box","description":"Hides the crowdfunding box between the player and video description.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","crowdfunding-box-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-email-address","description":"Hides the email address in the account switcher.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-email-address-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-endscreen-cards","description":"Hides the suggested video cards at the end of a video in fullscreen.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","hide-endscreen-cards-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-floating-microphone-button","description":"Hides the floating microphone button which appears in search.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideFloatingMicrophoneButtonResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-get-premium","description":"Removes all \"Get Premium\" evidences from the avatar menu.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":["5.14.53","5.16.51","5.17.51","5.21.52","5.22.54","5.23.50","5.25.51","5.25.52","5.26.52","5.27.51","5.28.52","5.29.52","5.31.50","5.34.51","5.36.51","5.38.53","5.39.52"]}]},{"name":"hide-inbox-ads","description":"Hides ads in inbox.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.facebook.orca","versions":[]}]},{"name":"hide-info-cards","description":"Hides info cards in videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","HideInfocardsResourcePatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-my-mix","description":"Hides mix playlists.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-player-buttons","description":"Adds the option to hide video player previous and next buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"hide-premium-navbar","description":"Removes the premium tab from the navbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping"],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"hide-recommended-users","description":"Hides recommended users.","version":"0.0.1","excluded":false,"options":[],"dependencies":["json-hook"],"compatiblePackages":[{"name":"com.twitter.android","versions":[]}]},{"name":"hide-seekbar","description":"Hides the seekbar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-shorts-button","description":"Hides the shorts button on the navigation bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","ResolvePivotBarFingerprintsPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-subreddit-banner","description":"Hides banner ads from comments on subreddits.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":["2023.05.0","2023.06.0","2023.07.0","2023.07.1","2023.08.0","2023.09.0","2023.09.1","2023.10.0","2023.11.0","2023.12.0"]}]},{"name":"hide-timeline-ads","description":"Removes ads from the timeline.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.instagram.android","versions":[]}]},{"name":"hide-timestamp","description":"Hides timestamp in video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-video-action-buttons","description":"Adds the options to hide action buttons under a video.","version":"0.0.1","excluded":false,"options":[],"dependencies":["resource-mapping","LithoFilterPatch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-views-stats","description":"Hides the view stats under tweets.","version":"0.0.1","excluded":false,"options":[],"dependencies":["HideViewsBytecodePatch"],"compatiblePackages":[{"name":"com.twitter.android","versions":["9.69.1-release.0","9.71.0-release.0"]}]},{"name":"hide-watch-in-vr","description":"Hides the option to watch in VR from the player settings flyout panel.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"hide-watermark","description":"Hides creator\u0027s watermarks on videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"minimized-playback","description":"Enables minimized and background playback.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"minimized-playback-music","description":"Enables minimized playback on Kids music.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-microg-support","description":"Allows YouTube Music ReVanced to run without root and under a different package name.","version":"0.0.2","excluded":false,"options":[],"dependencies":["music-microg-resource-patch"],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"music-video-ads","description":"Removes ads in the music player.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"old-quality-layout","description":"Enables the original video quality flyout in the video player settings","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"open-links-externally","description":"Open links outside of the app directly in your browser.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"playback-speed","description":"Enables the playback speed option for all videos.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"predictive-back-gesture","description":"Enables the predictive back gesture introduced on Android 13.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"premium-heading","description":"Shows premium branding on the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"premium-icon-reddit","description":"Unlocks premium Reddit app icons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.reddit.frontpage","versions":[]}]},{"name":"premium-unlock","description":"Unlocks premium functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.citra.citra_emu","versions":[]},{"name":"org.citra.citra_emu.canary","versions":[]}]},{"name":"pro-unlock","description":"Unlocks pro-only functions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.backdrops.wallpapers","versions":["4.52"]}]},{"name":"promo-code-unlock","description":"Disables the validation of promo code. Any code will work to unlock all features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["spoof-cert-patch"],"compatiblePackages":[{"name":"de.dwd.warnapp","versions":[]}]},{"name":"remember-playback-speed","description":"Adds the ability to remember the playback speed you chose in the video playback speed flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","video-id-hook","video-information"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.08.37"]}]},{"name":"remember-video-quality","description":"Adds the ability to remember the video quality you chose in the video quality flyout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.08.37"]}]},{"name":"remove-ads","description":"Removes all ads from the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.binarymode.android.irplus","versions":[]}]},{"name":"remove-bootloader-detection","description":"Removes the check for an unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-broadcasts-restriction","description":"Enables starting/stopping NetGuard via broadcasts.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[{"name":"eu.faircode.netguard","versions":[]}]},{"name":"remove-player-button-background","description":"Removes the background from the video player buttons.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions and unlocked bootloader.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":["2.5.2","2.6.0"]}]},{"name":"remove-root-detection","description":"Removes the check for root permissions.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.bmf.bmf2go","versions":["2.2.0"]}]},{"name":"remove-screenshot-restriction","description":"Removes the restriction of taking screenshots in apps that normally wouldn\u0027t allow it.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"return-youtube-dislike","description":"Shows the dislike count of videos using the Return YouTube Dislike API.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","return-youtube-dislike-resource-patch","player-type-hook"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.08.37"]}]},{"name":"seekbar-tapping","description":"Enables tap-to-seek on the seekbar of the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"settings","description":"Adds ReVanced settings to TikTok.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"settings","description":"Adds settings menu to Twitch.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings-resource-patch"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-deleted-messages","description":"Shows deleted chat messages behind a clickable spoiler.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"tv.twitch.android.app","versions":[]}]},{"name":"show-seekbar","description":"Shows progress bar for all video.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":[]},{"name":"com.zhiliaoapp.musically","versions":[]}]},{"name":"sim-spoof","description":"Spoofs the information which is retrieved from the sim-card.","version":"0.0.1","excluded":true,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.ss.android.ugc.trill","versions":["27.8.3"]},{"name":"com.zhiliaoapp.musically","versions":["27.8.3"]}]},{"name":"sponsorblock","description":"Integrates SponsorBlock which allows skipping video segments such as sponsored content.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","video-id-hook","video-information","player-type-hook","player-controls-bytecode-patch","sponsorblock-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.08.37"]}]},{"name":"spoof-app-version","description":"Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"spoof-signature","description":"Spoofs the signature of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"at.gv.oe.app","versions":["2.5.2","2.6.0"]}]},{"name":"spoof-signature-verification","description":"Spoofs a patched client to prevent playback issues.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings","player-type-hook","client-spoof"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"spoof-wifi-connection","description":"Spoofs an existing Wi-Fi connection.","version":"0.0.1","excluded":true,"options":[],"dependencies":[],"compatiblePackages":[]},{"name":"spotify-theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"backgroundColor","title":"Background color","description":"The background color. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentColor","title":"Accent color","description":"The accent color (\u0027spotify green\u0027 by default). Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"accentPressedColor","title":"Pressed accent for the dark theme","description":"The color when accented buttons are pressed, by default slightly darker than accent. Can be a hex color or a resource reference.","required":false,"choices":null}],"dependencies":[],"compatiblePackages":[{"name":"com.spotify.music","versions":[]}]},{"name":"swipe-controls","description":"Adds volume and brightness swipe controls.","version":"0.0.3","excluded":false,"options":[],"dependencies":["integrations","player-type-hook","swipe-controls-resource-patch"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"tablet-mini-player","description":"Enables the tablet mini player layout.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["18.08.37"]}]},{"name":"tasteBuilder-remover","description":"Removes the \"Tell us which artists you like\" card from the home screen.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"theme","description":"Applies a custom theme.","version":"0.0.1","excluded":false,"options":[{"key":"darkThemeBackgroundColor","title":"Background color for the dark theme","description":"The background color of the dark theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"lightThemeBackgroundColor","title":"Background color for the light theme","description":"The background color of the light theme. Can be a hex color or a resource reference.","required":false,"choices":null},{"key":"darkThemeSeekbarColor","title":"Dark theme seekbar color","description":"The background color of the seekbar of the dark theme. Leave empty for default color.","required":false,"choices":null}],"dependencies":["litho-components-theme"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":[]}]},{"name":"unlock-paid-widgets","description":"Unlocks paid widgets of the app","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.dci.dev.androidtwelvewidgets","versions":[]}]},{"name":"unlock-plus","description":"Unlocks plus features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureDetectionPatch"],"compatiblePackages":[{"name":"com.microblink.photomath","versions":["8.6.0","8.7.0","8.8.0","8.9.0","8.10.0","8.11.0","8.12.0","8.13.0","8.14.0","8.15.0","8.16.0","8.17.0","8.18.0","8.18.1","8.19.0","8.20.0","8.21.0"]}]},{"name":"unlock-premium","description":"Unlocks premium features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"io.yuka.android","versions":[]}]},{"name":"unlock-prime","description":"Unlocks Nova Prime and all functions of the app.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.teslacoilsw.launcher","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"ginlemon.iconpackstudio","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"co.windyapp.android","versions":[]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ithebk.expensemanager","versions":[]}]},{"name":"unlock-pro","description":"Unlocks all professional features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"org.totschnig.myexpenses","versions":["3.4.9"]}]},{"name":"unlock-pro","description":"Unlocks pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":["SignatureVerificationPatch","LicenseValidationPatch"],"compatiblePackages":[{"name":"com.zombodroid.MemeGenerator","versions":["4.6364"]}]},{"name":"unlock-pro","description":"Unlocks all pro features.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.awedea.nyx","versions":[]}]},{"name":"unlock-themes","description":"Unlocks all themes that are inaccessible until a certain level is reached.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.ticktick.task","versions":[]}]},{"name":"unlock-trial","description":"Unlocks the trial version.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"net.dinglisch.android.taskerm","versions":[]}]},{"name":"upgrade-button-remover","description":"Removes the upgrade tab from the pivot bar.","version":"0.0.1","excluded":false,"options":[],"dependencies":[],"compatiblePackages":[{"name":"com.google.android.apps.youtube.music","versions":[]}]},{"name":"vanced-microg-support","description":"Allows YouTube ReVanced to run without root and under a different package name with Vanced MicroG.","version":"0.0.1","excluded":false,"options":[],"dependencies":["microg-resource-patch","hide-cast-button"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]},{"name":"video-ads","description":"Removes ads in the video player.","version":"0.0.1","excluded":false,"options":[],"dependencies":["integrations","settings"],"compatiblePackages":[{"name":"com.google.android.youtube","versions":["17.49.37","18.03.36","18.03.42","18.04.35","18.04.41","18.05.32","18.05.35","18.05.40","18.08.37"]}]}] \ No newline at end of file