chore(YouTube): move TextComponentPatch to a shared path

This commit is contained in:
inotia00 2024-10-13 02:01:25 +09:00
parent b219e0d026
commit 4bc63034d3
8 changed files with 180 additions and 142 deletions

View File

@ -0,0 +1,135 @@
package app.revanced.patches.shared.textcomponent
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.textcomponent.fingerprints.SpannableStringBuilderFingerprint
import app.revanced.patches.shared.textcomponent.fingerprints.TextComponentConstructorFingerprint
import app.revanced.patches.shared.textcomponent.fingerprints.TextComponentContextFingerprint
import app.revanced.util.alsoResolve
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
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.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
object TextComponentPatch : BytecodePatch(
setOf(
SpannableStringBuilderFingerprint,
TextComponentConstructorFingerprint,
)
) {
override fun execute(context: BytecodeContext) {
SpannableStringBuilderFingerprint.resultOrThrow().mutableMethod.apply {
spannedMethod = this
spannedIndex = SpannableStringBuilderFingerprint.indexOfSpannableStringInstruction(this)
spannedRegister = getInstruction<FiveRegisterInstruction>(spannedIndex).registerC
spannedContextRegister =
getInstruction<TwoRegisterInstruction>(0).registerA
replaceInstruction(
spannedIndex,
"nop"
)
addInstruction(
++spannedIndex,
"invoke-static {v$spannedRegister}, ${SpannableStringBuilderFingerprint.SPANNABLE_STRING_REFERENCE}"
)
}
TextComponentContextFingerprint.alsoResolve(
context, TextComponentConstructorFingerprint
).let {
it.mutableMethod.apply {
textComponentMethod = this
val conversionContextFieldIndex = indexOfFirstInstructionOrThrow {
getReference<FieldReference>()?.type == "Ljava/util/Map;"
} - 1
val conversionContextFieldReference =
getInstruction<ReferenceInstruction>(conversionContextFieldIndex).reference
// ~ YouTube 19.32.xx
val legacyCharSequenceIndex = indexOfFirstInstruction {
getReference<FieldReference>()?.type == "Ljava/util/BitSet;"
} - 1
val charSequenceIndex = indexOfFirstInstruction {
val reference = getReference<MethodReference>()
opcode == Opcode.INVOKE_VIRTUAL &&
reference?.returnType == "V" &&
reference.parameterTypes.firstOrNull() == "Ljava/lang/CharSequence;"
}
val insertIndex: Int
if (legacyCharSequenceIndex > -2) {
textComponentRegister =
getInstruction<TwoRegisterInstruction>(legacyCharSequenceIndex).registerA
insertIndex = legacyCharSequenceIndex - 1
} else if (charSequenceIndex > -1) {
textComponentRegister =
getInstruction<FiveRegisterInstruction>(charSequenceIndex).registerD
insertIndex = charSequenceIndex
} else {
throw PatchException("Could not find insert index")
}
textComponentContextRegister = getInstruction<TwoRegisterInstruction>(
indexOfFirstInstructionOrThrow(insertIndex, Opcode.IGET_OBJECT)
).registerA
addInstructions(
insertIndex, """
move-object/from16 v$textComponentContextRegister, p0
iget-object v$textComponentContextRegister, v$textComponentContextRegister, $conversionContextFieldReference
"""
)
textComponentIndex = insertIndex + 2
}
}
}
private lateinit var spannedMethod: MutableMethod
private var spannedIndex = 0
private var spannedRegister = 0
private var spannedContextRegister = 0
private lateinit var textComponentMethod: MutableMethod
private var textComponentIndex = 0
private var textComponentRegister = 0
private var textComponentContextRegister = 0
fun hookSpannableString(
classDescriptor: String,
methodName: String
) = spannedMethod.addInstructions(
spannedIndex, """
invoke-static {v$spannedContextRegister, v$spannedRegister}, $classDescriptor->$methodName(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$spannedRegister
"""
)
fun hookTextComponent(
classDescriptor: String,
methodName: String = "onLithoTextLoaded"
) = textComponentMethod.apply {
addInstructions(
textComponentIndex, """
invoke-static {v$textComponentContextRegister, v$textComponentRegister}, $classDescriptor->$methodName(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$textComponentRegister
"""
)
textComponentIndex += 2
}
}

View File

