feat(YouTube/Hide shorts components): match original ReVanced code

This commit is contained in:
inotia00
2024-04-25 02:45:00 +09:00
parent 16dad655ba
commit dafaa60087
8 changed files with 231 additions and 226 deletions

View File

@ -5,15 +5,18 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsButtonFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsInfoPanelFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPaidPromotionFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPivotFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPivotLegacyFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletParentFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR
@ -23,9 +26,6 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelD
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelDynShare
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelForcedMuteButton
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPivotButton
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerBadge
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerBadge2
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerInfoPanel
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelRightDislikeIcon
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelRightLikeIcon
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.RightComment
@ -37,6 +37,9 @@ import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
@Suppress("unused")
object ShortsComponentPatch : BaseBytecodePatch(
@ -48,16 +51,15 @@ object ShortsComponentPatch : BaseBytecodePatch(
SettingsPatch::class,
SharedResourceIdPatch::class,
ShortsNavigationBarPatch::class,
ShortsSubscriptionsButtonPatch::class,
ShortsToolBarPatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(
ShortsButtonFingerprint,
ShortsInfoPanelFingerprint,
ShortsPaidPromotionFingerprint,
ShortsPivotFingerprint,
ShortsPivotLegacyFingerprint
ShortsPivotLegacyFingerprint,
ShortsSubscriptionsTabletParentFingerprint
)
) {
private const val BUTTON_FILTER_CLASS_DESCRIPTOR =
@ -67,14 +69,14 @@ object ShortsComponentPatch : BaseBytecodePatch(
override fun execute(context: BytecodeContext) {
/**
* Comment button
*/
// region patch for hide comments button (non-litho)
ShortsButtonFingerprint.hideButton(RightComment, "hideShortsCommentsButton", false)
/**
* Dislike button
*/
// endregion
// region patch for hide dislike button (non-litho)
ShortsButtonFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(ReelRightDislikeIcon)
@ -93,14 +95,10 @@ object ShortsComponentPatch : BaseBytecodePatch(
}
}
/**
* Info panel
*/
ShortsInfoPanelFingerprint.hideButtons(ReelPlayerInfoPanel, "hideShortsInfoPanel(Landroid/view/ViewGroup;)Landroid/view/ViewGroup;")
// endregion
// region patch for hide like button (non-litho)
/**
* Like button
*/
ShortsButtonFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = getWideLiteralInstructionIndex(ReelRightLikeIcon)
@ -118,15 +116,10 @@ object ShortsComponentPatch : BaseBytecodePatch(
}
}
/**
* Paid promotion
*/
ShortsPaidPromotionFingerprint.hideButtons(ReelPlayerBadge, "hideShortsPaidPromotionBanner(Landroid/view/ViewStub;)Landroid/view/ViewStub;")
ShortsPaidPromotionFingerprint.hideButtons(ReelPlayerBadge2, "hideShortsPaidPromotionBanner(Landroid/view/ViewStub;)Landroid/view/ViewStub;")
// endregion
// region patch for hide sound button
/**
* Sound button
*/
ShortsPivotLegacyFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(ReelForcedMuteButton)
@ -152,16 +145,97 @@ object ShortsComponentPatch : BaseBytecodePatch(
}
}
/**
* Remix button
*/
// endregion
// region patch for hide remix button (non-litho)
ShortsButtonFingerprint.hideButton(ReelDynRemix, "hideShortsRemixButton", true)
/**
* Share button
*/
// endregion
// region patch for hide share button (non-litho)
ShortsButtonFingerprint.hideButton(ReelDynShare, "hideShortsShareButton", true)
// endregion
// region patch for hide paid promotion label (non-litho)
ShortsPaidPromotionFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
when (returnType) {
"Landroid/widget/TextView;" -> {
val insertIndex = implementation!!.instructions.size - 1
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex + 1, """
invoke-static {v$insertRegister}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPaidPromotionLabel(Landroid/widget/TextView;)V
return-object v$insertRegister
"""
)
removeInstruction(insertIndex)
}
"V" -> {
addInstructionsWithLabels(
0, """
invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->hideShortsPaidPromotionLabel()Z
move-result v0
if-eqz v0, :show
return-void
""", ExternalLabel("show", getInstruction(0))
)
}
else -> {
throw PatchException("Unknown returnType: $returnType")
}
}
}
}
// endregion
// region patch for hide subscribe button (non-litho)
// This method is deprecated since YouTube v18.31.xx.
if (!SettingsPatch.upward1831) {
ShortsSubscriptionsTabletParentFingerprint.resultOrThrow().let { parentResult ->
lateinit var subscriptionFieldReference: FieldReference
parentResult.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.ReelPlayerFooter) - 1
subscriptionFieldReference =
(getInstruction<ReferenceInstruction>(targetIndex)).reference as FieldReference
}
ShortsSubscriptionsTabletFingerprint.also {
it.resolve(
context,
parentResult.classDef
)
}.resultOrThrow().mutableMethod.apply {
implementation!!.instructions.filter { instruction ->
val fieldReference =
(instruction as? ReferenceInstruction)?.reference as? FieldReference
instruction.opcode == Opcode.IGET
&& fieldReference == subscriptionFieldReference
}.forEach { instruction ->
val insertIndex = implementation!!.instructions.indexOf(instruction) + 1
val register = (instruction as TwoRegisterInstruction).registerA
addInstructions(
insertIndex, """
invoke-static {v$register}, $SHORTS_CLASS_DESCRIPTOR->hideShortsSubscribeButton(I)I
move-result v$register
"""
)
}
}
}
}
// endregion
LithoFilterPatch.addFilter(BUTTON_FILTER_CLASS_DESCRIPTOR)
LithoFilterPatch.addFilter(SHELF_FILTER_CLASS_DESCRIPTOR)

