mirror of
https://github.com/revanced/revanced-patches
synced 2024-09-02 04:25:11 +02:00
feat(youtube): add hide-shorts-components
patch
This commit is contained in:
parent
6347146900
commit
64868f41be
@ -1,6 +1,7 @@
|
|||||||
package app.revanced.extensions
|
package app.revanced.extensions
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
|
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.fingerprint.method.impl.MethodFingerprint
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
|
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) {
|
internal fun Node.doRecursively(action: (Node) -> Unit) {
|
||||||
action(this)
|
action(this)
|
||||||
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)
|
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun MutableMethod.injectHideViewCall(
|
||||||
|
insertIndex: Int,
|
||||||
|
viewRegister: Int,
|
||||||
|
classDescriptor: String,
|
||||||
|
targetMethod: String
|
||||||
|
) = addInstruction(
|
||||||
|
insertIndex,
|
||||||
|
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V"
|
||||||
|
)
|
@ -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
|
|
||||||
}
|
|
||||||
)
|
|
@ -1,25 +1,20 @@
|
|||||||
package app.revanced.patches.youtube.ad.general.bytecode.patch
|
package app.revanced.patches.youtube.ad.general.bytecode.patch
|
||||||
|
|
||||||
import app.revanced.extensions.findMutableMethodOf
|
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.Description
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
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.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
import app.revanced.patcher.patch.annotations.DependsOn
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
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.shared.misc.fix.verticalscroll.patch.VerticalScrollPatch
|
||||||
import app.revanced.patches.youtube.ad.general.annotation.HideAdsCompatibility
|
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.ad.general.resource.patch.HideAdsResourcePatch
|
||||||
import app.revanced.patches.youtube.misc.fix.backtoexitgesture.patch.FixBackToExitGesturePatch
|
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.Instruction31i
|
||||||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
|
|
||||||
@ -30,18 +25,8 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
|||||||
@Description("Removes general ads.")
|
@Description("Removes general ads.")
|
||||||
@HideAdsCompatibility
|
@HideAdsCompatibility
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class HideAdsPatch : BytecodePatch(
|
class HideAdsPatch : BytecodePatch() {
|
||||||
listOf(ReelConstructorFingerprint)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
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 ->
|
context.classes.forEach { classDef ->
|
||||||
classDef.methods.forEach { method ->
|
classDef.methods.forEach { method ->
|
||||||
with(method.implementation) {
|
with(method.implementation) {
|
||||||
@ -64,25 +49,18 @@ class HideAdsPatch : BytecodePatch(
|
|||||||
context.proxy(classDef)
|
context.proxy(classDef)
|
||||||
.mutableClass
|
.mutableClass
|
||||||
.findMutableMethodOf(method)
|
.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<TwoRegisterInstruction>(insertIndex).registerA
|
|
||||||
|
|
||||||
injectHideCall(insertIndex, viewRegister, "hideReelView")
|
|
||||||
}
|
|
||||||
} ?: return ReelConstructorFingerprint.toErrorResult()
|
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,6 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch.P
|
|||||||
@HideAdsCompatibility
|
@HideAdsCompatibility
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class HideAdsResourcePatch : ResourcePatch {
|
class HideAdsResourcePatch : ResourcePatch {
|
||||||
internal companion object {
|
|
||||||
var adAttributionId: Long = -1
|
|
||||||
var reelMultipleItemShelfId: Long = -1
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext): PatchResult {
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
PreferenceScreen.LAYOUT.addPreferences(
|
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_on", "Feed surveys are hidden"),
|
||||||
StringResource("revanced_hide_feed_survey_summary_off", "Feed surveys are shown")
|
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(
|
SwitchPreference(
|
||||||
"revanced_hide_community_guidelines",
|
"revanced_hide_community_guidelines",
|
||||||
StringResource("revanced_hide_community_guidelines_title", "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 = ResourceMappingPatch.resourceMappings.single { it.name == "ad_attribution" }.id
|
||||||
|
|
||||||
adAttributionId = "ad_attribution".getId()
|
|
||||||
reelMultipleItemShelfId = "reel_multiple_items_shelf".getId()
|
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal companion object {
|
||||||
|
var adAttributionId: Long = -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,4 +21,4 @@ import app.revanced.patcher.annotation.Package
|
|||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
internal annotation class CommentsCompatibility
|
internal annotation class HideCommentsCompatibility
|
@ -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
|
|
||||||
}
|
|
||||||
)
|
|
@ -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<OneRegisterInstruction>(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"
|
|
||||||
}
|
|
||||||
}
|
|
@ -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.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.ResourceContext
|
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.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.patcher.patch.annotations.DependsOn
|
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.mapping.misc.patch.ResourceMappingPatch
|
||||||
import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
|
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.StringResource
|
||||||
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
|
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
|
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||||
|
|
||||||
@Name("comments-resource-patch")
|
@Patch
|
||||||
@CommentsCompatibility
|
@Name("comments")
|
||||||
|
@Description("Hides components related to comments.")
|
||||||
|
@HideCommentsCompatibility
|
||||||
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
|
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class])
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class CommentsResourcePatch : ResourcePatch {
|
class CommentsPatch : ResourcePatch {
|
||||||
companion object {
|
|
||||||
internal var shortsCommentsButtonId: Long = -1
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun execute(context: ResourceContext): PatchResult {
|
override fun execute(context: ResourceContext): PatchResult {
|
||||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||||
PreferenceScreen(
|
PreferenceScreen(
|
||||||
@ -40,22 +40,12 @@ class CommentsResourcePatch : ResourcePatch {
|
|||||||
StringResource("revanced_hide_preview_comment_title", "Hide preview comment"),
|
StringResource("revanced_hide_preview_comment_title", "Hide preview comment"),
|
||||||
StringResource("revanced_hide_preview_comment_on", "Preview comment is hidden"),
|
StringResource("revanced_hide_preview_comment_on", "Preview comment is hidden"),
|
||||||
StringResource("revanced_hide_preview_comment_off", "Preview comment is shown")
|
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")
|
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()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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
|
@ -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
|
||||||
|
}
|
||||||
|
)
|
@ -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
|
||||||
|
}
|
||||||
|
)
|
@ -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<TwoRegisterInstruction>(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<FiveRegisterInstruction>(setIdIndex).registerC
|
||||||
|
method.injectHideViewCall(setIdIndex, viewRegister, CLASS_DESCRIPTOR, methodName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -119,7 +119,7 @@ class LithoFilterPatch : BytecodePatch(
|
|||||||
get() = (this as ReferenceInstruction).reference.toString()
|
get() = (this as ReferenceInstruction).reference.toString()
|
||||||
|
|
||||||
const val FILTER_METHOD_DESCRIPTOR =
|
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"
|
"->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/nio/ByteBuffer;)Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user