@ -0,0 +1,26 @@
package app.revanced.patches.shared.textcomponent.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.shared.textcomponent.fingerprints.SpannableStringBuilderFingerprint.indexOfSpannableStringInstruction
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
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 SpannableStringBuilderFingerprint : MethodFingerprint(
returnType = "Ljava/lang/CharSequence;",
strings = listOf("Failed to set PB Style Run Extension in TextComponentSpec. Extension id: %s"),
customFingerprint = { methodDef, _ ->
indexOfSpannableStringInstruction(methodDef) >= 0
}
) {
const val SPANNABLE_STRING_REFERENCE =
"Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;"
fun indexOfSpannableStringInstruction(methodDef: Method) =
methodDef.indexOfFirstInstruction {
opcode == Opcode.INVOKE_STATIC &&
getReference<MethodReference>()?.toString() == SPANNABLE_STRING_REFERENCE
}
}

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints package app.revanced.patches.shared.textcomponent.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints package app.revanced.patches.shared.textcomponent.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -11,6 +11,7 @@ import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.litho.LithoFilterPatch import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.patches.shared.textcomponent.TextComponentPatch
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsButtonFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsButtonFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPaidPromotionFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPaidPromotionFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPausedHeaderFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPausedHeaderFingerprint
@ -18,7 +19,6 @@ import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsPivotLe
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletParentFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.ShortsSubscriptionsTabletParentFingerprint
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.fingerprints.TextComponentSpecFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
@ -35,7 +35,6 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.Right
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
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
import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
@ -44,7 +43,6 @@ import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.replaceLiteralInstructionCall import app.revanced.util.replaceLiteralInstructionCall
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
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.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
@ -65,7 +63,8 @@ object ShortsComponentPatch : BaseBytecodePatch(
ShortsRepeatPatch::class, ShortsRepeatPatch::class,
ShortsTimeStampPatch::class, ShortsTimeStampPatch::class,
ShortsToolBarPatch::class, ShortsToolBarPatch::class,
VideoInformationPatch::class TextComponentPatch::class,
VideoInformationPatch::class,
), ),
compatiblePackages = COMPATIBLE_PACKAGE, compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf( fingerprints = setOf(
@ -74,7 +73,6 @@ object ShortsComponentPatch : BaseBytecodePatch(
ShortsPausedHeaderFingerprint, ShortsPausedHeaderFingerprint,
ShortsPivotLegacyFingerprint, ShortsPivotLegacyFingerprint,
ShortsSubscriptionsTabletParentFingerprint, ShortsSubscriptionsTabletParentFingerprint,
TextComponentSpecFingerprint
) )
) { ) {
private const val INTEGRATION_CLASS_DESCRIPTOR = private const val INTEGRATION_CLASS_DESCRIPTOR =
@ -324,29 +322,7 @@ object ShortsComponentPatch : BaseBytecodePatch(
// region patch for return shorts channel name // region patch for return shorts channel name
TextComponentSpecFingerprint.resultOrThrow().let { TextComponentPatch.hookSpannableString(INTEGRATION_CLASS_DESCRIPTOR, "onCharSequenceLoaded")
it.mutableMethod.apply {
val insertIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.toString() == "Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;"
}
val charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
val conversionContextRegister =
getInstruction<TwoRegisterInstruction>(0).registerA
val replaceReference =
getInstruction<ReferenceInstruction>(insertIndex).reference
addInstructions(
insertIndex + 1, """
invoke-static {v$conversionContextRegister, v$charSequenceRegister}, $INTEGRATION_CLASS_DESCRIPTOR->onCharSequenceLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$charSequenceRegister
invoke-static {v$charSequenceRegister}, $replaceReference
"""
)
removeInstruction(insertIndex)
}
}
VideoInformationPatch.hookShorts("$INTEGRATION_CLASS_DESCRIPTOR->newShortsVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V") VideoInformationPatch.hookShorts("$INTEGRATION_CLASS_DESCRIPTOR->newShortsVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V")

View File

@ -1,8 +0,0 @@
package app.revanced.patches.youtube.utils.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object TextComponentSpecFingerprint : MethodFingerprint(
returnType = "Ljava/lang/CharSequence;",
strings = listOf("Failed to set PB Style Run Extension in TextComponentSpec. Extension id: %s")
)

View File

@ -2,34 +2,22 @@ package app.revanced.patches.youtube.utils.returnyoutubedislike.general
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.PatchException
import app.revanced.patches.shared.litho.LithoFilterPatch import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.patches.shared.textcomponent.TextComponentPatch
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.DislikeFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.DislikeFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.LikeFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.LikeFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.RemoveLikeFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.RemoveLikeFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentConstructorFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentContextFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.ReturnYouTubeDislikeRollingNumberPatch import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.ReturnYouTubeDislikeRollingNumberPatch
import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.ReturnYouTubeDislikeShortsPatch import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.ReturnYouTubeDislikeShortsPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.patches.youtube.video.videoid.VideoIdPatch
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
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.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object ReturnYouTubeDislikePatch : BaseBytecodePatch( object ReturnYouTubeDislikePatch : BaseBytecodePatch(
@ -40,6 +28,7 @@ object ReturnYouTubeDislikePatch : BaseBytecodePatch(
ReturnYouTubeDislikeRollingNumberPatch::class, ReturnYouTubeDislikeRollingNumberPatch::class,
ReturnYouTubeDislikeShortsPatch::class, ReturnYouTubeDislikeShortsPatch::class,
SettingsPatch::class, SettingsPatch::class,
TextComponentPatch::class,
VideoInformationPatch::class VideoInformationPatch::class
), ),
compatiblePackages = COMPATIBLE_PACKAGE, compatiblePackages = COMPATIBLE_PACKAGE,
@ -47,7 +36,6 @@ object ReturnYouTubeDislikePatch : BaseBytecodePatch(
DislikeFingerprint, DislikeFingerprint,
LikeFingerprint, LikeFingerprint,
RemoveLikeFingerprint, RemoveLikeFingerprint,
TextComponentConstructorFingerprint
) )
) { ) {
private const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR = private const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR =
@ -70,59 +58,7 @@ object ReturnYouTubeDislikePatch : BaseBytecodePatch(
) )
} }
TextComponentPatch.hookTextComponent(INTEGRATIONS_RYD_CLASS_DESCRIPTOR)
TextComponentConstructorFingerprint.resultOrThrow().let { parentResult ->
// Resolves fingerprints
TextComponentContextFingerprint.resolve(context, parentResult.classDef)
TextComponentContextFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val conversionContextFieldIndex = indexOfFirstInstructionOrThrow {
getReference<FieldReference>()?.type == "Ljava/util/Map;"
} - 1
val conversionContextFieldReference =
getInstruction<ReferenceInstruction>(conversionContextFieldIndex).reference
val charSequenceIndex1932 = indexOfFirstInstruction {
getReference<FieldReference>()?.type == "Ljava/util/BitSet;"
} - 1
val charSequenceIndex1933 = indexOfFirstInstruction {
val reference = getReference<MethodReference>()
opcode == Opcode.INVOKE_VIRTUAL &&
reference?.returnType == "V" &&
reference.parameterTypes.firstOrNull() == "Ljava/lang/CharSequence;"
}
val insertIndex: Int
val charSequenceRegister: Int
if (charSequenceIndex1932 > -2) {
charSequenceRegister =
getInstruction<TwoRegisterInstruction>(charSequenceIndex1932).registerA
insertIndex = charSequenceIndex1932 - 1
} else if (charSequenceIndex1933 > -1) {
charSequenceRegister =
getInstruction<FiveRegisterInstruction>(charSequenceIndex1933).registerD
insertIndex = charSequenceIndex1933
} else {
throw PatchException("Could not find insert index")
}
val freeRegister = getInstruction<TwoRegisterInstruction>(
indexOfFirstInstructionOrThrow(insertIndex, Opcode.IGET_OBJECT)
).registerA
addInstructions(
insertIndex, """
move-object/from16 v$freeRegister, p0
iget-object v$freeRegister, v$freeRegister, $conversionContextFieldReference
invoke-static {v$freeRegister, v$charSequenceRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$charSequenceRegister
"""
)
}
}
}
// region Inject newVideoLoaded event handler to update dislikes when a new video is loaded. // region Inject newVideoLoaded event handler to update dislikes when a new video is loaded.
VideoIdPatch.hookVideoId("$INTEGRATIONS_RYD_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V") VideoIdPatch.hookVideoId("$INTEGRATIONS_RYD_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V")

