@@ -4,21 +4,29 @@ import app.revanced.patcher.data.BytecodeContext
4
4
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
5
5
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
6
6
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
7
+ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
8
+ import app.revanced.patches.shared.fingerprints.SpannableStringBuilderFingerprint
7
9
import app.revanced.patches.shared.litho.LithoFilterPatch
10
+ import app.revanced.patches.shared.textcomponent.TextComponentPatch
8
11
import app.revanced.patches.youtube.player.comments.fingerprints.ShortsLiveStreamEmojiPickerOnClickListenerFingerprint
9
12
import app.revanced.patches.youtube.player.comments.fingerprints.ShortsLiveStreamEmojiPickerOpacityFingerprint
10
13
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
11
14
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
12
15
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
16
+ import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_PATH
13
17
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
14
18
import app.revanced.patches.youtube.utils.settings.SettingsPatch
19
+ import app.revanced.util.getFiveRegisters
20
+ import app.revanced.util.getReference
15
21
import app.revanced.util.getWalkerMethod
16
22
import app.revanced.util.indexOfFirstInstructionOrThrow
23
+ import app.revanced.util.indexOfFirstInstructionReversedOrThrow
17
24
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
18
25
import app.revanced.util.patch.BaseBytecodePatch
19
26
import app.revanced.util.resultOrThrow
20
27
import com.android.tools.smali.dexlib2.Opcode
21
28
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
29
+ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
22
30
23
31
@Suppress(" unused" )
24
32
object CommentsComponentPatch : BaseBytecodePatch(
@@ -27,19 +35,59 @@ object CommentsComponentPatch : BaseBytecodePatch(
27
35
dependencies = setOf(
28
36
LithoFilterPatch ::class,
29
37
SettingsPatch ::class,
30
- SharedResourceIdPatch ::class
38
+ SharedResourceIdPatch ::class,
39
+ TextComponentPatch ::class,
31
40
),
32
41
compatiblePackages = COMPATIBLE_PACKAGE ,
33
42
fingerprints = setOf(
34
43
ShortsLiveStreamEmojiPickerOnClickListenerFingerprint ,
35
- ShortsLiveStreamEmojiPickerOpacityFingerprint
44
+ ShortsLiveStreamEmojiPickerOpacityFingerprint ,
45
+ SpannableStringBuilderFingerprint ,
36
46
)
37
47
) {
38
48
private const val FILTER_CLASS_DESCRIPTOR =
39
49
" $COMPONENTS_PATH /CommentsFilter;"
50
+ private const val INTEGRATIONS_SEARCH_LINKS_CLASS_DESCRIPTOR =
51
+ " $PLAYER_PATH /SearchLinksPatch;"
40
52
41
53
override fun execute (context : BytecodeContext ) {
42
54
55
+ TextComponentPatch .hookSpannableString(
56
+ INTEGRATIONS_SEARCH_LINKS_CLASS_DESCRIPTOR ,
57
+ " setConversionContext"
58
+ )
59
+
60
+ SpannableStringBuilderFingerprint .resultOrThrow().mutableMethod.apply {
61
+ val spannedIndex =
62
+ SpannableStringBuilderFingerprint .indexOfSpannableStringInstruction(this )
63
+ val setInclusiveSpanIndex = indexOfFirstInstructionOrThrow(spannedIndex) {
64
+ val reference = getReference<MethodReference >()
65
+ opcode == Opcode .INVOKE_STATIC &&
66
+ reference?.returnType == " V" &&
67
+ reference.parameterTypes.size > 3 &&
68
+ reference.parameterTypes.firstOrNull() == " Landroid/text/SpannableString;"
69
+ }
70
+ // In YouTube 18.29.38, YouTube 19.41.39, the target method is in class 'La;'
71
+ // 'getWalkerMethod' should be used until the dependency is updated to ReVanced Patcher 20+.
72
+ // https://github.com/ReVanced/revanced-patcher/issues/309
73
+ val setInclusiveSpanMethod =
74
+ getWalkerMethod(context, setInclusiveSpanIndex)
75
+
76
+ setInclusiveSpanMethod.apply {
77
+ val insertIndex = indexOfFirstInstructionReversedOrThrow {
78
+ opcode == Opcode .INVOKE_VIRTUAL &&
79
+ getReference<MethodReference >().toString() == " Landroid/text/SpannableString;->setSpan(Ljava/lang/Object;III)V"
80
+ }
81
+ replaceInstruction(
82
+ insertIndex,
83
+ " invoke-static { ${getFiveRegisters(insertIndex)} }, " +
84
+ INTEGRATIONS_SEARCH_LINKS_CLASS_DESCRIPTOR +
85
+ " ->" +
86
+ " hideSearchLinks(Landroid/text/SpannableString;Ljava/lang/Object;III)V"
87
+ )
88
+ }
89
+ }
90
+
43
91
// region patch for emoji picker button in shorts
44
92
45
93
ShortsLiveStreamEmojiPickerOpacityFingerprint .resultOrThrow().let {
0 commit comments