feat(youtube): add support version v18.19.36 & v18.31.40

This commit is contained in:
inotia00 2023-09-05 12:48:26 +09:00
parent 2afe8614cc
commit 47b2ed2104
25 changed files with 179 additions and 162 deletions

View File

@ -5,12 +5,11 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
object SecondaryPiPFingerprint : MethodFingerprint( object PiPNotificationFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"), parameters = listOf("L"),
opcodes = listOf( opcodes = listOf(
null,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.IF_EQZ, Opcode.IF_EQZ,

View File

@ -1,21 +0,0 @@
package app.revanced.patches.youtube.layout.pipnotification.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object PrimaryPiPFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"),
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.IPUT_BOOLEAN
),
strings = listOf("honeycomb.Shell\$HomeActivity")
)

View File

@ -5,13 +5,17 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
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.patches.youtube.layout.pipnotification.fingerprints.PrimaryPiPFingerprint import app.revanced.patches.youtube.layout.pipnotification.fingerprints.PiPNotificationFingerprint
import app.revanced.patches.youtube.layout.pipnotification.fingerprints.SecondaryPiPFingerprint
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.bytecode.getStringIndex
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@Patch @Patch
@Name("Disable pip notification") @Name("Disable pip notification")
@ -19,26 +23,36 @@ import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
@DependsOn([SettingsPatch::class]) @DependsOn([SettingsPatch::class])
@YouTubeCompatibility @YouTubeCompatibility
class PiPNotificationPatch : BytecodePatch( class PiPNotificationPatch : BytecodePatch(
listOf( listOf(PiPNotificationFingerprint)
PrimaryPiPFingerprint,
SecondaryPiPFingerprint
)
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
arrayOf( PiPNotificationFingerprint.result?.let {
PrimaryPiPFingerprint,
SecondaryPiPFingerprint
).forEach { fingerprint ->
fingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
var insertIndex = -1
val startIndex = it.scanResult.patternScanResult!!.startIndex - 6
val endIndex = getStringIndex("honeycomb.Shell\$HomeActivity")
for (index in endIndex downTo startIndex) {
if (getInstruction(index).opcode != Opcode.CHECK_CAST) continue
val targetReference =
getInstruction<ReferenceInstruction>(index).reference.toString()
if (targetReference == "Lcom/google/apps/tiktok/account/AccountId;") {
insertIndex = index + 1
addInstruction( addInstruction(
it.scanResult.patternScanResult!!.endIndex - 4, insertIndex,
"return-void" "return-void"
) )
} }
} ?: throw fingerprint.exception
} }
if (insertIndex == -1)
throw PatchException("Couldn't find target Index")
}
} ?: throw PiPNotificationFingerprint.exception
/** /**
* Add settings * Add settings

View File

@ -2,24 +2,19 @@ package app.revanced.patches.youtube.misc.ambientmode.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.YtBrandBackgroundSolid
import app.revanced.util.bytecode.isWideLiteralExists
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
object PowerSaveModeFingerprint : MethodFingerprint( object PowerSaveModeFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"), parameters = listOf("Ljava/lang/Object;"),
opcodes = listOf( opcodes = listOf(
Opcode.IGET_OBJECT, Opcode.IF_GT,
Opcode.CHECK_CAST, Opcode.IGET,
Opcode.CHECK_CAST, Opcode.ADD_INT_2ADDR
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
), ),
customFingerprint = { methodDef, _ -> methodDef.name == "accept" } customFingerprint = { methodDef, _ -> methodDef.isWideLiteralExists(YtBrandBackgroundSolid) && methodDef.name == "accept" }
) )

View File

@ -12,6 +12,7 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.misc.ambientmode.fingerprints.PowerSaveModeFingerprint import app.revanced.patches.youtube.misc.ambientmode.fingerprints.PowerSaveModeFingerprint
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.integrations.Constants.MISC_PATH import app.revanced.util.integrations.Constants.MISC_PATH
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -22,7 +23,12 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch @Patch
@Name("Bypass ambient mode restrictions") @Name("Bypass ambient mode restrictions")
@Description("Bypass ambient mode restrictions in battery saver mode.") @Description("Bypass ambient mode restrictions in battery saver mode.")
@DependsOn([SettingsPatch::class]) @DependsOn(
[
SettingsPatch::class,
SharedResourceIdPatch::class
]
)
@YouTubeCompatibility @YouTubeCompatibility
class PowerSaveModePatch : BytecodePatch( class PowerSaveModePatch : BytecodePatch(
listOf(PowerSaveModeFingerprint) listOf(PowerSaveModeFingerprint)

View File

@ -7,11 +7,12 @@ object GeneralPrefsFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
parameters = emptyList(), parameters = emptyList(),
opcodes = listOf( opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.IF_NEZ, Opcode.IF_NEZ,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.GOTO
), ),
strings = listOf("bedtime_reminder_toggle"), strings = listOf("bedtime_reminder_toggle"),
customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/GeneralPrefsFragment;") } customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/GeneralPrefsFragment;") }

View File

@ -26,7 +26,7 @@ class LanguageSelectorPatch : BytecodePatch(
GeneralPrefsFingerprint.result?.let { GeneralPrefsFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.startIndex + 2 val targetIndex = it.scanResult.patternScanResult!!.startIndex + 1
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(

View File

@ -8,8 +8,6 @@ import com.android.tools.smali.dexlib2.Opcode
object LayoutIconFingerprint : MethodFingerprint( object LayoutIconFingerprint : MethodFingerprint(
returnType = "Landroid/view/View;", returnType = "Landroid/view/View;",
opcodes = listOf( opcodes = listOf(
Opcode.CONST_4,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,

View File

@ -13,9 +13,9 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.patch.litho.LithoThemePatch import app.revanced.patches.shared.patch.litho.LithoThemePatch
import app.revanced.patches.youtube.seekbar.seekbarcolor.fingerprints.ControlsOverlayStyleFingerprint import app.revanced.patches.youtube.seekbar.seekbarcolor.fingerprints.ControlsOverlayStyleFingerprint
import app.revanced.patches.youtube.seekbar.seekbarcolor.fingerprints.PlayerSeekbarColorFingerprint
import app.revanced.patches.youtube.seekbar.seekbarcolor.fingerprints.ShortsSeekbarColorFingerprint import app.revanced.patches.youtube.seekbar.seekbarcolor.fingerprints.ShortsSeekbarColorFingerprint
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.fingerprints.PlayerSeekbarColorFingerprint
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.InlineTimeBarColorizedBarPlayedColorDark import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.InlineTimeBarColorizedBarPlayedColorDark
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.InlineTimeBarPlayedNotHighlightedColor import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.InlineTimeBarPlayedNotHighlightedColor

View File

@ -7,38 +7,11 @@ import com.android.tools.smali.dexlib2.Opcode
object TimeCounterFingerprint : MethodFingerprint( object TimeCounterFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(), parameters = emptyList(),
returnType = "V", returnType = "V",
opcodes = listOf( opcodes = listOf(
Opcode.RETURN_VOID,
Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.IGET_WIDE,
Opcode.IGET_WIDE,
Opcode.SUB_LONG_2ADDR,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_WIDE,
Opcode.IGET_WIDE,
Opcode.SUB_LONG_2ADDR, Opcode.SUB_LONG_2ADDR,
Opcode.IGET_WIDE, Opcode.IGET_WIDE,
Opcode.SUB_LONG_2ADDR, Opcode.SUB_LONG_2ADDR
Opcode.INVOKE_STATIC, )
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IGET_WIDE,
Opcode.IGET_WIDE,
Opcode.SUB_LONG_2ADDR,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.RETURN_VOID
),
customFingerprint = { _, classDef ->
// On older devices this fingerprint resolves very slowly.
// Speed this up by checking for the number of methods.
classDef.methods.count() == 14 || classDef.methods.count() == 15
}
) )

View File

@ -6,26 +6,35 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
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.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.seekbar.timestamps.fingerprints.TimeCounterFingerprint import app.revanced.patches.youtube.seekbar.timestamps.fingerprints.TimeCounterFingerprint
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.fingerprints.PlayerSeekbarColorFingerprint
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.integrations.Constants.SEEKBAR import app.revanced.util.integrations.Constants.SEEKBAR
@Patch @Patch
@Name("Hide time stamp") @Name("Hide time stamp")
@Description("Hides timestamp in video player.") @Description("Hides timestamp in video player.")
@DependsOn([SettingsPatch::class]) @DependsOn(
[
SettingsPatch::class,
SharedResourceIdPatch::class,
]
)
@YouTubeCompatibility @YouTubeCompatibility
class HideTimeStampPatch : BytecodePatch( class HideTimeStampPatch : BytecodePatch(
listOf(TimeCounterFingerprint) listOf(PlayerSeekbarColorFingerprint)
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
TimeCounterFingerprint.result?.let { PlayerSeekbarColorFingerprint.result?.let { parentResult ->
TimeCounterFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
addInstructionsWithLabels( addInstructionsWithLabels(
0, """ 0, """
@ -37,6 +46,7 @@ class HideTimeStampPatch : BytecodePatch(
) )
} }
} ?: throw TimeCounterFingerprint.exception } ?: throw TimeCounterFingerprint.exception
} ?: throw PlayerSeekbarColorFingerprint.exception
/** /**
* Add settings * Add settings

View File

@ -74,8 +74,8 @@ class ShortsSubscriptionsButtonPatch : BytecodePatch(
) )
} }
} }
} ?: throw ShortsSubscriptionsTabletFingerprint.exception }
} ?: throw ShortsSubscriptionsTabletParentFingerprint.exception }
} }

View File

@ -4,8 +4,11 @@ import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package import app.revanced.patcher.annotation.Package
@Compatibility( @Compatibility(
[Package( [
"com.google.android.youtube", arrayOf( Package(
"com.google.android.youtube",
arrayOf(
"18.19.36",
"18.20.39", "18.20.39",
"18.21.35", "18.21.35",
"18.22.37", "18.22.37",
@ -14,9 +17,11 @@ import app.revanced.patcher.annotation.Package
"18.25.40", "18.25.40",
"18.27.36", "18.27.36",
"18.29.38", "18.29.38",
"18.30.37" "18.30.37",
"18.31.40"
) )
)] )
]
) )
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
internal annotation class YouTubeCompatibility internal annotation class YouTubeCompatibility

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.seekbar.seekbarcolor.fingerprints package app.revanced.patches.youtube.utils.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint

View File

@ -9,5 +9,5 @@ object UserAgentHeaderBuilderFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL Opcode.INVOKE_VIRTUAL
), ),
strings = listOf("(Linux; U; Android "), strings = listOf("(Linux; U; Android ")
) )

View File

@ -1,13 +1,35 @@
package app.revanced.patches.youtube.utils.fix.parameter.fingerprints package app.revanced.patches.youtube.utils.fix.parameter.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
object ProtobufParameterBuilderFingerprint : MethodFingerprint( object ProtobufParameterBuilderFingerprint : MethodFingerprint(
opcodes = listOf( accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
Opcode.INVOKE_VIRTUAL_RANGE, // target reference returnType = "L",
Opcode.MOVE_RESULT_OBJECT, parameters = listOf(
Opcode.IPUT_OBJECT "Ljava/lang/String;",
"[B",
"Ljava/lang/String;",
"Ljava/lang/String;",
"I",
"I",
"Ljava/util/Set;",
"Ljava/lang/String;",
"Ljava/lang/String;",
"L",
"Z",
"Z",
"Z"
), ),
strings = listOf("Unexpected empty videoId.", "Prefetch request are disabled.") opcodes = listOf(
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE
),
customFingerprint = { methodDef, _ ->
methodDef.name == "b"
}
) )

View File

@ -11,7 +11,6 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
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.youtube.utils.annotations.YouTubeCompatibility import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.fix.parameter.fingerprints.ProtobufParameterBuilderFingerprint import app.revanced.patches.youtube.utils.fix.parameter.fingerprints.ProtobufParameterBuilderFingerprint
import app.revanced.patches.youtube.utils.fix.parameter.fingerprints.ScrubbedPreviewLayoutFingerprint import app.revanced.patches.youtube.utils.fix.parameter.fingerprints.ScrubbedPreviewLayoutFingerprint
@ -45,16 +44,11 @@ class SpoofPlayerParameterPatch : BytecodePatch(
// hook parameter // hook parameter
ProtobufParameterBuilderFingerprint.result?.let { ProtobufParameterBuilderFingerprint.result?.let {
(context it.mutableMethod.apply {
.toMethodWalker(it.method)
.nextMethod(it.scanResult.patternScanResult!!.startIndex, true)
.getMethod() as MutableMethod
).apply {
val protobufParam = 3 val protobufParam = 3
addInstructions( addInstructions(
0, 0, """
"""
invoke-static {p$protobufParam}, $INTEGRATIONS_CLASS_DESCRIPTOR->overridePlayerParameter(Ljava/lang/String;)Ljava/lang/String; invoke-static {p$protobufParam}, $INTEGRATIONS_CLASS_DESCRIPTOR->overridePlayerParameter(Ljava/lang/String;)Ljava/lang/String;
move-result-object p$protobufParam move-result-object p$protobufParam
""" """

View File

@ -9,7 +9,7 @@ object PlaybackSpeedPatchFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("F"), parameters = listOf("F"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/PlaybackSpeedPatch;") methodDef.definingClass == "Lapp/revanced/integrations/patches/video/PlaybackSpeedPatch;"
&& methodDef.name == "overrideSpeed" && methodDef.name == "overrideSpeed"
} }
) )

View File

@ -1,23 +1,18 @@
package app.revanced.patches.youtube.utils.quickactions.fingerprints package app.revanced.patches.youtube.utils.quickactions.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.QuickActionsElementContainer import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.QuickActionsElementContainer
import app.revanced.util.bytecode.isWideLiteralExists import app.revanced.util.bytecode.isWideLiteralExists
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.AccessFlags
object QuickActionsElementFingerprint : MethodFingerprint( object QuickActionsElementFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Landroid/view/View;"),
returnType = "V", returnType = "V",
opcodes = listOf( customFingerprint = { methodDef, _ ->
Opcode.RETURN_VOID, methodDef.isWideLiteralExists(
Opcode.IGET_OBJECT, QuickActionsElementContainer
Opcode.CONST, )
Opcode.INVOKE_VIRTUAL, }
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST
),
customFingerprint = { methodDef, _ -> methodDef.isWideLiteralExists(QuickActionsElementContainer) }
) )

View File

@ -8,8 +8,11 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.utils.quickactions.fingerprints.QuickActionsElementFingerprint import app.revanced.patches.youtube.utils.quickactions.fingerprints.QuickActionsElementFingerprint
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.resourceid.patch.SharedResourceIdPatch.Companion.QuickActionsElementContainer
import app.revanced.util.integrations.Constants.FULLSCREEN import app.revanced.util.integrations.Constants.FULLSCREEN
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
@DependsOn([SharedResourceIdPatch::class]) @DependsOn([SharedResourceIdPatch::class])
class QuickActionsHookPatch : BytecodePatch( class QuickActionsHookPatch : BytecodePatch(
@ -19,13 +22,18 @@ class QuickActionsHookPatch : BytecodePatch(
QuickActionsElementFingerprint.result?.let { QuickActionsElementFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = it.scanResult.patternScanResult!!.endIndex for (index in implementation!!.instructions.size - 1 downTo 0) {
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA if (getInstruction(index).opcode == Opcode.CONST && (getInstruction(index) as WideLiteralInstruction).wideLiteral == QuickActionsElementContainer) {
val targetRegister =
getInstruction<OneRegisterInstruction>(index + 2).registerA
addInstruction( addInstruction(
insertIndex, index + 3,
"invoke-static {v$targetRegister}, $FULLSCREEN->hideQuickActions(Landroid/view/View;)V" "invoke-static {v$targetRegister}, $FULLSCREEN->hideQuickActions(Landroid/view/View;)V"
) )
break
}
}
} }
} ?: throw QuickActionsElementFingerprint.exception } ?: throw QuickActionsElementFingerprint.exception

View File

@ -78,6 +78,7 @@ class SharedResourceIdPatch : ResourcePatch {
var VideoZoomIndicatorLayout: Long = -1 var VideoZoomIndicatorLayout: Long = -1
var WordMarkHeader: Long = -1 var WordMarkHeader: Long = -1
var YoutubeControlsOverlay: Long = -1 var YoutubeControlsOverlay: Long = -1
var YtBrandBackgroundSolid: Long = -1
var YtOutlineArrowTimeBlack: Long = -1 var YtOutlineArrowTimeBlack: Long = -1
var YtOutlineFireBlack: Long = -1 var YtOutlineFireBlack: Long = -1
var YtOutlineSearchBlack: Long = -1 var YtOutlineSearchBlack: Long = -1
@ -154,6 +155,7 @@ class SharedResourceIdPatch : ResourcePatch {
VideoZoomIndicatorLayout = find(ID, "video_zoom_indicator_layout") VideoZoomIndicatorLayout = find(ID, "video_zoom_indicator_layout")
WordMarkHeader = find(ATTR, "ytWordmarkHeader") WordMarkHeader = find(ATTR, "ytWordmarkHeader")
YoutubeControlsOverlay = find(ID, "youtube_controls_overlay") YoutubeControlsOverlay = find(ID, "youtube_controls_overlay")
YtBrandBackgroundSolid = find(ATTR, "ytBrandBackgroundSolid")
YtOutlineArrowTimeBlack = find(DRAWABLE, "yt_outline_arrow_time_black_24") YtOutlineArrowTimeBlack = find(DRAWABLE, "yt_outline_arrow_time_black_24")
YtOutlineFireBlack = find(DRAWABLE, "yt_outline_fire_black_24") YtOutlineFireBlack = find(DRAWABLE, "yt_outline_fire_black_24")
YtOutlineSearchBlack = find(DRAWABLE, "yt_outline_search_black_24") YtOutlineSearchBlack = find(DRAWABLE, "yt_outline_search_black_24")

View File

@ -10,7 +10,7 @@ object TextComponentContextFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL, accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
parameters = listOf("L"), parameters = listOf("L"),
opcodes = listOf( opcodes = listOf(
Opcode.IGET_OBJECT, // conversion context Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.IGET_BOOLEAN Opcode.IGET_BOOLEAN

View File

@ -27,6 +27,7 @@ import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.patch.Retu
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.patches.youtube.utils.videoid.general.patch.VideoIdPatch import app.revanced.patches.youtube.utils.videoid.general.patch.VideoIdPatch
import app.revanced.util.integrations.Constants.UTILS_PATH import app.revanced.util.integrations.Constants.UTILS_PATH
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction 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.instruction.TwoRegisterInstruction
@ -79,9 +80,21 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
) )
}.result?.let { }.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
val conversionContextIndex = it.scanResult.patternScanResult!!.startIndex val booleanIndex = it.scanResult.patternScanResult!!.endIndex
for (index in booleanIndex downTo 0) {
if (getInstruction(index).opcode != Opcode.IGET_OBJECT) continue
val targetReference =
getInstruction<ReferenceInstruction>(index).reference.toString()
if (targetReference.endsWith("Ljava/util/Map;")) {
conversionContextFieldReference = conversionContextFieldReference =
getInstruction<ReferenceInstruction>(conversionContextIndex).reference getInstruction<ReferenceInstruction>(index - 1).reference
break
}
}
} }
} ?: throw TextComponentContextFingerprint.exception } ?: throw TextComponentContextFingerprint.exception

View File

@ -24,7 +24,5 @@ object ShortsTextViewFingerprint : MethodFingerprint(
Opcode.IF_EQ, Opcode.IF_EQ,
Opcode.RETURN_VOID, Opcode.RETURN_VOID,
Opcode.IGET_OBJECT, // TextView field Opcode.IGET_OBJECT, // TextView field
Opcode.CHECK_CAST,
Opcode.IGET_BOOLEAN, // boolean field
) )
) )

View File

@ -8,6 +8,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints.ShortsTextViewFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints.ShortsTextViewFingerprint
import app.revanced.util.integrations.Constants.UTILS_PATH import app.revanced.util.integrations.Constants.UTILS_PATH
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
class ReturnYouTubeDislikeShortsPatch : BytecodePatch( class ReturnYouTubeDislikeShortsPatch : BytecodePatch(
@ -18,12 +19,16 @@ class ReturnYouTubeDislikeShortsPatch : BytecodePatch(
it.mutableMethod.apply { it.mutableMethod.apply {
val patternResult = it.scanResult.patternScanResult!! val patternResult = it.scanResult.patternScanResult!!
val isDisLikesBooleanIndex =
implementation!!.instructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.IGET_BOOLEAN
}
// If the field is true, the TextView is for a dislike button. // If the field is true, the TextView is for a dislike button.
val isDisLikesBooleanReference = val isDisLikesBooleanReference =
getInstruction<ReferenceInstruction>(patternResult.endIndex).reference getInstruction<ReferenceInstruction>(isDisLikesBooleanIndex).reference
val textViewFieldReference = // Like/Dislike button TextView field val textViewFieldReference = // Like/Dislike button TextView field
getInstruction<ReferenceInstruction>(patternResult.endIndex - 2).reference getInstruction<ReferenceInstruction>(patternResult.endIndex).reference
// Check if the hooked TextView object is that of the dislike button. // Check if the hooked TextView object is that of the dislike button.
// If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted. // If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted.