From b27aae85010785e12960e2a23bb1614afce21109 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 20 Jan 2025 02:31:09 +0900 Subject: [PATCH] fix(YouTube - Change live ring click action): Clicking on the timestamp in the comments opens the channel --- .../general/OpenChannelOfLiveAvatarPatch.java | 19 ++++++++-- .../youtube/general/livering/Fingerprints.kt | 36 +++++++++++++++++++ .../livering/OpenChannelOfLiveAvatarPatch.kt | 13 +++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/OpenChannelOfLiveAvatarPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/OpenChannelOfLiveAvatarPatch.java index 4acf4e346..7c6971af2 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/OpenChannelOfLiveAvatarPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/OpenChannelOfLiveAvatarPatch.java @@ -11,8 +11,17 @@ public final class OpenChannelOfLiveAvatarPatch { Settings.CHANGE_LIVE_RING_CLICK_ACTION.get(); private static volatile String videoId = ""; + private static volatile boolean isCommentsPanelOpen = false; private static volatile boolean liveChannelAvatarClicked = false; + public static void commentsPanelClosed() { + isCommentsPanelOpen = false; + } + + public static void commentsPanelOpen() { + isCommentsPanelOpen = true; + } + public static void liveChannelAvatarClicked() { liveChannelAvatarClicked = true; } @@ -25,6 +34,9 @@ public final class OpenChannelOfLiveAvatarPatch { if (!liveChannelAvatarClicked) { return false; } + if (isCommentsPanelOpen) { + return false; + } VideoDetailsRequest request = VideoDetailsRequest.getRequestForVideoId(videoId); if (request != null) { String channelId = request.getInfo(); @@ -45,10 +57,13 @@ public final class OpenChannelOfLiveAvatarPatch { if (!CHANGE_LIVE_RING_CLICK_ACTION) { return; } - if (newlyLoadedVideoId.isEmpty()) { + if (!liveChannelAvatarClicked) { return; } - if (!liveChannelAvatarClicked) { + if (isCommentsPanelOpen) { + return; + } + if (newlyLoadedVideoId.isEmpty()) { return; } videoId = newlyLoadedVideoId; diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/Fingerprints.kt index 873ef9df8..b77494757 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/Fingerprints.kt @@ -40,3 +40,39 @@ internal fun indexOfPlaybackStartDescriptorInstruction(method: Method) = reference?.returnType == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" && reference.parameterTypes.isEmpty() } + +internal val engagementPanelCommentsClosedFingerprint = legacyFingerprint( + name = "engagementPanelCommentsClosedFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + opcodes = listOf( + Opcode.IGET_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.IGET_OBJECT, + Opcode.INVOKE_DIRECT, + ), + customFingerprint = { method, _ -> + method.indexOfFirstInstruction { + opcode == Opcode.INVOKE_INTERFACE && + getReference()?.name == "hasNext" + } >= 0 + } +) + +internal val engagementPanelCommentsOpenFingerprint = legacyFingerprint( + name = "engagementPanelCommentsOpenFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L"), + opcodes = listOf( + Opcode.IGET_OBJECT, + Opcode.IF_NE, + Opcode.RETURN_VOID, + Opcode.IPUT_OBJECT, + Opcode.RETURN_VOID, + ), + customFingerprint = { method, _ -> + method.implementation!!.instructions.count() == 5 + } +) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt index 8c8a1a95f..62e6ee695 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt @@ -6,6 +6,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.engagementPanelTitleParentFingerprint import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_PATH import app.revanced.patches.youtube.utils.patch.PatchList.CHANGE_LIVE_RING_CLICK_ACTION import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch @@ -37,6 +38,18 @@ val openChannelOfLiveAvatarPatch = bytecodePatch( execute { + mapOf( + engagementPanelCommentsClosedFingerprint to "commentsPanelClosed", + engagementPanelCommentsOpenFingerprint to "commentsPanelOpen", + ).forEach { (fingerprint, methodName) -> + fingerprint + .methodOrThrow(engagementPanelTitleParentFingerprint) + .addInstruction( + 0, + "invoke-static {}, $EXTENSION_CLASS_DESCRIPTOR->$methodName()V" + ) + } + elementsImageFingerprint.methodOrThrow().addInstruction( 0, "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->liveChannelAvatarClicked()V"