View File

@ -1,83 +0,0 @@
package app.revanced.patches.youtube.shorts.components
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletParentFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerFooter
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerPausedStateButton
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
@Patch(dependencies = [SettingsPatch::class])
object ShortsSubscriptionsButtonPatch : BytecodePatch(
setOf(
ShortsSubscriptionsFingerprint,
ShortsSubscriptionsTabletParentFingerprint
)
) {
private lateinit var subscriptionFieldReference: FieldReference
override fun execute(context: BytecodeContext) {
ShortsSubscriptionsFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = getWideLiteralInstructionIndex(ReelPlayerPausedStateButton) + 2
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstruction(
insertIndex + 1,
"invoke-static {v$insertRegister}, $SHORTS_CLASS_DESCRIPTOR->hideShortsSubscriptionsButton(Landroid/view/View;)V"
)
}
}
/**
* Deprecated in YouTube v18.31.xx+
*/
if (!SettingsPatch.upward1831) {
ShortsSubscriptionsTabletParentFingerprint.resultOrThrow().let { parentResult ->
parentResult.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(ReelPlayerFooter) - 1
subscriptionFieldReference =
(getInstruction<ReferenceInstruction>(targetIndex)).reference as FieldReference
}
ShortsSubscriptionsTabletFingerprint.also {
it.resolve(
context,
parentResult.classDef
)
}.resultOrThrow().mutableMethod.apply {
implementation!!.instructions.filter { instruction ->
val fieldReference =
(instruction as? ReferenceInstruction)?.reference as? FieldReference
instruction.opcode == Opcode.IGET
&& fieldReference == subscriptionFieldReference
}.forEach { instruction ->
val insertIndex = implementation!!.instructions.indexOf(instruction) + 1
val register = (instruction as TwoRegisterInstruction).registerA
addInstructions(
insertIndex, """
invoke-static {v$register}, $SHORTS_CLASS_DESCRIPTOR->hideShortsSubscriptionsButton(I)I
move-result v$register
"""
)
}
}
}
}
}
}

View File

@ -1,12 +0,0 @@
package app.revanced.patches.youtube.shorts.components.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerInfoPanel
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object ShortsInfoPanelFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
literalSupplier = { ReelPlayerInfoPanel }
)

View File

@ -1,17 +1,13 @@
package app.revanced.patches.youtube.shorts.components.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerBadge
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerBadge2
import app.revanced.util.containsWideLiteralInstructionIndex
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BadgeLabel
import app.revanced.util.fingerprint.LiteralValueFingerprint
internal object ShortsPaidPromotionFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(ReelPlayerBadge)
&& methodDef.containsWideLiteralInstructionIndex(ReelPlayerBadge2)
},
/**
* The method by which patches are applied is different between the minimum supported version and the maximum supported version.
* There are two classes where R.id.badge_label[BadgeLabel] is used,
* but due to the structure of ReVanced Patcher, the patch is applied to the method found first.
*/
internal object ShortsPaidPromotionFingerprint : LiteralValueFingerprint(
literalSupplier = { BadgeLabel }
)

View File

@ -1,13 +0,0 @@
package app.revanced.patches.youtube.shorts.components.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelPlayerPausedStateButton
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal object ShortsSubscriptionsFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),
literalSupplier = { ReelPlayerPausedStateButton }
)

View File

@ -25,6 +25,7 @@ object SharedResourceIdPatch : ResourcePatch() {
var AutoNavPreviewStub = -1L
var AutoNavToggle = -1L
var BackgroundCategory = -1L
var BadgeLabel = -1L
var Bar = -1L
var BarContainerHeight = -1L
var BottomSheetFooterText = -1L
@ -66,11 +67,7 @@ object SharedResourceIdPatch : ResourcePatch() {
var ReelDynShare = -1L
var ReelForcedMuteButton = -1L
var ReelPivotButton = -1L
var ReelPlayerBadge = -1L
var ReelPlayerBadge2 = -1L
var ReelPlayerFooter = -1L
var ReelPlayerInfoPanel = -1L
var ReelPlayerPausedStateButton = -1L
var ReelRightDislikeIcon = -1L
var ReelRightLikeIcon = -1L
var ReelTimeBarPlayedColor = -1L
@ -99,6 +96,7 @@ object SharedResourceIdPatch : ResourcePatch() {
AutoNavPreviewStub = getId(ID, "autonav_preview_stub")
AutoNavToggle = getId(ID, "autonav_toggle")
BackgroundCategory = getId(STRING, "pref_background_and_offline_category")
BadgeLabel = getId(ID, "badge_label")
Bar = getId(LAYOUT, "bar")
BarContainerHeight = getId(DIMEN, "bar_container_height")
BottomSheetFooterText = getId(ID, "bottom_sheet_footer_text")
@ -142,11 +140,7 @@ object SharedResourceIdPatch : ResourcePatch() {
ReelDynShare = getId(ID, "reel_dyn_share")
ReelForcedMuteButton = getId(ID, "reel_player_forced_mute_button")
ReelPivotButton = getId(ID, "reel_pivot_button")
ReelPlayerBadge = getId(ID, "reel_player_badge")
ReelPlayerBadge2 = getId(ID, "reel_player_badge2")
ReelPlayerFooter = getId(LAYOUT, "reel_player_dyn_footer_vert_stories3")
ReelPlayerInfoPanel = getId(ID, "reel_player_info_panel")
ReelPlayerPausedStateButton = getId(ID, "reel_player_paused_state_buttons")
ReelRightDislikeIcon = getId(DRAWABLE, "reel_right_dislike_icon")
ReelRightLikeIcon = getId(DRAWABLE, "reel_right_like_icon")
ReelTimeBarPlayedColor = getId(COLOR, "reel_time_bar_played_color")