From c82ccb59955d7663a5be20338b4b5c9b7601195c Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sun, 30 Apr 2023 23:41:29 +0400 Subject: [PATCH] fix(youtube/return-youtube-dislike): support older UI layouts (#2031) --- .../DislikesOldLayoutTextViewFingerprint.kt | 28 +++++++++++++++++++ .../fingerprints/LikeFingerprint.kt | 5 +--- .../patch/ReturnYouTubeDislikePatch.kt | 27 ++++++++++++++---- .../ReturnYouTubeDislikeResourcePatch.kt | 9 ++++++ 4 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt new file mode 100644 index 000000000..29ab1564d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/DislikesOldLayoutTextViewFingerprint.kt @@ -0,0 +1,28 @@ +package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.youtube.layout.returnyoutubedislike.resource.patch.ReturnYouTubeDislikeResourcePatch +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.WideLiteralInstruction + +object DislikesOldLayoutTextViewFingerprint : MethodFingerprint( + returnType = "V", + parameters = listOf("L"), + access = 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, + ), + customFingerprint = { methodDef -> + methodDef.implementation?.instructions?.any { instruction -> + instruction.opcode.ordinal == Opcode.CONST.ordinal && + (instruction as? WideLiteralInstruction)?.wideLiteral == ReturnYouTubeDislikeResourcePatch.oldUIDislikeId + } == true + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt index 5761a395e..53a9c0e89 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/fingerprints/LikeFingerprint.kt @@ -1,11 +1,8 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints -import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint - -@FuzzyPatternScanMethod(2) object LikeFingerprint : MethodFingerprint( "V", - strings = listOf("like/like") + strings = listOf("like/like") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt index 0f5ff3c88..1686c7996 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/patch/ReturnYouTubeDislikePatch.kt @@ -7,6 +7,7 @@ import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.toMethodWalker import app.revanced.patcher.extensions.MethodFingerprintExtensions.name +import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.instruction import app.revanced.patcher.extensions.replaceInstruction @@ -48,6 +49,7 @@ class ReturnYouTubeDislikePatch : BytecodePatch( listOf( TextComponentConstructorFingerprint, ShortsTextComponentParentFingerprint, + DislikesOldLayoutTextViewFingerprint, LikeFingerprint, DislikeFingerprint, RemoveLikeFingerprint, @@ -56,7 +58,7 @@ class ReturnYouTubeDislikePatch : BytecodePatch( override fun execute(context: BytecodeContext): PatchResult { // region Inject newVideoLoaded event handler to update dislikes when a new video is loaded. - VideoIdPatch.injectCall("$INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V") + VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V") // endregion @@ -72,7 +74,7 @@ class ReturnYouTubeDislikePatch : BytecodePatch( 0, """ const/4 v0, ${vote.value} - invoke-static {v0}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->sendVote(I)V + invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->sendVote(I)V """ ) } ?: return PatchResultError("Failed to find ${fingerprint.name} method.") @@ -120,7 +122,7 @@ class ReturnYouTubeDislikePatch : BytecodePatch( addInstructions( insertIndex + 1, """ iget-object v$contextRegister, v$contextRegister, $conversionContextFieldReference # copy obfuscated context field into free register - invoke-static {v$contextRegister, v$atomicReferenceRegister, v$charSequenceRegister}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; + invoke-static {v$contextRegister, v$atomicReferenceRegister, v$charSequenceRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; move-result-object v$charSequenceRegister move-object v${moveCharSequenceInstruction.registerA}, v${charSequenceRegister} # original instruction at the insertion point """ @@ -164,11 +166,26 @@ class ReturnYouTubeDislikePatch : BytecodePatch( // 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 = (instruction(startIndex) as OneRegisterInstruction).registerA + val textViewRegister = (instruction(startIndex + 4) as OneRegisterInstruction).registerA + addInstruction(startIndex + 4, + "invoke-static {v$resourceIdentifierRegister, v$textViewRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->setOldUILayoutDislikes(ILandroid/widget/TextView;)V" + ) + } + } ?: return DislikesOldLayoutTextViewFingerprint.toErrorResult() + + // endregion + return PatchResultSuccess() } private companion object { - const val INTEGRATIONS_PATCH_CLASS_DESCRIPTOR = + const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;" private fun MethodFingerprint.toPatch(voteKind: Vote) = VotePatch(this, voteKind) @@ -182,7 +199,7 @@ class ReturnYouTubeDislikePatch : BytecodePatch( private fun MutableMethod.insertShorts(index: Int, register: Int) { addInstructions( index, """ - invoke-static {v$register}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onShortsComponentCreated(Landroid/text/Spanned;)Landroid/text/Spanned; + invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->onShortsComponentCreated(Landroid/text/Spanned;)Landroid/text/Spanned; move-result-object v$register """ ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt index 16eaf3a26..41e8eb34a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/resource/patch/ReturnYouTubeDislikeResourcePatch.kt @@ -8,6 +8,7 @@ import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotations.DependsOn +import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.settings.preference.impl.Preference import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.youtube.layout.returnyoutubedislike.annotations.ReturnYouTubeDislikeCompatibility @@ -20,6 +21,10 @@ import app.revanced.util.resources.ResourceUtils.mergeStrings @ReturnYouTubeDislikeCompatibility @Version("0.0.1") class ReturnYouTubeDislikeResourcePatch : ResourcePatch { + companion object { + internal var oldUIDislikeId: Long = -1 + } + override fun execute(context: ResourceContext): PatchResult { val youtubePackage = "com.google.android.youtube" SettingsPatch.addPreference( @@ -36,6 +41,10 @@ class ReturnYouTubeDislikeResourcePatch : ResourcePatch { // merge strings context.mergeStrings("returnyoutubedislike/host/values/strings.xml") + oldUIDislikeId = ResourceMappingPatch.resourceMappings.single { + it.type == "id" && it.name == "dislike_button" + }.id + return PatchResultSuccess() } } \ No newline at end of file