mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-13 13:47:42 +02:00
chore(YouTube Music): replace with a fingerprint that supports a wider range of versions
This commit is contained in:
@ -13,6 +13,8 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
|||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
import app.revanced.patcher.util.smali.ExternalLabel
|
||||||
import app.revanced.patches.music.player.components.fingerprints.AudioVideoSwitchToggleFingerprint
|
import app.revanced.patches.music.player.components.fingerprints.AudioVideoSwitchToggleFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.EngagementPanelHeightFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.EngagementPanelHeightParentFingerprint
|
||||||
import app.revanced.patches.music.player.components.fingerprints.HandleSearchRenderedFingerprint
|
import app.revanced.patches.music.player.components.fingerprints.HandleSearchRenderedFingerprint
|
||||||
import app.revanced.patches.music.player.components.fingerprints.HandleSignInEventFingerprint
|
import app.revanced.patches.music.player.components.fingerprints.HandleSignInEventFingerprint
|
||||||
import app.revanced.patches.music.player.components.fingerprints.InteractionLoggingEnumFingerprint
|
import app.revanced.patches.music.player.components.fingerprints.InteractionLoggingEnumFingerprint
|
||||||
@ -59,6 +61,7 @@ import app.revanced.patches.music.utils.settings.SettingsPatch
|
|||||||
import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch
|
import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch
|
||||||
import app.revanced.patches.shared.litho.LithoFilterPatch
|
import app.revanced.patches.shared.litho.LithoFilterPatch
|
||||||
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||||
|
import app.revanced.util.alsoResolve
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.getWalkerMethod
|
import app.revanced.util.getWalkerMethod
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
@ -102,6 +105,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
compatiblePackages = COMPATIBLE_PACKAGE,
|
compatiblePackages = COMPATIBLE_PACKAGE,
|
||||||
fingerprints = setOf(
|
fingerprints = setOf(
|
||||||
AudioVideoSwitchToggleFingerprint,
|
AudioVideoSwitchToggleFingerprint,
|
||||||
|
EngagementPanelHeightParentFingerprint,
|
||||||
HandleSearchRenderedFingerprint,
|
HandleSearchRenderedFingerprint,
|
||||||
InteractionLoggingEnumFingerprint,
|
InteractionLoggingEnumFingerprint,
|
||||||
MinimizedPlayerFingerprint,
|
MinimizedPlayerFingerprint,
|
||||||
@ -530,15 +534,12 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
it.mutableClass.methods.find { method ->
|
it.mutableClass.methods.find { method ->
|
||||||
method.parameters == listOf("Landroid/view/View;", "I")
|
method.parameters == listOf("Landroid/view/View;", "I")
|
||||||
}?.apply {
|
}?.apply {
|
||||||
val bottomSheetBehaviorIndex =
|
val bottomSheetBehaviorIndex = indexOfFirstInstructionOrThrow {
|
||||||
implementation!!.instructions.indexOfFirst { instruction ->
|
val reference = getReference<MethodReference>()
|
||||||
instruction.opcode == Opcode.INVOKE_VIRTUAL
|
opcode == Opcode.INVOKE_VIRTUAL
|
||||||
&& instruction.getReference<MethodReference>()?.definingClass == "Lcom/google/android/material/bottomsheet/BottomSheetBehavior;"
|
&& reference?.definingClass == "Lcom/google/android/material/bottomsheet/BottomSheetBehavior;"
|
||||||
&& instruction.getReference<MethodReference>()?.parameterTypes?.first() == "Z"
|
&& reference.parameterTypes.first() == "Z"
|
||||||
}
|
}
|
||||||
if (bottomSheetBehaviorIndex < 0)
|
|
||||||
throw PatchException("Could not find bottomSheetBehaviorIndex")
|
|
||||||
|
|
||||||
val freeRegister =
|
val freeRegister =
|
||||||
getInstruction<FiveRegisterInstruction>(bottomSheetBehaviorIndex).registerD
|
getInstruction<FiveRegisterInstruction>(bottomSheetBehaviorIndex).registerD
|
||||||
|
|
||||||
@ -744,18 +745,20 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
rememberShuffleStateObjectClass = definingClass
|
rememberShuffleStateObjectClass = definingClass
|
||||||
|
|
||||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(45468)
|
|
||||||
val iGetObjectIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.IGET_OBJECT)
|
|
||||||
val checkCastIndex =
|
|
||||||
indexOfFirstInstructionOrThrow(iGetObjectIndex, Opcode.CHECK_CAST)
|
|
||||||
|
|
||||||
val ordinalIndex = indexOfOrdinalInstruction(this)
|
|
||||||
val imageViewIndex = indexOfImageViewInstruction(this)
|
val imageViewIndex = indexOfImageViewInstruction(this)
|
||||||
|
val ordinalIndex = indexOfOrdinalInstruction(this)
|
||||||
|
|
||||||
|
val invokeInterfaceIndex =
|
||||||
|
indexOfFirstInstructionReversedOrThrow(ordinalIndex, Opcode.INVOKE_INTERFACE)
|
||||||
|
val iGetObjectIndex =
|
||||||
|
indexOfFirstInstructionReversedOrThrow(invokeInterfaceIndex, Opcode.IGET_OBJECT)
|
||||||
|
val checkCastIndex =
|
||||||
|
indexOfFirstInstructionOrThrow(invokeInterfaceIndex, Opcode.CHECK_CAST)
|
||||||
|
|
||||||
val iGetObjectReference =
|
val iGetObjectReference =
|
||||||
getInstruction<ReferenceInstruction>(iGetObjectIndex).reference
|
getInstruction<ReferenceInstruction>(iGetObjectIndex).reference
|
||||||
val invokeInterfaceReference =
|
val invokeInterfaceReference =
|
||||||
getInstruction<ReferenceInstruction>(iGetObjectIndex + 1).reference
|
getInstruction<ReferenceInstruction>(invokeInterfaceIndex).reference
|
||||||
val checkCastReference =
|
val checkCastReference =
|
||||||
getInstruction<ReferenceInstruction>(checkCastIndex).reference
|
getInstruction<ReferenceInstruction>(checkCastIndex).reference
|
||||||
val getOrdinalClassReference =
|
val getOrdinalClassReference =
|
||||||
@ -890,12 +893,82 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
|||||||
|
|
||||||
// region patch for restore old comments popup panels
|
// region patch for restore old comments popup panels
|
||||||
|
|
||||||
OldEngagementPanelFingerprint.result?.let {
|
var restoreOldCommentsPopupPanel = false
|
||||||
|
|
||||||
|
if (SettingsPatch.upward0627 && !SettingsPatch.upward0718) {
|
||||||
OldEngagementPanelFingerprint.injectLiteralInstructionBooleanCall(
|
OldEngagementPanelFingerprint.injectLiteralInstructionBooleanCall(
|
||||||
45427672,
|
45427672,
|
||||||
"$PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z"
|
"$PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z"
|
||||||
)
|
)
|
||||||
|
restoreOldCommentsPopupPanel = true
|
||||||
|
} else if (SettingsPatch.upward0718) {
|
||||||
|
|
||||||
|
// region disable player from being pushed to the top when opening a comment
|
||||||
|
|
||||||
|
MppWatchWhileLayoutFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
|
val callableIndex =
|
||||||
|
MppWatchWhileLayoutFingerprint.indexOfCallableInstruction(this)
|
||||||
|
val insertIndex = indexOfFirstInstructionReversedOrThrow(callableIndex, Opcode.NEW_INSTANCE)
|
||||||
|
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
insertIndex, """
|
||||||
|
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels()Z
|
||||||
|
move-result v$insertRegister
|
||||||
|
if-eqz v$insertRegister, :restore
|
||||||
|
""", ExternalLabel("restore", getInstruction(callableIndex + 1))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region region limit the height of the engagement panel
|
||||||
|
|
||||||
|
EngagementPanelHeightFingerprint.alsoResolve(
|
||||||
|
context, EngagementPanelHeightParentFingerprint
|
||||||
|
).let {
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
||||||
|
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
targetIndex + 1, """
|
||||||
|
invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z
|
||||||
|
move-result v$targetRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MiniPlayerDefaultViewVisibilityFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableClass.methods.find { method ->
|
||||||
|
method.parameters == listOf("Landroid/view/View;", "I")
|
||||||
|
}?.apply {
|
||||||
|
val targetIndex = indexOfFirstInstructionOrThrow {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
opcode == Opcode.INVOKE_INTERFACE
|
||||||
|
&& reference?.returnType == "Z"
|
||||||
|
&& reference.parameterTypes.size == 0
|
||||||
|
} + 1
|
||||||
|
val targetRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
targetIndex + 1, """
|
||||||
|
invoke-static {v$targetRegister}, $PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z
|
||||||
|
move-result v$targetRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
} ?: throw PatchException("Could not find targetMethod")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
restoreOldCommentsPopupPanel = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restoreOldCommentsPopupPanel) {
|
||||||
SettingsPatch.addSwitchPreference(
|
SettingsPatch.addSwitchPreference(
|
||||||
CategoryType.PLAYER,
|
CategoryType.PLAYER,
|
||||||
"revanced_restore_old_comments_popup_panels",
|
"revanced_restore_old_comments_popup_panels",
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
internal object EngagementPanelHeightFingerprint : MethodFingerprint(
|
||||||
|
returnType = "L",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
),
|
||||||
|
parameters = emptyList(),
|
||||||
|
customFingerprint = custom@{ methodDef, _ ->
|
||||||
|
methodDef.indexOfFirstInstruction {
|
||||||
|
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||||
|
getReference<MethodReference>()?.name == "booleanValue"
|
||||||
|
} >= 0
|
||||||
|
}
|
||||||
|
)
|
@ -0,0 +1,28 @@
|
|||||||
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
|
||||||
|
internal object EngagementPanelHeightParentFingerprint : MethodFingerprint(
|
||||||
|
returnType = "L",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
opcodes = listOf(Opcode.NEW_ARRAY),
|
||||||
|
parameters = emptyList(),
|
||||||
|
customFingerprint = custom@{ methodDef, _ ->
|
||||||
|
if (methodDef.definingClass.startsWith("Lcom/")) {
|
||||||
|
return@custom false
|
||||||
|
}
|
||||||
|
if (methodDef.returnType == "Ljava/lang/Object;") {
|
||||||
|
return@custom false
|
||||||
|
}
|
||||||
|
|
||||||
|
methodDef.indexOfFirstInstruction {
|
||||||
|
opcode == Opcode.CHECK_CAST &&
|
||||||
|
(this as? ReferenceInstruction)?.reference?.toString() == "Lcom/google/android/libraries/youtube/engagementpanel/size/EngagementPanelSizeBehavior;"
|
||||||
|
} >= 0
|
||||||
|
}
|
||||||
|
)
|
@ -1,16 +1,36 @@
|
|||||||
package app.revanced.patches.music.player.components.fingerprints
|
package app.revanced.patches.music.player.components.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.patches.music.player.components.fingerprints.MppWatchWhileLayoutFingerprint.indexOfCallableInstruction
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
|
||||||
import app.revanced.util.containsWideLiteralInstructionValue
|
import app.revanced.util.containsWideLiteralInstructionValue
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
internal object MppWatchWhileLayoutFingerprint : MethodFingerprint(
|
internal object MppWatchWhileLayoutFingerprint : MethodFingerprint(
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
opcodes = listOf(Opcode.NEW_ARRAY),
|
opcodes = listOf(Opcode.NEW_ARRAY),
|
||||||
customFingerprint = { methodDef, _ ->
|
customFingerprint = custom@{ methodDef, _ ->
|
||||||
methodDef.definingClass.endsWith("/MppWatchWhileLayout;")
|
if (!methodDef.definingClass.endsWith("/MppWatchWhileLayout;")) {
|
||||||
&& methodDef.name == "onFinishInflate"
|
return@custom false
|
||||||
&& methodDef.containsWideLiteralInstructionValue(MiniPlayerPlayPauseReplayButton)
|
}
|
||||||
|
if (methodDef.name != "onFinishInflate") {
|
||||||
|
return@custom false
|
||||||
|
}
|
||||||
|
|
||||||
|
methodDef.containsWideLiteralInstructionValue(MiniPlayerPlayPauseReplayButton) &&
|
||||||
|
indexOfCallableInstruction(methodDef) >= 0
|
||||||
}
|
}
|
||||||
)
|
) {
|
||||||
|
fun indexOfCallableInstruction(methodDef: Method) =
|
||||||
|
methodDef.indexOfFirstInstruction {
|
||||||
|
val reference = getReference<MethodReference>()
|
||||||
|
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||||
|
reference?.returnType == "V" &&
|
||||||
|
reference.parameterTypes.size == 1 &&
|
||||||
|
reference.parameterTypes.firstOrNull() == "Ljava/util/concurrent/Callable;"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.or
|
|||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfImageViewInstruction
|
import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfImageViewInstruction
|
||||||
import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfOrdinalInstruction
|
import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfOrdinalInstruction
|
||||||
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.YtFillArrowShuffle
|
||||||
import app.revanced.util.containsWideLiteralInstructionValue
|
import app.revanced.util.containsWideLiteralInstructionValue
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
@ -19,7 +20,7 @@ internal object ShuffleClassReferenceFingerprint : MethodFingerprint(
|
|||||||
parameters = emptyList(),
|
parameters = emptyList(),
|
||||||
strings = listOf("Unknown shuffle mode"),
|
strings = listOf("Unknown shuffle mode"),
|
||||||
customFingerprint = { methodDef, _ ->
|
customFingerprint = { methodDef, _ ->
|
||||||
methodDef.containsWideLiteralInstructionValue(45468) &&
|
methodDef.containsWideLiteralInstructionValue(YtFillArrowShuffle) &&
|
||||||
indexOfOrdinalInstruction(methodDef) >= 0 &&
|
indexOfOrdinalInstruction(methodDef) >= 0 &&
|
||||||
indexOfImageViewInstruction(methodDef) >= 0
|
indexOfImageViewInstruction(methodDef) >= 0
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import app.revanced.patches.shared.mapping.ResourceMappingPatch
|
|||||||
import app.revanced.patches.shared.mapping.ResourceMappingPatch.getId
|
import app.revanced.patches.shared.mapping.ResourceMappingPatch.getId
|
||||||
import app.revanced.patches.shared.mapping.ResourceType.BOOL
|
import app.revanced.patches.shared.mapping.ResourceType.BOOL
|
||||||
import app.revanced.patches.shared.mapping.ResourceType.COLOR
|
import app.revanced.patches.shared.mapping.ResourceType.COLOR
|
||||||
|
import app.revanced.patches.shared.mapping.ResourceType.DRAWABLE
|
||||||
import app.revanced.patches.shared.mapping.ResourceType.DIMEN
|
import app.revanced.patches.shared.mapping.ResourceType.DIMEN
|
||||||
import app.revanced.patches.shared.mapping.ResourceType.ID
|
import app.revanced.patches.shared.mapping.ResourceType.ID
|
||||||
import app.revanced.patches.shared.mapping.ResourceType.LAYOUT
|
import app.revanced.patches.shared.mapping.ResourceType.LAYOUT
|
||||||
@ -57,6 +58,7 @@ object SharedResourceIdPatch : ResourcePatch() {
|
|||||||
var TouchOutside = -1L
|
var TouchOutside = -1L
|
||||||
var TrimSilenceSwitch: Long = -1
|
var TrimSilenceSwitch: Long = -1
|
||||||
var VarispeedUnavailableTitle = -1L
|
var VarispeedUnavailableTitle = -1L
|
||||||
|
var YtFillArrowShuffle = -1L
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
|
|
||||||
@ -102,6 +104,7 @@ object SharedResourceIdPatch : ResourcePatch() {
|
|||||||
TouchOutside = getId(ID, "touch_outside")
|
TouchOutside = getId(ID, "touch_outside")
|
||||||
TrimSilenceSwitch = getId(ID, "trim_silence_switch")
|
TrimSilenceSwitch = getId(ID, "trim_silence_switch")
|
||||||
VarispeedUnavailableTitle = getId(STRING, "varispeed_unavailable_title")
|
VarispeedUnavailableTitle = getId(STRING, "varispeed_unavailable_title")
|
||||||
|
YtFillArrowShuffle = getId(DRAWABLE, "yt_fill_arrow_shuffle_vd_theme_24")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -132,8 +132,10 @@ object SettingsPatch : BaseResourcePatch(
|
|||||||
|
|
||||||
val playServicesVersion = node.textContent.toInt()
|
val playServicesVersion = node.textContent.toInt()
|
||||||
|
|
||||||
|
upward0627 = 234412000 <= playServicesVersion
|
||||||
upward0636 = 240399000 <= playServicesVersion
|
upward0636 = 240399000 <= playServicesVersion
|
||||||
upward0642 = 240999000 <= playServicesVersion
|
upward0642 = 240999000 <= playServicesVersion
|
||||||
|
upward0718 = 243699000 <= playServicesVersion
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user