From 3e24fdc76d89ae639fe7ee4b1710713042cfc2d4 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Wed, 10 Jan 2024 23:38:11 +0400 Subject: [PATCH] feat: Unofficial early support for `19.01.33` --- .../PlayerResponseMethodHookPatch.kt | 56 +++++++++++++++---- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt index 3811b761fd..135779eec2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt @@ -18,29 +18,44 @@ object PlayerResponseMethodHookPatch : BytecodePatch(setOf(PlayerParameterBuilderFingerprint)), Closeable, MutableSet by mutableSetOf() { - private const val VIDEO_ID_PARAMETER = 1 - private const val IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER = 11 - private const val PROTO_BUFFER_PARAMETER_PARAMETER = 3 + + // Parameter numbers of the patched method. + private const val PARAMETER_VIDEO_ID = 1 + private const val PARAMETER_PROTO_BUFFER = 3 + private const val PARAMETER_IS_SHORT_AND_OPENING_OR_PLAYING = 11 + + // Temporary 4-bit registers used to pass the parameters to integrations. + private const val REGISTER_VIDEO_ID = 0 + private const val REGISTER_PROTO_BUFFER = 1 + private const val REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING = 2 private lateinit var playerResponseMethod: MutableMethod + private var numberOfInstructionsAdded = 0 + override fun execute(context: BytecodeContext) { playerResponseMethod = PlayerParameterBuilderFingerprint.result?.mutableMethod ?: throw PlayerParameterBuilderFingerprint.exception } override fun close() { - fun hookVideoId(hook: Hook) = playerResponseMethod.addInstruction( - 0, "invoke-static {p$VIDEO_ID_PARAMETER, p$IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER}, $hook" - ) + fun hookVideoId(hook: Hook) { + playerResponseMethod.addInstruction( + 0, "invoke-static {v$REGISTER_VIDEO_ID, v$REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING}, $hook" + ) + numberOfInstructionsAdded++ + } - fun hookProtoBufferParameter(hook: Hook) = playerResponseMethod.addInstructions( - 0, - """ - invoke-static {p$PROTO_BUFFER_PARAMETER_PARAMETER, p$IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER}, $hook - move-result-object p$PROTO_BUFFER_PARAMETER_PARAMETER + fun hookProtoBufferParameter(hook: Hook) { + playerResponseMethod.addInstructions( + 0, + """ + invoke-static {v$REGISTER_PROTO_BUFFER, v$REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING}, $hook + move-result-object v$REGISTER_PROTO_BUFFER """ - ) + ) + numberOfInstructionsAdded += 2 + } // Reverse the order in order to preserve insertion order of the hooks. val beforeVideoIdHooks = filterIsInstance().asReversed() @@ -51,6 +66,23 @@ object PlayerResponseMethodHookPatch : afterVideoIdHooks.forEach(::hookProtoBufferParameter) videoIdHooks.forEach(::hookVideoId) beforeVideoIdHooks.forEach(::hookProtoBufferParameter) + + // On some app targets the method has too many registers pushing the parameters past v15. + // Move the parameters to 4-bit registers so they can be passed to integrations. + playerResponseMethod.addInstructions( + 0, """ + move-object/from16 v$REGISTER_VIDEO_ID, p$PARAMETER_VIDEO_ID + move-object/from16 v$REGISTER_PROTO_BUFFER, p$PARAMETER_PROTO_BUFFER + move/from16 v$REGISTER_IS_SHORT_AND_OPENING_OR_PLAYING, p$PARAMETER_IS_SHORT_AND_OPENING_OR_PLAYING + """, + ) + numberOfInstructionsAdded += 3 + + // Move the modified register back. + playerResponseMethod.addInstruction( + numberOfInstructionsAdded, + "move-object/from16 p$PARAMETER_PROTO_BUFFER, v$REGISTER_PROTO_BUFFER" + ) } internal abstract class Hook(private val methodDescriptor: String) {