Skip to content

Commit 3343b5c

Browse files
committed
feat(X): Add Unlock downloads patch
1 parent 1bf9582 commit 3343b5c

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

api/revanced-patches.api

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,12 @@ public final class app/revanced/patches/twitch/misc/settings/SettingsResourcePat
10651065
public static final field INSTANCE Lapp/revanced/patches/twitch/misc/settings/SettingsResourcePatch;
10661066
}
10671067

1068+
public final class app/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch : app/revanced/patcher/patch/BytecodePatch {
1069+
public static final field INSTANCE Lapp/revanced/patches/twitter/interaction/downloads/UnlockDownloadsPatch;
1070+
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
1071+
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
1072+
}
1073+
10681074
public final class app/revanced/patches/twitter/layout/viewcount/HideViewCountPatch : app/revanced/patcher/patch/BytecodePatch {
10691075
public static final field INSTANCE Lapp/revanced/patches/twitter/layout/viewcount/HideViewCountPatch;
10701076
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package app.revanced.patches.twitter.interaction.downloads
2+
3+
import app.revanced.patcher.data.BytecodeContext
4+
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
5+
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
6+
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
7+
import app.revanced.patcher.fingerprint.MethodFingerprint
8+
import app.revanced.patcher.fingerprint.MethodFingerprintResult
9+
import app.revanced.patcher.patch.BytecodePatch
10+
import app.revanced.patcher.patch.annotation.CompatiblePackage
11+
import app.revanced.patcher.patch.annotation.Patch
12+
import app.revanced.patches.twitter.interaction.downloads.fingerprints.ConstructMediaOptionsSheetFingerprint
13+
import app.revanced.patches.twitter.interaction.downloads.fingerprints.ShowDownloadVideoUpsellBottomSheetFingerprint
14+
import app.revanced.util.exception
15+
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
16+
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
17+
18+
@Patch(
19+
name = "Unlock downloads",
20+
description = "Unlocks the ability to download any video.",
21+
compatiblePackages = [CompatiblePackage("com.twitter.android")]
22+
)
23+
@Suppress("unused")
24+
object UnlockDownloadsPatch : BytecodePatch(
25+
setOf(ConstructMediaOptionsSheetFingerprint, ShowDownloadVideoUpsellBottomSheetFingerprint)
26+
) {
27+
override fun execute(context: BytecodeContext) {
28+
fun MethodFingerprint.patch(getRegisterAndIndex: MethodFingerprintResult.() -> Pair<Int, Int>) = result?.let {
29+
getRegisterAndIndex(it).let { (index, register) ->
30+
it.mutableMethod.addInstruction(index, "const/4 v$register, 0x1")
31+
}
32+
} ?: throw exception
33+
34+
// Allow downloads for non-premium users.
35+
ShowDownloadVideoUpsellBottomSheetFingerprint.patch {
36+
val checkIndex = scanResult.patternScanResult!!.startIndex
37+
val register = mutableMethod.getInstruction<OneRegisterInstruction>(checkIndex).registerA
38+
39+
checkIndex to register
40+
}
41+
42+
// Force show the download menu item.
43+
ConstructMediaOptionsSheetFingerprint.patch {
44+
val showDownloadButtonIndex = mutableMethod.getInstructions().lastIndex - 1
45+
val register = mutableMethod.getInstruction<TwoRegisterInstruction>(showDownloadButtonIndex).registerA
46+
47+
showDownloadButtonIndex to register
48+
}
49+
}
50+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package app.revanced.patches.twitter.interaction.downloads.fingerprints
2+
3+
import app.revanced.patcher.extensions.or
4+
import app.revanced.patcher.fingerprint.MethodFingerprint
5+
import com.android.tools.smali.dexlib2.AccessFlags
6+
7+
8+
internal object ConstructMediaOptionsSheetFingerprint : MethodFingerprint(
9+
returnType = "V",
10+
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
11+
strings = listOf("captionsState")
12+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package app.revanced.patches.twitter.interaction.downloads.fingerprints
2+
3+
import app.revanced.patcher.fingerprint.MethodFingerprint
4+
import com.android.tools.smali.dexlib2.Opcode
5+
6+
internal object ShowDownloadVideoUpsellBottomSheetFingerprint : MethodFingerprint(
7+
returnType = "Z",
8+
strings = listOf("variantToDownload.url"),
9+
opcodes = listOf(Opcode.IF_EQZ)
10+
)

0 commit comments

Comments
 (0)