From a47ee38b1cdd974a959008006ecaf58917addc60 Mon Sep 17 00:00:00 2001 From: 1fexd <58902674+1fexd@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:28:30 +0200 Subject: [PATCH] feat(Sync for Reddit): Add `Fix video downloads` patch (#3739) Co-authored-by: oSumAtrIX --- api/revanced-patches.api | 6 ++ .../fix/video/FixVideoDownloadsPatch.kt | 62 +++++++++++++++++++ ...seRedditVideoNetworkResponseFingerprint.kt | 16 +++++ 3 files changed, 84 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/fingerprints/ParseRedditVideoNetworkResponseFingerprint.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 74523ce8c..49822b6f9 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -840,6 +840,12 @@ public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/u public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch; + 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/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch { public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch; } diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch.kt new file mode 100644 index 000000000..b228025c8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch.kt @@ -0,0 +1,62 @@ +package app.revanced.patches.reddit.customclients.syncforreddit.fix.video + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.reddit.customclients.syncforreddit.fix.video.fingerprints.ParseRedditVideoNetworkResponseFingerprint +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c + +@Patch( + name = "Fix video downloads", + description = "Fixes a bug in Sync's MPD parser resulting in only the audio-track being saved.", + compatiblePackages = [ + CompatiblePackage("com.laurencedawson.reddit_sync"), + CompatiblePackage("com.laurencedawson.reddit_sync.pro"), + CompatiblePackage("com.laurencedawson.reddit_sync.dev"), + ], + requiresIntegrations = true, +) +@Suppress("unused") +object FixVideoDownloadsPatch : BytecodePatch( + fingerprints = setOf(ParseRedditVideoNetworkResponseFingerprint), +) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/syncforreddit/FixRedditVideoDownloadPatch;" + private const val GET_LINKS_METHOD = "getLinks([B)[Ljava/lang/String;" + + override fun execute(context: BytecodeContext) { + ParseRedditVideoNetworkResponseFingerprint.resultOrThrow().let { + val scanResult = it.scanResult.patternScanResult!! + val newInstanceIndex = scanResult.startIndex + val invokeDirectIndex = scanResult.endIndex - 1 + + val buildResponseInstruction = it.mutableMethod.getInstruction(invokeDirectIndex) + + it.mutableMethod.addInstructions( + newInstanceIndex + 1, + """ + # Get byte array from response. + iget-object v2, p1, Lcom/android/volley/NetworkResponse;->data:[B + + # Parse the videoUrl and audioUrl from the byte array. + invoke-static { v2 }, $INTEGRATIONS_CLASS_DESCRIPTOR->$GET_LINKS_METHOD + move-result-object v2 + + # Get videoUrl (Index 0). + const/4 v5, 0x0 + aget-object v${buildResponseInstruction.registerE}, v2, v5 + + # Get audioUrl (Index 1). + const/4 v6, 0x1 + aget-object v${buildResponseInstruction.registerF}, v2, v6 + + # Register E and F are used to build the response. + """, + ) + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/fingerprints/ParseRedditVideoNetworkResponseFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/fingerprints/ParseRedditVideoNetworkResponseFingerprint.kt new file mode 100644 index 000000000..1a06cd54d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/fix/video/fingerprints/ParseRedditVideoNetworkResponseFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.reddit.customclients.syncforreddit.fix.video.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +internal object ParseRedditVideoNetworkResponseFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.NEW_INSTANCE, + Opcode.IGET_OBJECT, + Opcode.INVOKE_DIRECT, + Opcode.CONST_WIDE_32 + ), + customFingerprint = { methodDef, classDef -> + classDef.sourceFile == "RedditVideoRequest.java" && methodDef.name == "parseNetworkResponse" + } +)