View File

@ -1,33 +1,29 @@
package app.revanced.patches.youtube.utils.returnyoutubedislike.shorts package app.revanced.patches.youtube.utils.returnyoutubedislike.shorts
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
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.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.utils.fingerprints.TextComponentSpecFingerprint import app.revanced.patches.shared.textcomponent.TextComponentPatch
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints.ShortsTextViewFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints.ShortsTextViewFingerprint
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
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.reference.MethodReference
@Patch(dependencies = [SettingsPatch::class]) @Patch(
dependencies = [
SettingsPatch::class,
TextComponentPatch::class
]
)
object ReturnYouTubeDislikeShortsPatch : BytecodePatch( object ReturnYouTubeDislikeShortsPatch : BytecodePatch(
setOf( setOf(ShortsTextViewFingerprint)
ShortsTextViewFingerprint,
TextComponentSpecFingerprint
)
) { ) {
private const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR = private const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR =
"$UTILS_PATH/ReturnYouTubeDislikePatch;" "$UTILS_PATH/ReturnYouTubeDislikePatch;"
@ -71,31 +67,8 @@ object ReturnYouTubeDislikeShortsPatch : BytecodePatch(
} }
} }
if (!SettingsPatch.upward1834) { if (SettingsPatch.upward1834) {
return TextComponentPatch.hookSpannableString(INTEGRATIONS_RYD_CLASS_DESCRIPTOR, "onCharSequenceLoaded")
}
TextComponentSpecFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.toString() == "Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;"
}
val charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
val conversionContextRegister =
getInstruction<TwoRegisterInstruction>(0).registerA
val replaceReference =
getInstruction<ReferenceInstruction>(insertIndex).reference
addInstructions(
insertIndex + 1, """
invoke-static {v$conversionContextRegister, v$charSequenceRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onCharSequenceLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$charSequenceRegister
invoke-static {v$charSequenceRegister}, $replaceReference
"""
)
removeInstruction(insertIndex)
}
} }
} }
} }