From 64868f41be9f567cb54d9214fafbf849d08b64d2 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Wed, 10 May 2023 01:04:06 +0200 Subject: [PATCH] feat(youtube): add `hide-shorts-components` patch --- .../app/revanced/extensions/Extensions.kt | 13 ++- .../ReelConstructorFingerprint.kt | 17 ---- .../ad/general/bytecode/patch/HideAdsPatch.kt | 38 ++------ .../resource/patch/HideAdsResourcePatch.kt | 19 +--- ...bility.kt => HideCommentsCompatibility.kt} | 2 +- .../ShortsCommentsButtonFingerprint.kt | 17 ---- .../comments/bytecode/patch/CommentsPatch.kt | 75 --------------- .../CommentsPatch.kt} | 30 ++---- .../HideShortsComponentsCompatibility.kt | 8 ++ .../CreateShortsButtonsFingerprint.kt | 19 ++++ .../ReelConstructorFingerprint.kt | 19 ++++ .../patch/HideShortsComponentsPatch.kt | 93 +++++++++++++++++++ .../HideShortsComponentsResourcePatch.kt | 89 ++++++++++++++++++ .../litho/filter/patch/LithoFilterPatch.kt | 2 +- 14 files changed, 265 insertions(+), 176 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/fingerprints/ReelConstructorFingerprint.kt rename src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/{CommentsCompatibility.kt => HideCommentsCompatibility.kt} (91%) delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/fingerprints/ShortsCommentsButtonFingerprint.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/patch/CommentsPatch.kt rename src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/{resource/patch/CommentsResourcePatch.kt => patch/CommentsPatch.kt} (70%) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/annotations/HideShortsComponentsCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/CreateShortsButtonsFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/ReelConstructorFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/patch/HideShortsComponentsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/resource/patch/HideShortsComponentsResourcePatch.kt diff --git a/src/main/kotlin/app/revanced/extensions/Extensions.kt b/src/main/kotlin/app/revanced/extensions/Extensions.kt index 7c70f90c..f09f1c5c 100644 --- a/src/main/kotlin/app/revanced/extensions/Extensions.kt +++ b/src/main/kotlin/app/revanced/extensions/Extensions.kt @@ -1,6 +1,7 @@ package app.revanced.extensions import app.revanced.patcher.extensions.MethodFingerprintExtensions.name +import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.util.proxy.mutableTypes.MutableClass @@ -41,4 +42,14 @@ fun MutableClass.transformMethods(transform: MutableMethod.() -> MutableMethod) internal fun Node.doRecursively(action: (Node) -> Unit) { action(this) for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action) -} \ No newline at end of file +} + +fun MutableMethod.injectHideViewCall( + insertIndex: Int, + viewRegister: Int, + classDescriptor: String, + targetMethod: String +) = addInstruction( + insertIndex, + "invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V" +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/fingerprints/ReelConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/fingerprints/ReelConstructorFingerprint.kt deleted file mode 100644 index 06708052..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/fingerprints/ReelConstructorFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.ad.general.bytecode.fingerprints - -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.ad.general.resource.patch.HideAdsResourcePatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object ReelConstructorFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL - ), - customFingerprint = { method, _ -> - method.implementation?.instructions?.any { - it.opcode == Opcode.CONST && (it as WideLiteralInstruction).wideLiteral == HideAdsResourcePatch.reelMultipleItemShelfId - } ?: false - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/patch/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/patch/HideAdsPatch.kt index c681c9f6..4d907a65 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/patch/HideAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/general/bytecode/patch/HideAdsPatch.kt @@ -1,25 +1,20 @@ package app.revanced.patches.youtube.ad.general.bytecode.patch import app.revanced.extensions.findMutableMethodOf -import app.revanced.extensions.toErrorResult +import app.revanced.extensions.injectHideViewCall 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.instruction 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.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.shared.misc.fix.verticalscroll.patch.VerticalScrollPatch import app.revanced.patches.youtube.ad.general.annotation.HideAdsCompatibility -import app.revanced.patches.youtube.ad.general.bytecode.fingerprints.ReelConstructorFingerprint import app.revanced.patches.youtube.ad.general.resource.patch.HideAdsResourcePatch import app.revanced.patches.youtube.misc.fix.backtoexitgesture.patch.FixBackToExitGesturePatch -import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction import org.jf.dexlib2.iface.instruction.formats.Instruction31i import org.jf.dexlib2.iface.instruction.formats.Instruction35c @@ -30,18 +25,8 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction35c @Description("Removes general ads.") @HideAdsCompatibility @Version("0.0.1") -class HideAdsPatch : BytecodePatch( - listOf(ReelConstructorFingerprint) -) { +class HideAdsPatch : BytecodePatch() { override fun execute(context: BytecodeContext): PatchResult { - fun String.buildHideCall(viewRegister: Int) = "invoke-static { v$viewRegister }, " + - "Lapp/revanced/integrations/patches/litho/AdsFilter;" + - "->" + - "$this(Landroid/view/View;)V" - - fun MutableMethod.injectHideCall(insertIndex: Int, viewRegister: Int, method: String) = - this.addInstruction(insertIndex, method.buildHideCall(viewRegister)) - context.classes.forEach { classDef -> classDef.methods.forEach { method -> with(method.implementation) { @@ -64,25 +49,18 @@ class HideAdsPatch : BytecodePatch( context.proxy(classDef) .mutableClass .findMutableMethodOf(method) - .injectHideCall(insertIndex, viewRegister, "hideAdAttributionView") + .injectHideViewCall( + insertIndex, + viewRegister, + "Lapp/revanced/integrations/patches/components/AdsFilter;", + "hideAdAttributionView" + ) } } } } } - ReelConstructorFingerprint.result?.let { - // iput-object v$viewRegister, ... - val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2 - - it.mutableMethod.apply { - val viewRegister = instruction(insertIndex).registerA - - injectHideCall(insertIndex, viewRegister, "hideReelView") - } - } ?: return ReelConstructorFingerprint.toErrorResult() - return PatchResultSuccess() } - } diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/HideAdsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/HideAdsResourcePatch.kt index c8cb32c4..35d6f54d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/HideAdsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/general/resource/patch/HideAdsResourcePatch.kt @@ -23,10 +23,6 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.P @HideAdsCompatibility @Version("0.0.1") class HideAdsResourcePatch : ResourcePatch { - internal companion object { - var adAttributionId: Long = -1 - var reelMultipleItemShelfId: Long = -1 - } override fun execute(context: ResourceContext): PatchResult { PreferenceScreen.LAYOUT.addPreferences( @@ -105,12 +101,6 @@ class HideAdsResourcePatch : ResourcePatch { StringResource("revanced_hide_feed_survey_summary_on", "Feed surveys are hidden"), StringResource("revanced_hide_feed_survey_summary_off", "Feed surveys are shown") ), - SwitchPreference( - "revanced_hide_shorts", - StringResource("revanced_hide_shorts_title", "Hide shorts"), - StringResource("revanced_hide_shorts_summary_on", "Shorts are hidden"), - StringResource("revanced_hide_shorts_summary_off", "Shorts are shown") - ), SwitchPreference( "revanced_hide_community_guidelines", StringResource("revanced_hide_community_guidelines_title", "Hide community guidelines"), @@ -263,11 +253,12 @@ class HideAdsResourcePatch : ResourcePatch { ) ) - fun String.getId() = ResourceMappingPatch.resourceMappings.single { it.name == this }.id - - adAttributionId = "ad_attribution".getId() - reelMultipleItemShelfId = "reel_multiple_items_shelf".getId() + adAttributionId = ResourceMappingPatch.resourceMappings.single { it.name == "ad_attribution" }.id return PatchResultSuccess() } + + internal companion object { + var adAttributionId: Long = -1 + } } 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/HideCommentsCompatibility.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/CommentsCompatibility.kt rename to src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/annotations/HideCommentsCompatibility.kt index c852dc42..c79e5422 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/HideCommentsCompatibility.kt @@ -21,4 +21,4 @@ import app.revanced.patcher.annotation.Package )] ) @Target(AnnotationTarget.CLASS) -internal annotation class CommentsCompatibility +internal annotation class HideCommentsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/fingerprints/ShortsCommentsButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/fingerprints/ShortsCommentsButtonFingerprint.kt deleted file mode 100644 index b8a22d23..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/fingerprints/ShortsCommentsButtonFingerprint.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.comments.bytecode.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patches.youtube.layout.hide.comments.resource.patch.CommentsResourcePatch -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.WideLiteralInstruction - -object ShortsCommentsButtonFingerprint : MethodFingerprint( - "V", AccessFlags.PRIVATE or AccessFlags.FINAL, listOf("Z", "Z", "L"), - customFingerprint = { methodDef, _ -> - methodDef.implementation?.instructions?.any { - it.opcode.ordinal == Opcode.CONST.ordinal && (it as WideLiteralInstruction).wideLiteral == CommentsResourcePatch.shortsCommentsButtonId - } == true - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/patch/CommentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/patch/CommentsPatch.kt deleted file mode 100644 index e86de09f..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/bytecode/patch/CommentsPatch.kt +++ /dev/null @@ -1,75 +0,0 @@ -package app.revanced.patches.youtube.layout.hide.comments.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 -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 -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependsOn -import app.revanced.patcher.patch.annotations.Patch -import app.revanced.patches.youtube.layout.hide.comments.annotations.CommentsCompatibility -import app.revanced.patches.youtube.layout.hide.comments.bytecode.fingerprints.ShortsCommentsButtonFingerprint -import app.revanced.patches.youtube.layout.hide.comments.resource.patch.CommentsResourcePatch -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch -@DependsOn([IntegrationsPatch::class, CommentsResourcePatch::class]) -@Name("comments") -@Description("Hides components related to comments.") -@CommentsCompatibility -@Version("0.0.1") -class CommentsPatch : BytecodePatch( - listOf( - ShortsCommentsButtonFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - val checkCastAnchorFingerprint = object : MethodFingerprint( - opcodes = listOf( - Opcode.CONST, - Opcode.CONST_HIGH16, - Opcode.IF_EQZ, - Opcode.CONST, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - ) - ) {} - - ShortsCommentsButtonFingerprint.result?.let { - it.mutableMethod.apply { - val checkCastAnchorIndex = checkCastAnchorFingerprint.also { result -> - if (!result.resolve(context, this, it.classDef)) - throw checkCastAnchorFingerprint.toErrorResult() - }.result!!.scanResult.patternScanResult!!.endIndex - - val shortsCommentsButtonRegister = instruction(checkCastAnchorIndex).registerA - val insertIndex = checkCastAnchorIndex + 1 - - addInstructions( - insertIndex, - """ - invoke-static { v$shortsCommentsButtonRegister }, $FILTER_METHOD_DESCRIPTOR - """ - ) - } - } ?: return ShortsCommentsButtonFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - private companion object { - private const val FILTER_METHOD_DESCRIPTOR = - "Lapp/revanced/integrations/patches/HideShortsCommentsButtonPatch;" + - "->hideShortsCommentsButton(Landroid/view/View;)V" - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/resource/patch/CommentsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/patch/CommentsPatch.kt similarity index 70% rename from src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/resource/patch/CommentsResourcePatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/patch/CommentsPatch.kt index 695aa69c..5ebb44d1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/resource/patch/CommentsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/patch/CommentsPatch.kt @@ -1,5 +1,6 @@ -package app.revanced.patches.youtube.layout.hide.comments.resource.patch +package app.revanced.patches.youtube.layout.hide.comments.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 @@ -7,22 +8,21 @@ import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.SwitchPreference -import app.revanced.patches.youtube.layout.hide.comments.annotations.CommentsCompatibility +import app.revanced.patches.youtube.layout.hide.comments.annotations.HideCommentsCompatibility import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch -@Name("comments-resource-patch") -@CommentsCompatibility +@Patch +@Name("comments") +@Description("Hides components related to comments.") +@HideCommentsCompatibility @DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @Version("0.0.1") -class CommentsResourcePatch : ResourcePatch { - companion object { - internal var shortsCommentsButtonId: Long = -1 - } - +class CommentsPatch : ResourcePatch { override fun execute(context: ResourceContext): PatchResult { SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( PreferenceScreen( @@ -40,22 +40,12 @@ class CommentsResourcePatch : ResourcePatch { StringResource("revanced_hide_preview_comment_title", "Hide preview comment"), StringResource("revanced_hide_preview_comment_on", "Preview comment is hidden"), StringResource("revanced_hide_preview_comment_off", "Preview comment is shown") - ), - SwitchPreference( - "revanced_hide_shorts_comments_button", - StringResource("revanced_hide_shorts_comments_button_title", "Hide shorts comments button"), - StringResource("revanced_hide_shorts_comments_button_on", "Shorts comments button is hidden"), - StringResource("revanced_hide_shorts_comments_button_off", "Shorts comments button is shown") - ), + ) ), StringResource("revanced_comments_preference_screen_summary", "Manage the visibility of comments section components") ) ) - shortsCommentsButtonId = ResourceMappingPatch.resourceMappings.single { - it.type == "drawable" && it.name == "ic_right_comment_32c" - }.id - return PatchResultSuccess() } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/annotations/HideShortsComponentsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/annotations/HideShortsComponentsCompatibility.kt new file mode 100644 index 00000000..a00aca95 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/annotations/HideShortsComponentsCompatibility.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.youtube.layout.hide.shorts.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37"))]) +@Target(AnnotationTarget.CLASS) +internal annotation class HideShortsComponentsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/CreateShortsButtonsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/CreateShortsButtonsFingerprint.kt new file mode 100644 index 00000000..2f99a2f0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/CreateShortsButtonsFingerprint.kt @@ -0,0 +1,19 @@ +package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.WideLiteralInstruction + +object CreateShortsButtonsFingerprint : MethodFingerprint( + parameters = listOf("Z", "Z", "L"), + customFingerprint = { methodDef, _ -> + methodDef.implementation?.instructions?.any { + if (it.opcode != Opcode.CONST) return@any false + + val literal = (it as WideLiteralInstruction).wideLiteral + + literal == HideShortsComponentsResourcePatch.reelPlayerRightLargeIconSize + } ?: false + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/ReelConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/ReelConstructorFingerprint.kt new file mode 100644 index 00000000..2d6836b2 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/fingerprints/ReelConstructorFingerprint.kt @@ -0,0 +1,19 @@ +package app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.WideLiteralInstruction + +object ReelConstructorFingerprint : MethodFingerprint( + opcodes = listOf(Opcode.INVOKE_VIRTUAL), + customFingerprint = { method, _ -> + method.implementation?.instructions?.any { + if (it.opcode != Opcode.CONST) return@any false + + val literal = (it as WideLiteralInstruction).wideLiteral + + literal == HideShortsComponentsResourcePatch.reelMultipleItemShelfId + } ?: false + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/patch/HideShortsComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/patch/HideShortsComponentsPatch.kt new file mode 100644 index 00000000..4d8ac578 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/bytecode/patch/HideShortsComponentsPatch.kt @@ -0,0 +1,93 @@ +package app.revanced.patches.youtube.layout.hide.shorts.bytecode.patch + +import app.revanced.extensions.injectHideViewCall +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.instruction +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.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch +import app.revanced.patches.youtube.layout.hide.shorts.annotations.HideShortsComponentsCompatibility +import app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints.CreateShortsButtonsFingerprint +import app.revanced.patches.youtube.layout.hide.shorts.bytecode.fingerprints.ReelConstructorFingerprint +import app.revanced.patches.youtube.layout.hide.shorts.resource.patch.HideShortsComponentsResourcePatch +import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch +import app.revanced.patches.youtube.misc.litho.filter.patch.LithoFilterPatch +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction +import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction +import org.jf.dexlib2.iface.instruction.WideLiteralInstruction + +@Patch +@DependsOn( + [ + IntegrationsPatch::class, + LithoFilterPatch::class, + HideShortsComponentsResourcePatch::class, + ResourceMappingPatch::class + ] +) +@Name("hide-shorts-components") +@Description("Hides components from YouTube Shorts.") +@HideShortsComponentsCompatibility +@Version("0.0.1") +class HideShortsComponentsPatch : BytecodePatch(listOf(CreateShortsButtonsFingerprint, ReelConstructorFingerprint)) { + override fun execute(context: BytecodeContext): PatchResult { + // Hide the Shorts shelf. + ReelConstructorFingerprint.result?.let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2 + val viewRegister = instruction(insertIndex).registerA + + injectHideViewCall( + insertIndex, + viewRegister, + CLASS_DESCRIPTOR, + "hideShortsShelf" + ) + } + } ?: return ReelConstructorFingerprint.toErrorResult() + + // Some Shorts buttons are views, hide them by setting their visibility to GONE. + CreateShortsButtonsFingerprint.result?.let { + ShortsButtons.values().forEach { button -> button.injectHideCall(it.mutableMethod) } + } ?: return CreateShortsButtonsFingerprint.toErrorResult() + return PatchResultSuccess() + } + + private companion object { + private const val CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/components/ShortsFilter;" + + private enum class ShortsButtons(private val resourceName: String, private val methodName: String) { + COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"), + REMIX("reel_dyn_remix", "hideShortsRemixButton"), + SHARE("reel_dyn_share", "hideShortsShareButton"); + + fun injectHideCall(method: MutableMethod) { + val resourceId = ResourceMappingPatch.resourceMappings.single { + it.type == "id" && it.name == resourceName + }.id + + // Get the index of the reference to the view's resource ID. + val referencedIndex = method.implementation!!.instructions.indexOfFirst { + if (it.opcode != Opcode.CONST) return@indexOfFirst false + + val literal = (it as WideLiteralInstruction).wideLiteral + + return@indexOfFirst resourceId == literal + } + + val setIdIndex = referencedIndex + 1 + val viewRegister = method.instruction(setIdIndex).registerC + method.injectHideViewCall(setIdIndex, viewRegister, CLASS_DESCRIPTOR, methodName) + } + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/resource/patch/HideShortsComponentsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/resource/patch/HideShortsComponentsResourcePatch.kt new file mode 100644 index 00000000..29e3d149 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/resource/patch/HideShortsComponentsResourcePatch.kt @@ -0,0 +1,89 @@ +package app.revanced.patches.youtube.layout.hide.shorts.resource.patch + +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch +import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference +import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch + +@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) +@Version("0.0.1") +class HideShortsComponentsResourcePatch : ResourcePatch { + override fun execute(context: ResourceContext): PatchResult { + SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( + PreferenceScreen( + "revanced_shorts", + StringResource("revanced_shorts_title", "Shorts components"), + listOf( + SwitchPreference( + "revanced_hide_shorts", + StringResource("revanced_hide_shorts_enabled_title", "Hide shorts"), + StringResource("revanced_hide_shorts_on", "Shorts are hidden"), + StringResource("revanced_hide_shorts_off", "Shorts are shown") + ), + SwitchPreference( + "revanced_hide_shorts_join_button", + StringResource("revanced_hide_shorts_join_button_title", "Hide join button"), + StringResource("revanced_hide_shorts_join_button_on", "Join button is hidden"), + StringResource("revanced_hide_shorts_join_button_off", "Join button is shown") + ), + SwitchPreference( + "revanced_hide_shorts_subscribe_button", + StringResource("revanced_hide_shorts_subscribe_button_title", "Hide subscribe button"), + StringResource("revanced_hide_shorts_subscribe_button_on", "Subscribe button is hidden"), + StringResource("revanced_hide_shorts_subscribe_button_off", "Subscribe button is shown") + ), + SwitchPreference( + "revanced_hide_shorts_thanks_button", + StringResource("revanced_hide_shorts_thanks_button_title", "Hide thanks button"), + StringResource("revanced_hide_shorts_thanks_button_on", "Thanks button is hidden"), + StringResource("revanced_hide_shorts_thanks_button_off", "Thanks button is shown") + ), + SwitchPreference( + "revanced_hide_shorts_comments_button", + StringResource("revanced_hide_shorts_comments_button_title", "Hide comments button"), + StringResource("revanced_hide_shorts_comments_button_on", "Comments button is hidden"), + StringResource("revanced_hide_shorts_comments_button_off", "Comments button is shown") + ), + SwitchPreference( + "revanced_hide_shorts_remix_button", + StringResource("revanced_hide_shorts_remix_button_title", "Hide remix button"), + StringResource("revanced_hide_shorts_remix_button_on", "Remix button is hidden"), + StringResource("revanced_hide_shorts_remix_button_off", "Remix button is shown") + ), + SwitchPreference( + "revanced_hide_shorts_share_button", + StringResource("revanced_hide_shorts_share_button_title", "Hide share button"), + StringResource("revanced_hide_shorts_share_button_on", "Share button is hidden"), + StringResource("revanced_hide_shorts_share_button_off", "Share button is shown") + ), + SwitchPreference( + "revanced_hide_shorts_navigation_bar", + StringResource("revanced_hide_shorts_navigation_bar_title", "Hide navigation bar"), + StringResource("revanced_hide_shorts_navigation_bar_on", "Navigation bar is hidden"), + StringResource("revanced_hide_shorts_navigation_bar_off", "Navigation bar is shown") + ), + ), + StringResource("revanced_shorts_summary", "Manage the visibility of Shorts components") + ) + ) + + fun String.getId() = ResourceMappingPatch.resourceMappings.single { it.name == this }.id + + reelMultipleItemShelfId = "reel_multiple_items_shelf".getId() + reelPlayerRightLargeIconSize = "reel_player_right_large_icon_size".getId() + + return PatchResultSuccess() + } + + companion object { + var reelMultipleItemShelfId: Long = -1 + var reelPlayerRightLargeIconSize = -1L + } +} \ 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 14d91178..84c53504 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 @@ -119,7 +119,7 @@ class LithoFilterPatch : BytecodePatch( get() = (this as ReferenceInstruction).reference.toString() const val FILTER_METHOD_DESCRIPTOR = - "Lapp/revanced/integrations/patches/litho/LithoFilterPatch;" + + "Lapp/revanced/integrations/patches/components/LithoFilterPatch;" + "->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/nio/ByteBuffer;)Z" } } \ No newline at end of file