Compare commits

...

13 Commits

Author SHA1 Message Date
semantic-release-bot
651e34b997 chore: Release v4.17.0-dev.10 [skip ci]
# [4.17.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.9...v4.17.0-dev.10) (2024-10-17)

### Features

* **Facebook:** Add `Hide sponsored stories` patch ([#3627](https://github.com/ReVanced/revanced-patches/issues/3627)) ([fc7644d](fc7644d3b7))
2024-10-17 15:39:04 +00:00
PantlessCoding
fc7644d3b7 feat(Facebook): Add Hide sponsored stories patch (#3627)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-10-17 17:36:35 +02:00
semantic-release-bot
061ebcb7c6 chore: Release v4.17.0-dev.9 [skip ci]
# [4.17.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.8...v4.17.0-dev.9) (2024-10-17)

### Features

* **Sync for Reddit:** Add `Fix video downloads` patch ([#3739](https://github.com/ReVanced/revanced-patches/issues/3739)) ([38e7884](38e7884d17))
2024-10-17 15:30:41 +00:00
1fexd
38e7884d17 feat(Sync for Reddit): Add Fix video downloads patch (#3739)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-10-17 17:28:30 +02:00
semantic-release-bot
64680c718b chore: Release v4.17.0-dev.8 [skip ci]
# [4.17.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.7...v4.17.0-dev.8) (2024-10-17)

### Features

* **Twitter:** Add `Change link sharing domain` patch ([#3753](https://github.com/ReVanced/revanced-patches/issues/3753)) ([0077028](007702825b))
2024-10-17 15:26:18 +00:00
Alex
007702825b feat(Twitter): Add Change link sharing domain patch (#3753)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-10-17 17:24:06 +02:00
semantic-release-bot
596c2b0f8d chore: Release v4.17.0-dev.7 [skip ci]
# [4.17.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.6...v4.17.0-dev.7) (2024-10-17)

### Bug Fixes

* **Twitter - Unlock downloads:** Make it work with latest versions ([#3782](https://github.com/ReVanced/revanced-patches/issues/3782)) ([773fd81](773fd81dfd))
* **YouTube - Spoof video streams:** Fix playback for Android VR by removing invalid body as well ([#3769](https://github.com/ReVanced/revanced-patches/issues/3769)) ([68b61b4](68b61b4725))
2024-10-17 15:21:25 +00:00
Alex
773fd81dfd fix(Twitter - Unlock downloads): Make it work with latest versions (#3782) 2024-10-17 17:18:48 +02:00
oSumAtrIX
68b61b4725 fix(YouTube - Spoof video streams): Fix playback for Android VR by removing invalid body as well (#3769) 2024-10-17 17:16:45 +02:00
semantic-release-bot
10efb20e35 chore: Release v4.17.0-dev.6 [skip ci]
# [4.17.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.5...v4.17.0-dev.6) (2024-10-14)

### Features

* **YouTube - Hide Shorts components:** Add option to hide `Use template`, `Upcoming`, `Green screen` buttons ([#3752](https://github.com/ReVanced/revanced-patches/issues/3752)) ([d5a1368](d5a13684f6))
2024-10-14 12:13:04 +00:00
MarcaD
d5a13684f6 feat(YouTube - Hide Shorts components): Add option to hide Use template, Upcoming, Green screen buttons (#3752) 2024-10-14 14:10:53 +02:00
semantic-release-bot
e2dd1bdaf3 chore: Release v4.17.0-dev.5 [skip ci]
# [4.17.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.4...v4.17.0-dev.5) (2024-10-07)

### Features

* **Backdrops - Pro unlock:** Support latest versions by removing version constraint ([98c33f0](98c33f03dd))
2024-10-07 20:58:34 +00:00
KAZI MMT
98c33f03dd feat(Backdrops - Pro unlock): Support latest versions by removing version constraint 2024-10-07 22:56:31 +02:00
19 changed files with 444 additions and 8 deletions

View File

@@ -1,3 +1,46 @@
# [4.17.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.9...v4.17.0-dev.10) (2024-10-17)
### Features
* **Facebook:** Add `Hide sponsored stories` patch ([#3627](https://github.com/ReVanced/revanced-patches/issues/3627)) ([214c72b](https://github.com/ReVanced/revanced-patches/commit/214c72baeb7f87f21cd2ca34301ab11fa0ff1a4f))
# [4.17.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.8...v4.17.0-dev.9) (2024-10-17)
### Features
* **Sync for Reddit:** Add `Fix video downloads` patch ([#3739](https://github.com/ReVanced/revanced-patches/issues/3739)) ([a47ee38](https://github.com/ReVanced/revanced-patches/commit/a47ee38b1cdd974a959008006ecaf58917addc60))
# [4.17.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.7...v4.17.0-dev.8) (2024-10-17)
### Features
* **Twitter:** Add `Change link sharing domain` patch ([#3753](https://github.com/ReVanced/revanced-patches/issues/3753)) ([9269a07](https://github.com/ReVanced/revanced-patches/commit/9269a076b674ecdcf478bca842238f6e30869f44))
# [4.17.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.6...v4.17.0-dev.7) (2024-10-17)
### Bug Fixes
* **Twitter - Unlock downloads:** Make it work with latest versions ([#3782](https://github.com/ReVanced/revanced-patches/issues/3782)) ([5189122](https://github.com/ReVanced/revanced-patches/commit/5189122006b0f72d5bfb50422021c3b0f3a9ae4a))
* **YouTube - Spoof video streams:** Fix playback for Android VR by removing invalid body as well ([#3769](https://github.com/ReVanced/revanced-patches/issues/3769)) ([5150a15](https://github.com/ReVanced/revanced-patches/commit/5150a15ad4ca73a747f0a89f933db7f2d686ec2d))
# [4.17.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.5...v4.17.0-dev.6) (2024-10-14)
### Features
* **YouTube - Hide Shorts components:** Add option to hide `Use template`, `Upcoming`, `Green screen` buttons ([#3752](https://github.com/ReVanced/revanced-patches/issues/3752)) ([f71c406](https://github.com/ReVanced/revanced-patches/commit/f71c4068bc646d02954b59fac4756f1419c55dbe))
# [4.17.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.4...v4.17.0-dev.5) (2024-10-07)
### Features
* **Backdrops - Pro unlock:** Support latest versions by removing version constraint ([a62b506](https://github.com/ReVanced/revanced-patches/commit/a62b50691c49d1ce529a7c9c4e49da0d0dd46df2))
# [4.17.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.3...v4.17.0-dev.4) (2024-10-06)

View File

@@ -263,6 +263,12 @@ public final class app/revanced/patches/duolingo/debug/EnableDebugMenuPatch : ap
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}
public final class app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch;
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/facebook/ads/story/HideStoryAdsPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/facebook/ads/story/HideStoryAdsPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
@@ -840,6 +846,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;
}
@@ -1490,6 +1502,12 @@ public final class app/revanced/patches/twitter/misc/hook/patch/recommendation/H
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/hook/patch/recommendation/HideRecommendedUsersPatch;
}
public final class app/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch;
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/twitter/misc/links/OpenLinksWithAppChooserPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/links/OpenLinksWithAppChooserPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 4.17.0-dev.4
version = 4.17.0-dev.10

View File

@@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Pro unlock",
compatiblePackages = [CompatiblePackage("com.backdrops.wallpapers", ["4.52"])]
compatiblePackages = [CompatiblePackage("com.backdrops.wallpapers")]
)
@Suppress("unused")
object ProUnlockPatch : BytecodePatch(
@@ -34,4 +34,4 @@ object ProUnlockPatch : BytecodePatch(
} ?: throw ProUnlockFingerprint.exception
}
}
}

View File

@@ -0,0 +1,96 @@
package app.revanced.patches.facebook.ads.mainfeed
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.or
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.facebook.ads.mainfeed.fingerprints.BaseModelMapperFingerprint
import app.revanced.patches.facebook.ads.mainfeed.fingerprints.GetSponsoredDataModelTemplateFingerprint
import app.revanced.patches.facebook.ads.mainfeed.fingerprints.GetStoryVisibilityFingerprint
import app.revanced.util.exception
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
@Patch(
name = "Hide 'Sponsored Stories'",
compatiblePackages = [CompatiblePackage("com.facebook.katana")],
)
@Suppress("unused")
object HideSponsoredStoriesPatch : BytecodePatch(
setOf(GetStoryVisibilityFingerprint, GetSponsoredDataModelTemplateFingerprint, BaseModelMapperFingerprint),
) {
private const val GRAPHQL_STORY_TYPE = "Lcom/facebook/graphql/model/GraphQLStory;"
override fun execute(context: BytecodeContext) {
GetStoryVisibilityFingerprint.result?.apply {
val sponsoredDataModelTemplateMethod = GetSponsoredDataModelTemplateFingerprint.resultOrThrow().method
val baseModelMapperMethod = BaseModelMapperFingerprint.resultOrThrow().method
val baseModelWithTreeType = baseModelMapperMethod.returnType
// The "SponsoredDataModelTemplate" methods has the ids in its body to extract sponsored data
// from GraphQL models, but targets the wrong derived type of "BaseModelWithTree". Since those ids
// could change in future version, we need to extract them and call the base implementation directly.
val getSponsoredDataHelperMethod = ImmutableMethod(
classDef.type,
"getSponsoredData",
listOf(ImmutableMethodParameter(GRAPHQL_STORY_TYPE, null, null)),
baseModelWithTreeType,
AccessFlags.PRIVATE or AccessFlags.STATIC,
null,
null,
MutableMethodImplementation(4),
).toMutable().apply {
// Extract the ids of the original method. These ids seem to correspond to model types for
// GraphQL data structure. They are then fed to a method of BaseModelWithTree that populate
// and cast the requested GraphQL subtype. The Ids are found in the two first "CONST" instructions.
val constInstructions = sponsoredDataModelTemplateMethod.implementation!!.instructions
.asSequence()
.filterIsInstance<Instruction31i>()
.take(2)
.toList()
val storyTypeId = constInstructions[0].narrowLiteral
val sponsoredDataTypeId = constInstructions[1].narrowLiteral
addInstructions(
"""
const-class v2, $baseModelWithTreeType
const v1, $storyTypeId
const v0, $sponsoredDataTypeId
invoke-virtual {p0, v2, v1, v0}, $baseModelMapperMethod
move-result-object v0
check-cast v0, $baseModelWithTreeType
return-object v0
""",
)
}
mutableClass.methods.add(getSponsoredDataHelperMethod)
// Check if the parameter type is GraphQLStory and if sponsoredDataModelGetter returns a non-null value.
// If so, hide the story by setting the visibility to StoryVisibility.GONE.
mutableMethod.addInstructionsWithLabels(
scanResult.patternScanResult!!.startIndex,
"""
instance-of v0, p0, $GRAPHQL_STORY_TYPE
if-eqz v0, :resume_normal
invoke-static {p0}, $getSponsoredDataHelperMethod
move-result-object v0
if-eqz v0, :resume_normal
const-string v0, "GONE"
return-object v0
:resume_normal
nop
""",
)
} ?: throw GetStoryVisibilityFingerprint.exception
}
}

View File

@@ -0,0 +1,21 @@
package app.revanced.patches.facebook.ads.mainfeed.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 BaseModelMapperFingerprint : MethodFingerprint(
accessFlags = (AccessFlags.PUBLIC or AccessFlags.FINAL),
parameters = listOf("Ljava/lang/Class","I","I"),
returnType = "Lcom/facebook/graphql/modelutil/BaseModelWithTree;",
opcodes = listOf(
Opcode.SGET_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.IF_EQ
)
)

View File

@@ -0,0 +1,23 @@
package app.revanced.patches.facebook.ads.mainfeed.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 GetSponsoredDataModelTemplateFingerprint : MethodFingerprint(
accessFlags = (AccessFlags.PUBLIC or AccessFlags.FINAL),
parameters = listOf(),
returnType = "L",
opcodes = listOf(
Opcode.CONST,
Opcode.CONST,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT
),
customFingerprint = { methodDef, classDef ->
classDef.type == "Lcom/facebook/graphql/model/GraphQLFBMultiAdsFeedUnit;"
}
)

View File

@@ -0,0 +1,23 @@
package app.revanced.patches.facebook.ads.mainfeed.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
import com.android.tools.smali.dexlib2.iface.Annotation
import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue
internal object GetStoryVisibilityFingerprint : MethodFingerprint(
returnType = "Ljava/lang/String;",
accessFlags = (AccessFlags.PUBLIC or AccessFlags.STATIC),
opcodes = listOf(
Opcode.INSTANCE_OF,
Opcode.IF_NEZ,
Opcode.INSTANCE_OF,
Opcode.IF_NEZ,
Opcode.INSTANCE_OF,
Opcode.IF_NEZ,
Opcode.CONST
),
strings = listOf("This should not be called for base class object"),
)

View File

@@ -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<Instruction35c>(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.
""",
)
}
}
}

View File

@@ -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"
}
)

View File

@@ -10,5 +10,5 @@ internal object BuildMediaOptionsSheetFingerprint : MethodFingerprint(
Opcode.GOTO_16,
Opcode.NEW_INSTANCE,
),
strings = listOf("resources.getString(R.string.post_video)"),
strings = listOf("mediaEntity", "media_options_sheet"),
)

View File

@@ -5,6 +5,6 @@ import com.android.tools.smali.dexlib2.Opcode
internal object ShowDownloadVideoUpsellBottomSheetFingerprint : MethodFingerprint(
returnType = "Z",
strings = listOf("variantToDownload.url"),
strings = listOf("mediaEntity", "url"),
opcodes = listOf(Opcode.IF_EQZ)
)

View File

@@ -0,0 +1,93 @@
package app.revanced.patches.twitter.misc.links
import app.revanced.patcher.data.BytecodeContext
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.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
import app.revanced.patches.twitter.misc.links.fingerprints.LinkBuilderFingerprint
import app.revanced.patches.twitter.misc.links.fingerprints.LinkResourceGetterFingerprint
import app.revanced.patches.twitter.misc.links.fingerprints.LinkSharingDomainFingerprint
import app.revanced.util.exception
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.StringReference
@Patch(
name = "Change link sharing domain",
description = "Replaces the domain name of Twitter links when sharing them.",
compatiblePackages = [CompatiblePackage("com.twitter.android")],
)
@Suppress("unused")
object ChangeLinkSharingDomainPatch : BytecodePatch(
setOf(
LinkBuilderFingerprint,
LinkResourceGetterFingerprint,
LinkSharingDomainFingerprint,
),
) {
private var domainName by stringPatchOption(
key = "domainName",
default = "fxtwitter.com",
title = "Domain name",
description = "The domain name to use when sharing links.",
required = true,
)
// This method is used to build the link that is shared when the "Share via..." button is pressed.
private const val FORMAT_METHOD_RESOURCE_REFERENCE =
"Lapp/revanced/integrations/twitter/patches/links/ChangeLinkSharingDomainPatch;->" +
"formatResourceLink([Ljava/lang/Object;)Ljava/lang/String;"
// This method is used to build the link that is shared when the "Copy link" button is pressed.
private const val FORMAT_METHOD_REFERENCE =
"Lapp/revanced/integrations/twitter/patches/links/ChangeLinkSharingDomainPatch;->" +
"formatLink(JLjava/lang/String;)Ljava/lang/String;"
override fun execute(context: BytecodeContext) {
LinkSharingDomainFingerprint.result?.let {
val replacementIndex = it.scanResult.stringsScanResult!!.matches.first().index
val domainRegister = it.mutableMethod.getInstruction<OneRegisterInstruction>(replacementIndex).registerA
it.mutableMethod.replaceInstruction(
replacementIndex,
"const-string v$domainRegister, \"https://$domainName\"",
)
} ?: throw LinkSharingDomainFingerprint.exception
// Replace the domain name when copying a link with "Copy link" button.
LinkBuilderFingerprint.result?.let {
it.mutableMethod.apply {
addInstructions(
0,
"""
invoke-static { p0, p1, p2 }, $FORMAT_METHOD_REFERENCE
move-result-object p0
return-object p0
""",
)
}
} ?: throw LinkBuilderFingerprint.exception
// Used in the Share via... dialog.
LinkResourceGetterFingerprint.result?.mutableMethod?.apply {
val constWithParameterName = indexOfFirstInstructionOrThrow {
getReference<StringReference>()?.string?.contains("id.toString()") == true
}
// Format the link with the new domain name register (2 instructions above the const-string).
val formatLinkCallIndex = constWithParameterName - 2
val formatLinkCall = getInstruction<Instruction35c>(formatLinkCallIndex)
// Replace the original method call with the new method call.
replaceInstruction(
formatLinkCallIndex,
"invoke-static { v${formatLinkCall.registerE} }, $FORMAT_METHOD_RESOURCE_REFERENCE",
)
} ?: throw LinkResourceGetterFingerprint.exception
}
}

View File

@@ -0,0 +1,8 @@
package app.revanced.patches.twitter.misc.links.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
// Returns a shareable link string based on a tweet ID and a username.
internal object LinkBuilderFingerprint : MethodFingerprint(
strings = listOf("/%1\$s/status/%2\$d"),
)

View File

@@ -0,0 +1,12 @@
package app.revanced.patches.twitter.misc.links.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
// Gets Resource string for share link view available by pressing "Share via" button.
internal object LinkResourceGetterFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Landroid/content/res/Resources;"),
strings = listOf("res.getString(R.string.t…lUsername, id.toString())"),
)

View File

@@ -0,0 +1,7 @@
package app.revanced.patches.twitter.misc.links.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object LinkSharingDomainFingerprint : MethodFingerprint(
strings = listOf("https://fxtwitter.com"),
)

View File

@@ -42,6 +42,9 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
SwitchPreference("revanced_hide_shorts_subscribe_button"),
SwitchPreference("revanced_hide_shorts_paused_overlay_buttons"),
SwitchPreference("revanced_hide_shorts_save_sound_button"),
SwitchPreference("revanced_hide_shorts_use_template_button"),
SwitchPreference("revanced_hide_shorts_upcoming_button"),
SwitchPreference("revanced_hide_shorts_green_screen_button"),
SwitchPreference("revanced_hide_shorts_shop_button"),
SwitchPreference("revanced_hide_shorts_tagged_products"),
SwitchPreference("revanced_hide_shorts_stickers"),

View File

@@ -254,7 +254,9 @@ object SpoofVideoStreamsPatch : BytecodePatch(
// endregion
// region Remove /videoplayback request body to fix playback.
// This is needed when using iOS client as streaming data source.
// It is assumed, YouTube makes a request with a body tuned for Android.
// Requesting streams intended for other platforms with a body tuned for Android could be the cause of 400 errors.
// A proper fix may include modifying the request body to match the platforms expected body.
BuildMediaDataSourceFingerprint.resultOrThrow().let {
it.mutableMethod.apply {

View File

@@ -637,8 +637,17 @@ This is because Crowdin requires temporarily flattening this file and removing t
<string name="revanced_hide_shorts_location_label_summary_on">Location label is hidden</string>
<string name="revanced_hide_shorts_location_label_summary_off">Location label is shown</string>
<string name="revanced_hide_shorts_save_sound_button_title">Hide save music button</string>
<string name="revanced_hide_shorts_save_sound_button_summary_on">Save music is hidden</string>
<string name="revanced_hide_shorts_save_sound_button_summary_off">Save music is shown</string>
<string name="revanced_hide_shorts_save_sound_button_summary_on">Save music button is hidden</string>
<string name="revanced_hide_shorts_save_sound_button_summary_off">Save music button is shown</string>
<string name="revanced_hide_shorts_use_template_button_title">Hide use template button</string>
<string name="revanced_hide_shorts_use_template_button_summary_on">Use template button is hidden</string>
<string name="revanced_hide_shorts_use_template_button_summary_off">Use template button is shown</string>
<string name="revanced_hide_shorts_upcoming_button_title">Hide upcoming button</string>
<string name="revanced_hide_shorts_upcoming_button_summary_on">Upcoming button is hidden</string>
<string name="revanced_hide_shorts_upcoming_button_summary_off">Upcoming button is shown</string>
<string name="revanced_hide_shorts_green_screen_button_title">Hide green screen button</string>
<string name="revanced_hide_shorts_green_screen_button_summary_on">Green screen button is hidden</string>
<string name="revanced_hide_shorts_green_screen_button_summary_off">Green screen button is shown</string>
<string name="revanced_hide_shorts_search_suggestions_title">Hide search suggestions</string>
<string name="revanced_hide_shorts_search_suggestions_summary_on">Search suggestions are hidden</string>
<string name="revanced_hide_shorts_search_suggestions_summary_off">Search suggestions are shown</string>