diff --git a/api/revanced-patches.api b/api/revanced-patches.api index aedca5b993..8c86c23def 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -3402,86 +3402,12 @@ public final class app/revanced/patches/youtube/utils/resourceid/SharedResourceI public final fun setYtOutlineSearchBlack (J)V } -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch : app/revanced/patcher/patch/BytecodePatch { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch; +public final class app/revanced/patches/youtube/utils/returnyoutubedislike/ReturnYouTubeDislikePatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/ReturnYouTubeDislikePatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/DislikeFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/DislikeFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/LikeFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/LikeFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/RemoveLikeFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/RemoveLikeFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentConstructorFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentConstructorFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentContextFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentContextFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/ReturnYouTubeDislikeOldLayoutPatch : app/revanced/patcher/patch/BytecodePatch { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/ReturnYouTubeDislikeOldLayoutPatch; - public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V - public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/fingerprints/ButtonTagFingerprint : app/revanced/util/fingerprint/LiteralValueFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/fingerprints/ButtonTagFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/ReturnYouTubeDislikeRollingNumberPatch : app/revanced/patcher/patch/BytecodePatch { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/ReturnYouTubeDislikeRollingNumberPatch; - public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V - public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureAnimatedTextFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureAnimatedTextFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureStaticLabelFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureStaticLabelFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureTextParentFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureTextParentFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberSetterFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberSetterFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberTextViewFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberTextViewFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/ReturnYouTubeDislikeShortsPatch : app/revanced/patcher/patch/BytecodePatch { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/shorts/ReturnYouTubeDislikeShortsPatch; - public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V - public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/IncognitoFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/IncognitoFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/ShortsTextViewFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/ShortsTextViewFingerprint; -} - -public final class app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/TextComponentSpecFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint { - public static final field INSTANCE Lapp/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/TextComponentSpecFingerprint; -} - public final class app/revanced/patches/youtube/utils/settings/ResourceUtils { public static final field INSTANCE Lapp/revanced/patches/youtube/utils/settings/ResourceUtils; public static final field TARGET_PREFERENCE_PATH Ljava/lang/String; diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/ReturnYouTubeDislikePatch.kt new file mode 100644 index 0000000000..f427083fc7 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/ReturnYouTubeDislikePatch.kt @@ -0,0 +1,362 @@ +package app.revanced.patches.youtube.utils.returnyoutubedislike + +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.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.youtube.utils.fingerprints.RollingNumberTextViewAnimationUpdateFingerprint +import app.revanced.patches.youtube.utils.litho.LithoFilterPatch +import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch +import app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints.* +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.patches.youtube.utils.videoid.general.VideoIdPatch +import app.revanced.util.exception +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +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.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 +import com.android.tools.smali.dexlib2.iface.reference.TypeReference + +@Patch( + name = "Return YouTube Dislike", + description = "Adds an option to show the dislike count of videos using the Return YouTube Dislike API.", + dependencies = [ + SettingsPatch::class, + LithoFilterPatch::class, + VideoIdPatch::class, + ReturnYouTubeDislikeResourcePatch::class, + PlayerTypeHookPatch::class, + ], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube", [ + "18.49.37", + "19.01.34", + "19.02.39", + "19.03.36", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" + ] + ) + ] +) +@Suppress("unused") +object ReturnYouTubeDislikePatch : BytecodePatch( + setOf( + ConversionContextFingerprint, + TextComponentConstructorFingerprint, + TextComponentDataFingerprint, + ShortsTextViewFingerprint, + DislikesOldLayoutTextViewFingerprint, + LikeFingerprint, + DislikeFingerprint, + RemoveLikeFingerprint, + RollingNumberSetterFingerprint, + RollingNumberMeasureStaticLabelParentFingerprint, + RollingNumberMeasureAnimatedTextFingerprint, + RollingNumberTextViewFingerprint, + RollingNumberTextViewAnimationUpdateFingerprint + ) +) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/youtube/patches/utils/ReturnYouTubeDislikePatch;" + + private const val FILTER_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/youtube/patches/components/ReturnYouTubeDislikeFilterPatch;" + + private fun MethodFingerprint.getResultOrThrow() = + result ?: throw exception + + override fun execute(context: BytecodeContext) { + // region Inject newVideoLoaded event handler to update dislikes when a new video is loaded. + + VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V") + + // Hook the player response video id, to start loading RYD sooner in the background. + VideoIdPatch.injectPlayerResponseVideoId("$INTEGRATIONS_CLASS_DESCRIPTOR->preloadVideoId(Ljava/lang/String;Z)V") + + // endregion + + // region Hook like/dislike/remove like button clicks to send votes to the API. + + listOf( + LikeFingerprint.toPatch(Vote.LIKE), + DislikeFingerprint.toPatch(Vote.DISLIKE), + RemoveLikeFingerprint.toPatch(Vote.REMOVE_LIKE) + ).forEach { (fingerprint, vote) -> + fingerprint.result?.mutableMethod?.apply { + addInstructions( + 0, + """ + const/4 v0, ${vote.value} + invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->sendVote(I)V + """ + ) + } ?: throw fingerprint.exception + } + + // endregion + + // region Hook code for creation and cached lookup of text Spans. + + // Alternatively the hook can be made at the creation of Spans in TextComponentSpec, + // And it works in all situations except it fails to update the Span when the user dislikes, + // since the underlying (likes only) text did not change. + // This hook handles all situations, as it's where the created Spans are stored and later reused. + TextComponentConstructorFingerprint.result?.let { textConstructorResult -> + // Find the field name of the conversion context. + val conversionContextClassType = ConversionContextFingerprint.getResultOrThrow().classDef.type + val conversionContextField = textConstructorResult.classDef.fields.find { + it.type == conversionContextClassType + } ?: throw PatchException("Could not find conversion context field") + + TextComponentLookupFingerprint.resolve(context, textConstructorResult.classDef) + TextComponentLookupFingerprint.getResultOrThrow().mutableMethod.apply { + // Find the instruction for creating the text data object. + val textDataClassType = TextComponentDataFingerprint.getResultOrThrow().classDef.type + val insertIndex = indexOfFirstInstruction { + opcode == Opcode.NEW_INSTANCE && + getReference()?.type == textDataClassType + } + if (insertIndex < 0) throw PatchException("Could not find data creation instruction") + val tempRegister = getInstruction(insertIndex).registerA + + // Find the instruction that sets the span to an instance field. + // The instruction is only a few lines after the creation of the instance. + // The method has multiple iput-object instructions using a CharSequence, + // so verify the found instruction is in the expected location. + val putFieldInstruction = implementation!!.instructions + .subList(insertIndex, insertIndex + 20) + .find { + it.opcode == Opcode.IPUT_OBJECT && + it.getReference()?.type == "Ljava/lang/CharSequence;" + } ?: throw PatchException("Could not find put object instruction") + val charSequenceRegister = (putFieldInstruction as TwoRegisterInstruction).registerA + + addInstructions( + insertIndex, + """ + # Copy conversion context + move-object/from16 v$tempRegister, p0 + iget-object v$tempRegister, v$tempRegister, $conversionContextField + invoke-static {v$tempRegister, v$charSequenceRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; + move-result-object v$charSequenceRegister + """ + ) + } + } ?: throw TextComponentConstructorFingerprint.exception + + // endregion + + // region Hook for non-litho Short videos. + + ShortsTextViewFingerprint.result?.let { + it.mutableMethod.apply { + val patternResult = it.scanResult.patternScanResult!! + + // If the field is true, the TextView is for a dislike button. + val isDisLikesBooleanReference = getInstruction(patternResult.endIndex).reference + + val textViewFieldReference = // Like/Dislike button TextView field + getInstruction(patternResult.endIndex - 1).reference + + // 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. + // Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward. + val insertIndex = patternResult.startIndex + 6 + addInstructionsWithLabels( + insertIndex, + """ + # Check, if the TextView is for a dislike button + iget-boolean v0, p0, $isDisLikesBooleanReference + if-eqz v0, :is_like + + # Hook the TextView, if it is for the dislike button + iget-object v0, p0, $textViewFieldReference + invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->setShortsDislikes(Landroid/view/View;)Z + move-result v0 + if-eqz v0, :ryd_disabled + return-void + + :is_like + :ryd_disabled + nop + """ + ) + } + } ?: throw ShortsTextViewFingerprint.exception + + // endregion + + // region Hook for litho Shorts + + // Filter that parses the video id from the UI + LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) + + // Player response video id is needed to search for the video ids in Shorts litho components. + VideoIdPatch.injectPlayerResponseVideoId("$FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V") + + // endregion + + // region Hook old UI layout dislikes, for the older app spoofs used with spoof-app-version. + + DislikesOldLayoutTextViewFingerprint.result?.let { + it.mutableMethod.apply { + val startIndex = it.scanResult.patternScanResult!!.startIndex + + val resourceIdentifierRegister = getInstruction(startIndex).registerA + val textViewRegister = getInstruction(startIndex + 4).registerA + + addInstruction( + startIndex + 4, + "invoke-static {v$resourceIdentifierRegister, v$textViewRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setOldUILayoutDislikes(ILandroid/widget/TextView;)V" + ) + } + } ?: throw DislikesOldLayoutTextViewFingerprint.exception + + // endregion + + + // region Hook rolling numbers. + + // Do this last to allow patching old unsupported versions (if the user really wants), + // On older unsupported version this will fail to resolve and throw an exception, + // but everything will still work correctly anyway. + + RollingNumberSetterFingerprint.result?.let { + val dislikesIndex = it.scanResult.patternScanResult!!.endIndex + + it.mutableMethod.apply { + val insertIndex = 1 + + val charSequenceInstanceRegister = + getInstruction(0).registerA + val charSequenceFieldReference = + getInstruction(dislikesIndex).reference + + val registerCount = implementation!!.registerCount + + // This register is being overwritten, so it is free to use. + val freeRegister = registerCount - 1 + val conversionContextRegister = registerCount - parameters.size + 1 + + addInstructions( + insertIndex, + """ + iget-object v$freeRegister, v$charSequenceInstanceRegister, $charSequenceFieldReference + invoke-static {v$conversionContextRegister, v$freeRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onRollingNumberLoaded(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String; + move-result-object v$freeRegister + iput-object v$freeRegister, v$charSequenceInstanceRegister, $charSequenceFieldReference + """ + ) + } + } ?: throw RollingNumberSetterFingerprint.exception + + // Rolling Number text views use the measured width of the raw string for layout. + // Modify the measure text calculation to include the left drawable separator if needed. + RollingNumberMeasureAnimatedTextFingerprint.result?.also { + val scanResult = it.scanResult.patternScanResult!! + // Additional check to verify the opcodes are at the start of the method + if (scanResult.startIndex != 0) throw PatchException("Unexpected opcode location") + val endIndex = scanResult.endIndex + it.mutableMethod.apply { + val measuredTextWidthRegister = getInstruction(endIndex).registerA + + addInstructions( + endIndex + 1, + """ + invoke-static {p1, v$measuredTextWidthRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F + move-result v$measuredTextWidthRegister + """ + ) + } + } ?: throw RollingNumberMeasureAnimatedTextFingerprint.exception + + // Additional text measurement method. Used if YouTube decides not to animate the likes count + // and sometimes used for initial video load. + RollingNumberMeasureStaticLabelFingerprint.resolve(context, RollingNumberMeasureStaticLabelParentFingerprint.getResultOrThrow().classDef) + RollingNumberMeasureStaticLabelFingerprint.result?.also { + val measureTextIndex = it.scanResult.patternScanResult!!.startIndex + 1 + it.mutableMethod.apply { + val freeRegister = getInstruction(0).registerA + + addInstructions( + measureTextIndex + 1, + """ + move-result v$freeRegister + invoke-static {p1, v$freeRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F + """ + ) + } + } ?: throw RollingNumberMeasureStaticLabelFingerprint.exception + + // The rolling number Span is missing styling since it's initially set as a String. + // Modify the UI text view and use the styled like/dislike Span. + RollingNumberTextViewFingerprint.result?.let { + // Initial TextView is set in this method. + val initiallyCreatedTextViewMethod = it.mutableMethod + + // Videos less than 24 hours after uploaded, like counts will be updated in real time. + // Whenever like counts are updated, TextView is set in this method. + val realTimeUpdateTextViewMethod = + RollingNumberTextViewAnimationUpdateFingerprint.result?.mutableMethod + ?: throw RollingNumberTextViewAnimationUpdateFingerprint.exception + + arrayOf( + initiallyCreatedTextViewMethod, + realTimeUpdateTextViewMethod + ).forEach { insertMethod -> + insertMethod.apply { + val setTextIndex = indexOfFirstInstruction { + getReference()?.name == "setText" + } + + val textViewRegister = + getInstruction(setTextIndex).registerC + val textSpanRegister = + getInstruction(setTextIndex).registerD + + addInstructions( + setTextIndex, + """ + invoke-static {v$textViewRegister, v$textSpanRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; + move-result-object v$textSpanRegister + """ + ) + } + } + } ?: throw RollingNumberTextViewFingerprint.exception + + // endregion + + /** + * Add ReVanced Extended Settings + */ + SettingsPatch.addReVancedPreference("ryd_settings") + + SettingsPatch.updatePatchStatus("Return YouTube Dislike") + } + + private fun MethodFingerprint.toPatch(voteKind: Vote) = VotePatch(this, voteKind) + private data class VotePatch(val fingerprint: MethodFingerprint, val voteKind: Vote) + private enum class Vote(val value: Int) { + LIKE(1), + DISLIKE(-1), + REMOVE_LIKE(0) + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/ReturnYouTubeDislikeResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/ReturnYouTubeDislikeResourcePatch.kt new file mode 100644 index 0000000000..18ade5ed0d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/ReturnYouTubeDislikeResourcePatch.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.youtube.utils.returnyoutubedislike + +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.shared.patch.mapping.ResourceMappingPatch +import app.revanced.patches.youtube.utils.settings.SettingsPatch + +@Patch( + dependencies = [ + SettingsPatch::class + ] +) +internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() { + internal var oldUIDislikeId: Long = -1 + + override fun execute(context: ResourceContext) { + oldUIDislikeId = ResourceMappingPatch.resourceMappings.single { + it.type == "id" && it.name == "dislike_button" + }.id + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/ConversionContextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/ConversionContextFingerprint.kt new file mode 100644 index 0000000000..61e2eb6f4a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/ConversionContextFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object ConversionContextFingerprint : MethodFingerprint( + returnType = "Ljava/lang/String;", + parameters = listOf(), + strings = listOf( + ", widthConstraint=", + ", heightConstraint=", + ", templateLoggerFactory=", + ", rootDisposableContainer=", + // 18.37.36 and after this String is: ConversionContext{containerInternal= + // and before it is: ConversionContext{container= + // Use a partial string to match both. + "ConversionContext{container" + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/DislikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/DislikeFingerprint.kt similarity index 63% rename from src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/DislikeFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/DislikeFingerprint.kt index 0391882235..59003b2870 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/DislikeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/DislikeFingerprint.kt @@ -1,8 +1,8 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint -object DislikeFingerprint : MethodFingerprint( - returnType = "V", +internal object DislikeFingerprint : MethodFingerprint( + "V", strings = listOf("like/dislike") -) \ No newline at end of file +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt new file mode 100644 index 0000000000..8802dab3f2 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.utils.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch +import app.revanced.util.fingerprint.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object DislikesOldLayoutTextViewFingerprint : LiteralValueFingerprint( + returnType = "V", + parameters = listOf("L"), + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + opcodes = listOf( + Opcode.CONST, // resource identifier register + Opcode.INVOKE_VIRTUAL, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, // textview register + Opcode.GOTO, + ), + literalSupplier = { ReturnYouTubeDislikeResourcePatch.oldUIDislikeId } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/LikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/LikeFingerprint.kt similarity index 64% rename from src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/LikeFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/LikeFingerprint.kt index a89cad1434..35d2ebba57 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/LikeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/LikeFingerprint.kt @@ -1,8 +1,8 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint -object LikeFingerprint : MethodFingerprint( - returnType = "V", +internal object LikeFingerprint : MethodFingerprint( + "V", strings = listOf("like/like") -) \ No newline at end of file +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/RemoveLikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt similarity index 63% rename from src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/RemoveLikeFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt index 95d8b58a72..c8f0a15459 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/RemoveLikeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RemoveLikeFingerprint.kt @@ -1,8 +1,8 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint -object RemoveLikeFingerprint : MethodFingerprint( - returnType = "V", +internal object RemoveLikeFingerprint : MethodFingerprint( + "V", strings = listOf("like/removelike") -) \ No newline at end of file +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberMeasureAnimatedTextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberMeasureAnimatedTextFingerprint.kt new file mode 100644 index 0000000000..80702067a4 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberMeasureAnimatedTextFingerprint.kt @@ -0,0 +1,28 @@ +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object RollingNumberMeasureAnimatedTextFingerprint : MethodFingerprint( + returnType = "Lj\$/util/Optional;", + accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf( + "L", + "Ljava/lang/String;", + "L" + ), + opcodes = listOf( + Opcode.IGET, // First instruction of method + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.CONST_HIGH16, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.CONST_4, + Opcode.AGET, + Opcode.CONST_4, + Opcode.CONST_4, // Measured text width + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureStaticLabelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberMeasureStaticLabelFingerprint.kt similarity index 75% rename from src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureStaticLabelFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberMeasureStaticLabelFingerprint.kt index d1a8af72b9..1ca710a203 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureStaticLabelFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberMeasureStaticLabelFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint @@ -6,9 +6,9 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode /** - * Resolves to class found in [RollingNumberMeasureTextParentFingerprint]. + * Resolves to class found in [RollingNumberMeasureStaticLabelParentFingerprint]. */ -object RollingNumberMeasureStaticLabelFingerprint : MethodFingerprint( +internal object RollingNumberMeasureStaticLabelFingerprint : MethodFingerprint( returnType = "F", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("Ljava/lang/String;"), @@ -18,4 +18,4 @@ object RollingNumberMeasureStaticLabelFingerprint : MethodFingerprint( Opcode.MOVE_RESULT, Opcode.RETURN ) -) \ No newline at end of file +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureTextParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberMeasureStaticLabelParentFingerprint.kt similarity index 79% rename from src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureTextParentFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberMeasureStaticLabelParentFingerprint.kt index 18c2652c69..54c454f3ea 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureTextParentFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberMeasureStaticLabelParentFingerprint.kt @@ -1,12 +1,12 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags -object RollingNumberMeasureTextParentFingerprint : MethodFingerprint( +internal object RollingNumberMeasureStaticLabelParentFingerprint : MethodFingerprint( returnType = "Ljava/lang/String;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf(), strings = listOf("RollingNumberFontProperties{paint=") -) \ No newline at end of file +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberSetterFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberSetterFingerprint.kt similarity index 58% rename from src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberSetterFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberSetterFingerprint.kt index 560eee0b60..f482ee72f6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberSetterFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberSetterFingerprint.kt @@ -1,16 +1,12 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.Opcode -/** - * This fingerprint is compatible with YouTube v18.29.38+ - */ -object RollingNumberSetterFingerprint : MethodFingerprint( +internal object RollingNumberSetterFingerprint : MethodFingerprint( opcodes = listOf( - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.AND_INT_LIT8 + Opcode.INVOKE_DIRECT, + Opcode.IGET_OBJECT ), strings = listOf("RollingNumberType required properties missing! Need updateCount, fontName, color and fontSize.") -) \ No newline at end of file +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberTextViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberTextViewFingerprint.kt similarity index 77% rename from src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberTextViewFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberTextViewFingerprint.kt index ba8a76f274..4437897b04 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberTextViewFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/RollingNumberTextViewFingerprint.kt @@ -1,14 +1,11 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -/** - * This fingerprint is compatible with YouTube v18.32.39+ - */ -object RollingNumberTextViewFingerprint : MethodFingerprint( +internal object RollingNumberTextViewFingerprint : MethodFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("L", "F", "F"), @@ -20,7 +17,7 @@ object RollingNumberTextViewFingerprint : MethodFingerprint( Opcode.INVOKE_VIRTUAL, Opcode.RETURN_VOID ), - customFingerprint = custom@{ _, classDef -> + customFingerprint = { _, classDef -> classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;" } -) \ No newline at end of file +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/ShortsTextViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/ShortsTextViewFingerprint.kt new file mode 100644 index 0000000000..9fa284b495 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/ShortsTextViewFingerprint.kt @@ -0,0 +1,32 @@ +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object ShortsTextViewFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", + parameters = listOf("L", "L"), + opcodes = listOf( + Opcode.INVOKE_SUPER, // first instruction of method + Opcode.IF_NEZ, + null, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.SGET_OBJECT, // insertion point, must be after constructor call to parent class + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.CONST_4, + Opcode.IF_EQ, + Opcode.CONST_4, + Opcode.IF_EQ, + Opcode.RETURN_VOID, + Opcode.IGET_OBJECT, // TextView field + Opcode.IGET_BOOLEAN, // boolean field + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt similarity index 59% rename from src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentConstructorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt index 9ca52990b5..2f8485e2cc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentConstructorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/TextComponentConstructorFingerprint.kt @@ -1,11 +1,10 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags -object TextComponentConstructorFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PRIVATE or AccessFlags.CONSTRUCTOR, +internal object TextComponentConstructorFingerprint : MethodFingerprint( + accessFlags = AccessFlags.CONSTRUCTOR or AccessFlags.PRIVATE, strings = listOf("TextComponent") -) \ No newline at end of file +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/TextComponentDataFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/TextComponentDataFingerprint.kt new file mode 100644 index 0000000000..d1b8c2d1f6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/TextComponentDataFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object TextComponentDataFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + parameters = listOf("L", "L"), + strings = listOf("text"), + customFingerprint = { _, classDef -> + val fields = classDef.fields + fields.find { it.type == "Ljava/util/BitSet;" } != null && + fields.find { it.type == "[Ljava/lang/String;" } != null + } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentContextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/TextComponentLookupFingerprint.kt similarity index 55% rename from src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentContextFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/TextComponentLookupFingerprint.kt index a1fd89d03c..c94710ecc3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/TextComponentContextFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/fingerprints/TextComponentLookupFingerprint.kt @@ -1,18 +1,15 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints +package app.revanced.patches.youtube.utils.returnyoutubedislike.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -object TextComponentContextFingerprint : MethodFingerprint( +/** + * Resolves against the same class that [TextComponentConstructorFingerprint] resolves to. + */ +internal object TextComponentLookupFingerprint : MethodFingerprint( returnType = "L", accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL, parameters = listOf("L"), - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_BOOLEAN - ) -) \ No newline at end of file + strings = listOf("…") +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt deleted file mode 100644 index b4b9047080..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt +++ /dev/null @@ -1,180 +0,0 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.general - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -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.litho.LithoFilterPatch -import app.revanced.patches.youtube.utils.playerresponse.PlayerResponsePatch -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.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.oldlayout.ReturnYouTubeDislikeOldLayoutPatch -import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.ReturnYouTubeDislikeRollingNumberPatch -import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.ReturnYouTubeDislikeShortsPatch -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.patches.youtube.utils.videoid.general.VideoIdPatch -import app.revanced.util.exception -import app.revanced.util.getReference -import com.android.tools.smali.dexlib2.Opcode -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 - -@Patch( - name = "Return YouTube Dislike", - description = "Shows the dislike count of videos using the Return YouTube Dislike API.", - dependencies = [ - LithoFilterPatch::class, - PlayerResponsePatch::class, - ReturnYouTubeDislikeOldLayoutPatch::class, - ReturnYouTubeDislikeRollingNumberPatch::class, - ReturnYouTubeDislikeShortsPatch::class, - SettingsPatch::class, - VideoIdPatch::class - ], - compatiblePackages = [ - CompatiblePackage( - "com.google.android.youtube", - [ - "18.25.40", - "18.27.36", - "18.29.38", - "18.30.37", - "18.31.40", - "18.32.39", - "18.33.40", - "18.34.38", - "18.35.36", - "18.36.39", - "18.37.36", - "18.38.44", - "18.39.41", - "18.40.34", - "18.41.39", - "18.42.41", - "18.43.45", - "18.44.41", - "18.45.43", - "18.46.45", - "18.48.39", - "18.49.37", - "19.01.34", - "19.02.39", - "19.03.36", - "19.04.38", - "19.05.36", - "19.06.39", - "19.07.40", - "19.08.36", - "19.09.38", - "19.10.39", - "19.11.43", - "19.12.41", - "19.13.37", - "19.14.43", - "19.15.36", - "19.16.38" - ] - ) - ] -) -@Suppress("unused") -object ReturnYouTubeDislikePatch : BytecodePatch( - setOf( - DislikeFingerprint, - LikeFingerprint, - RemoveLikeFingerprint, - TextComponentConstructorFingerprint - ) -) { - override fun execute(context: BytecodeContext) { - listOf( - LikeFingerprint.toPatch(Vote.LIKE), - DislikeFingerprint.toPatch(Vote.DISLIKE), - RemoveLikeFingerprint.toPatch(Vote.REMOVE_LIKE) - ).forEach { (fingerprint, vote) -> - with(fingerprint.result ?: throw fingerprint.exception) { - mutableMethod.addInstructions( - 0, - """ - const/4 v0, ${vote.value} - invoke-static {v0}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->sendVote(I)V - """ - ) - } - } - - - TextComponentConstructorFingerprint.result?.let { parentResult -> - // Resolves fingerprints - TextComponentContextFingerprint.resolve(context, parentResult.classDef) - - TextComponentContextFingerprint.result?.let { - it.mutableMethod.apply { - val conversionContextFieldIndex = implementation!!.instructions.indexOfFirst { instruction -> - instruction.opcode == Opcode.IGET_OBJECT - && instruction.getReference()?.type == "Ljava/util/Map;" - } - 1 - val conversionContextFieldReference = - getInstruction(conversionContextFieldIndex).reference - - val charSequenceIndex = implementation!!.instructions.indexOfFirst { instruction -> - instruction.opcode == Opcode.IGET_OBJECT - && instruction.getReference()?.type == "Ljava/util/BitSet;" - } - 1 - val charSequenceRegister = getInstruction(charSequenceIndex).registerA - val freeRegister = getInstruction(charSequenceIndex).registerB - - addInstructions( - charSequenceIndex - 1, """ - 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 - """ - ) - } - } ?: throw TextComponentContextFingerprint.exception - } ?: throw TextComponentConstructorFingerprint.exception - - VideoIdPatch.injectCall("$INTEGRATIONS_RYD_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V") - VideoIdPatch.injectPlayerResponseVideoId("$INTEGRATIONS_RYD_CLASS_DESCRIPTOR->preloadVideoId(Ljava/lang/String;Z)V") - - if (SettingsPatch.upward1834) { - LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) - VideoIdPatch.injectPlayerResponseVideoId("$FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V") - } - - /** - * Add ReVanced Extended Settings - */ - SettingsPatch.addReVancedPreference("ryd_settings") - - SettingsPatch.updatePatchStatus("Return YouTube Dislike") - - } - - private const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR = - "$UTILS_PATH/ReturnYouTubeDislikePatch;" - - private const val FILTER_CLASS_DESCRIPTOR = - "$COMPONENTS_PATH/ReturnYouTubeDislikeFilterPatch;" - - private fun MethodFingerprint.toPatch(voteKind: Vote) = VotePatch(this, voteKind) - - private data class VotePatch(val fingerprint: MethodFingerprint, val voteKind: Vote) - - private enum class Vote(val value: Int) { - LIKE(1), - DISLIKE(-1), - REMOVE_LIKE(0) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/ReturnYouTubeDislikeOldLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/ReturnYouTubeDislikeOldLayoutPatch.kt deleted file mode 100644 index c114d0e9d0..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/ReturnYouTubeDislikeOldLayoutPatch.kt +++ /dev/null @@ -1,42 +0,0 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.oldlayout - -import app.revanced.patcher.data.BytecodeContext -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.annotation.Patch -import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DislikeButton -import app.revanced.patches.youtube.utils.returnyoutubedislike.oldlayout.fingerprints.ButtonTagFingerprint -import app.revanced.util.exception -import app.revanced.util.getWideLiteralInstructionIndex -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -@Patch(dependencies = [SharedResourceIdPatch::class]) -object ReturnYouTubeDislikeOldLayoutPatch : BytecodePatch( - setOf(ButtonTagFingerprint) -) { - override fun execute(context: BytecodeContext) { - - ButtonTagFingerprint.result?.let { - it.mutableMethod.apply { - val dislikeButtonIndex = getWideLiteralInstructionIndex(DislikeButton) - - val resourceIdentifierRegister = - getInstruction(dislikeButtonIndex).registerA - val textViewRegister = - getInstruction(dislikeButtonIndex + 4).registerA - - addInstruction( - dislikeButtonIndex + 4, - "invoke-static {v$resourceIdentifierRegister, v$textViewRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->setOldUILayoutDislikes(ILandroid/widget/TextView;)V" - ) - } - } ?: throw ButtonTagFingerprint.exception - - } - - private const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR = - "$UTILS_PATH/ReturnYouTubeDislikePatch;" -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/fingerprints/ButtonTagFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/fingerprints/ButtonTagFingerprint.kt deleted file mode 100644 index eba68deb7b..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/oldlayout/fingerprints/ButtonTagFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.oldlayout.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DislikeButton -import app.revanced.util.fingerprint.LiteralValueFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -object ButtonTagFingerprint : LiteralValueFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("L"), - literalSupplier = { DislikeButton } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/ReturnYouTubeDislikeRollingNumberPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/ReturnYouTubeDislikeRollingNumberPatch.kt deleted file mode 100644 index d39082fcc3..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/ReturnYouTubeDislikeRollingNumberPatch.kt +++ /dev/null @@ -1,181 +0,0 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber - -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.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.utils.fingerprints.RollingNumberTextViewAnimationUpdateFingerprint -import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH -import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberMeasureAnimatedTextFingerprint -import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberMeasureStaticLabelFingerprint -import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberMeasureTextParentFingerprint -import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberSetterFingerprint -import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberTextViewFingerprint -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.exception -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c -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.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.iface.reference.Reference - -@Patch(dependencies = [SettingsPatch::class]) -object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch( - setOf( - RollingNumberSetterFingerprint, - RollingNumberMeasureTextParentFingerprint, - RollingNumberTextViewFingerprint, - RollingNumberMeasureAnimatedTextFingerprint, - RollingNumberTextViewAnimationUpdateFingerprint - ) -) { - private const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR = - "$UTILS_PATH/ReturnYouTubeDislikePatch;" - - override fun execute(context: BytecodeContext) { - /** - * RollingNumber is applied to YouTube v18.41.39+. - * - * In order to maintain compatibility with YouTube v18.40.34 or previous versions, - * This patch is applied only to the version after YouTube v18.41.39 - */ - if (SettingsPatch.upward1841) { - - RollingNumberSetterFingerprint.result?.let { - it.mutableMethod.apply { - val rollingNumberClassIndex = it.scanResult.patternScanResult!!.startIndex - val rollingNumberClassReference = - getInstruction(rollingNumberClassIndex).reference - val rollingNumberClass = - context.findClass(rollingNumberClassReference.toString())!!.mutableClass - - lateinit var charSequenceFieldReference: Reference - - rollingNumberClass.methods.find { method -> method.name == "" } - ?.apply { - val rollingNumberFieldIndex = - implementation!!.instructions.indexOfFirst { instruction -> - instruction.opcode == Opcode.IPUT_OBJECT - } - charSequenceFieldReference = - getInstruction(rollingNumberFieldIndex).reference - } ?: throw PatchException("RollingNumberClass not found!") - - val insertIndex = rollingNumberClassIndex + 1 - - val charSequenceInstanceRegister = - getInstruction(rollingNumberClassIndex).registerA - - val registerCount = implementation!!.registerCount - - // This register is being overwritten, so it is free to use. - val freeRegister = registerCount - 1 - val conversionContextRegister = registerCount - parameters.size + 1 - - addInstructions( - insertIndex, """ - iget-object v$freeRegister, v$charSequenceInstanceRegister, $charSequenceFieldReference - invoke-static {v$conversionContextRegister, v$freeRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onRollingNumberLoaded(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String; - move-result-object v$freeRegister - iput-object v$freeRegister, v$charSequenceInstanceRegister, $charSequenceFieldReference - """ - ) - } - } ?: throw RollingNumberSetterFingerprint.exception - - // Rolling Number text views use the measured width of the raw string for layout. - // Modify the measure text calculation to include the left drawable separator if needed. - RollingNumberMeasureAnimatedTextFingerprint.result?.let { - it.mutableMethod.apply { - val endIndex = it.scanResult.patternScanResult!!.endIndex - val measuredTextWidthIndex = endIndex - 2 - val measuredTextWidthRegister = - getInstruction(measuredTextWidthIndex).registerA - - addInstructions( - endIndex + 1, """ - invoke-static {p1, v$measuredTextWidthRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F - move-result v$measuredTextWidthRegister - """ - ) - - val ifGeIndex = implementation!!.instructions.indexOfFirst { instruction -> - instruction.opcode == Opcode.IF_GE - } - val ifGeInstruction = getInstruction(ifGeIndex) - - removeInstruction(ifGeIndex) - addInstructionsWithLabels( - ifGeIndex, """ - if-ge v${ifGeInstruction.registerA}, v${ifGeInstruction.registerB}, :jump - """, ExternalLabel("jump", getInstruction(endIndex)) - ) - } - } ?: throw RollingNumberMeasureAnimatedTextFingerprint.exception - - RollingNumberMeasureTextParentFingerprint.result?.classDef?.let { parentClassDef -> - RollingNumberMeasureStaticLabelFingerprint.resolve(context, parentClassDef) - - // Additional text measurement method. Used if YouTube decides not to animate the likes count - // and sometimes used for initial video load. - RollingNumberMeasureStaticLabelFingerprint.result?.let { - it.mutableMethod.apply { - val measureTextIndex = it.scanResult.patternScanResult!!.startIndex + 1 - val freeRegister = getInstruction(0).registerA - - addInstructions( - measureTextIndex + 1, """ - move-result v$freeRegister - invoke-static {p1, v$freeRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onRollingNumberMeasured(Ljava/lang/String;F)F - """ - ) - } - } ?: throw RollingNumberMeasureStaticLabelFingerprint.exception - } ?: throw RollingNumberMeasureTextParentFingerprint.exception - - // The rolling number Span is missing styling since it's initially set as a String. - // Modify the UI text view and use the styled like/dislike Span. - RollingNumberTextViewFingerprint.result?.let { - // Initial TextView is set in this method. - val initiallyCreatedTextViewMethod = it.mutableMethod - - // Video less than 24 hours after uploaded, like counts will be updated in real time. - // Whenever like counts are updated, TextView is set in this method. - val realTimeUpdateTextViewMethod = it.mutableClass.methods.find { method -> - method.parameterTypes.first() == "Landroid/graphics/Bitmap;" - } ?: throw PatchException("Failed to find realTimeUpdateTextViewMethod") - - arrayOf( - initiallyCreatedTextViewMethod, - realTimeUpdateTextViewMethod - ).forEach { insertMethod -> - insertMethod.apply { - val setTextIndex = - implementation!!.instructions.indexOfFirst { instruction -> - ((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "setText" - } - val textViewRegister = - getInstruction(setTextIndex).registerC - val textSpanRegister = - getInstruction(setTextIndex).registerD - - addInstructions( - setTextIndex, """ - invoke-static {v$textViewRegister, v$textSpanRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->updateRollingNumber(Landroid/widget/TextView;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; - move-result-object v$textSpanRegister - """ - ) - } - } - } ?: throw RollingNumberTextViewFingerprint.exception - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureAnimatedTextFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureAnimatedTextFingerprint.kt deleted file mode 100644 index 8705d27d6c..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/rollingnumber/fingerprints/RollingNumberMeasureAnimatedTextFingerprint.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction - -/** - * Compatible with YouTube v18.30.xx to v18.49.xx - */ -object RollingNumberMeasureAnimatedTextFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.ADD_FLOAT_2ADDR, // measuredTextWidth - Opcode.ADD_INT_LIT8, - Opcode.GOTO - ), - customFingerprint = custom@{ methodDef, _ -> - if (methodDef.implementation == null) - return@custom false - - for (instruction in methodDef.implementation!!.instructions) { - if (instruction.opcode != Opcode.INVOKE_VIRTUAL) - continue - - val invokeInstruction = instruction as ReferenceInstruction - if (!invokeInstruction.reference.toString().endsWith("Landroid/text/TextPaint;->measureText([CII)F")) - continue - - return@custom true - } - return@custom false - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/ReturnYouTubeDislikeShortsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/ReturnYouTubeDislikeShortsPatch.kt deleted file mode 100644 index 54dc788ebd..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/ReturnYouTubeDislikeShortsPatch.kt +++ /dev/null @@ -1,108 +0,0 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.shorts - -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.addInstructionsWithLabels -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.annotation.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH -import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints.IncognitoFingerprint -import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints.ShortsTextViewFingerprint -import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints.TextComponentSpecFingerprint -import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.exception -import app.revanced.util.getTargetIndexReversed -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 - -@Patch(dependencies = [SettingsPatch::class]) -object ReturnYouTubeDislikeShortsPatch : BytecodePatch( - setOf( - IncognitoFingerprint, - ShortsTextViewFingerprint, - TextComponentSpecFingerprint - ) -) { - private const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR = - "$UTILS_PATH/ReturnYouTubeDislikePatch;" - - override fun execute(context: BytecodeContext) { - ShortsTextViewFingerprint.result?.let { - it.mutableMethod.apply { - val startIndex = it.scanResult.patternScanResult!!.startIndex - - val isDisLikesBooleanIndex = getTargetIndexReversed(startIndex, Opcode.IGET_BOOLEAN) - val textViewFieldIndex = getTargetIndexReversed(startIndex, Opcode.IGET_OBJECT) - - // If the field is true, the TextView is for a dislike button. - val isDisLikesBooleanReference = - getInstruction(isDisLikesBooleanIndex).reference - - val textViewFieldReference = // Like/Dislike button TextView field - getInstruction(textViewFieldIndex).reference - - // 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. - // Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward. - val insertIndex = implementation!!.instructions.indexOfFirst { instruction -> - instruction.opcode == Opcode.CHECK_CAST - } + 1 - - addInstructionsWithLabels( - insertIndex, """ - # Check, if the TextView is for a dislike button - iget-boolean v0, p0, $isDisLikesBooleanReference - if-eqz v0, :ryd_disabled - - # Hook the TextView, if it is for the dislike button - iget-object v0, p0, $textViewFieldReference - invoke-static {v0}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->setShortsDislikes(Landroid/view/View;)Z - move-result v0 - if-eqz v0, :ryd_disabled - return-void - """, ExternalLabel("ryd_disabled", getInstruction(insertIndex)) - ) - } - } ?: throw ShortsTextViewFingerprint.exception - - if (SettingsPatch.upward1834) { - TextComponentSpecFingerprint.result?.let { - it.mutableMethod.apply { - val insertIndex = it.scanResult.patternScanResult!!.startIndex - - val charSequenceRegister = - getInstruction(insertIndex).registerC - val conversionContextRegister = - getInstruction(0).registerA - - val replaceReference = - getInstruction(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) - } - } ?: throw TextComponentSpecFingerprint.exception - - IncognitoFingerprint.result?.let { - it.mutableMethod.apply { - addInstruction( - 1, - "sput-boolean p4, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->isIncognito:Z" - ) - } - } ?: throw IncognitoFingerprint.exception - } - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/IncognitoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/IncognitoFingerprint.kt deleted file mode 100644 index 8f54bd0bda..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/IncognitoFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - -object IncognitoFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("${'$'}AutoValue_AccountIdentity;") } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/ShortsTextViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/ShortsTextViewFingerprint.kt deleted file mode 100644 index 08095a23f1..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/ShortsTextViewFingerprint.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -object ShortsTextViewFingerprint : MethodFingerprint( - returnType = "V", - parameters = listOf("L", "L"), - opcodes = listOf( - Opcode.IF_EQZ, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.GOTO, - Opcode.IGET, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.SGET_OBJECT, - Opcode.IF_NE, - Opcode.IGET, - Opcode.AND_INT_LIT8, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.GOTO, - Opcode.IGET, - Opcode.AND_INT_LIT8, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ), - customFingerprint = custom@{ _, classDef -> - classDef.methods.count() == 3 - } -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/TextComponentSpecFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/TextComponentSpecFingerprint.kt deleted file mode 100644 index 059965bb97..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/shorts/fingerprints/TextComponentSpecFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -object TextComponentSpecFingerprint : MethodFingerprint( - returnType = "Ljava/lang/CharSequence;", - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - null, // Opcode.CONST_4 or Opcode.MOVE - Opcode.INVOKE_INTERFACE_RANGE - ), - strings = listOf("Failed to set PB Style Run Extension in TextComponentSpec. Extension id: %s") -) \ No newline at end of file