fix(X / Twitter - Change Link Sharing Domain): Change link domain of share copy action (#6091)

Co-authored-by: nyraa <112930946+nyraa@users.noreply.github.com>
This commit is contained in:
ADudeCalledLeo
2025-10-11 01:01:44 +03:00
committed by GitHub
parent a98e8f7370
commit 54846253d7
3 changed files with 53 additions and 67 deletions

View File

@@ -2,22 +2,19 @@ package app.revanced.twitter.patches.links;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class ChangeLinkSharingDomainPatch { public final class ChangeLinkSharingDomainPatch {
private static final String DOMAIN_NAME = "https://fxtwitter.com";
private static final String LINK_FORMAT = "%s/%s/status/%s"; private static final String LINK_FORMAT = "%s/%s/status/%s";
/** /**
* Injection point. * Method is modified during patching. Do not change.
*/ */
public static String formatResourceLink(Object... formatArgs) { private static String getShareDomain() {
String username = (String) formatArgs[0]; return "";
String tweetId = (String) formatArgs[1];
return String.format(LINK_FORMAT, DOMAIN_NAME, username, tweetId);
} }
/** /**
* Injection point. * Injection point.
*/ */
public static String formatLink(long tweetId, String username) { public static String formatLink(long tweetId, String username) {
return String.format(LINK_FORMAT, DOMAIN_NAME, username, tweetId); return String.format(LINK_FORMAT, getShareDomain(), username, tweetId);
} }
} }

View File

@@ -1,33 +1,59 @@
package app.revanced.patches.twitter.misc.links package app.revanced.patches.twitter.misc.links
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions 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.bytecodePatch
import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.stringOption import app.revanced.patcher.patch.stringOption
import app.revanced.patches.shared.PATCH_DESCRIPTION_CHANGE_LINK_SHARING_DOMAIN import app.revanced.patches.shared.PATCH_DESCRIPTION_CHANGE_LINK_SHARING_DOMAIN
import app.revanced.patches.shared.PATCH_NAME_CHANGE_LINK_SHARING_DOMAIN import app.revanced.patches.shared.PATCH_NAME_CHANGE_LINK_SHARING_DOMAIN
import app.revanced.patches.shared.misc.mapping.get
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.mapping.resourceMappings
import app.revanced.patches.twitter.misc.extension.sharedExtensionPatch import app.revanced.patches.twitter.misc.extension.sharedExtensionPatch
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import app.revanced.util.findElementByAttributeValueOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import app.revanced.util.returnEarly
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import java.net.InetAddress
import java.net.UnknownHostException
import java.util.logging.Logger
internal var tweetShareLinkTemplateId = -1L internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/twitter/patches/links/ChangeLinkSharingDomainPatch;"
private set
internal val domainNameOption by stringOption(
key = "domainName",
default = "https://fxtwitter.com",
title = "Domain name",
description = "The domain name to use when sharing links.",
required = true,
) {
// Do a courtesy check if the host can be resolved.
// If it does not resolve, then print a warning but use the host anyway.
// Unresolvable hosts should not be rejected, since the patching environment
// may not allow network connections or the network may be down.
try {
InetAddress.getByName(it)
} catch (e: UnknownHostException) {
Logger.getLogger(this::class.java.name).warning(
"Host \"$it\" did not resolve to any domain."
)
}
true
}
internal val changeLinkSharingDomainResourcePatch = resourcePatch { internal val changeLinkSharingDomainResourcePatch = resourcePatch {
dependsOn(resourceMappingPatch)
execute { execute {
tweetShareLinkTemplateId = resourceMappings["string", "tweet_share_link"] val domainName = domainNameOption!!
}
val shareLinkTemplate = if (domainName.endsWith("/")) {
"$domainName%1\$s/status/%2\$s"
} else {
"$domainName/%1\$s/status/%2\$s"
} }
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/twitter/patches/links/ChangeLinkSharingDomainPatch;" document("res/values/strings.xml").use { document ->
document.documentElement.childNodes.findElementByAttributeValueOrThrow(
"name",
"tweet_share_link"
).textContent = shareLinkTemplate
}
}
}
@Suppress("unused") @Suppress("unused")
val changeLinkSharingDomainPatch = bytecodePatch( val changeLinkSharingDomainPatch = bytecodePatch(
@@ -46,26 +72,11 @@ val changeLinkSharingDomainPatch = bytecodePatch(
) )
) )
val domainName by stringOption(
key = "domainName",
default = "fxtwitter.com",
title = "Domain name",
description = "The domain name to use when sharing links.",
required = true,
)
execute { execute {
linkSharingDomainFingerprint.let { val domainName = domainNameOption!!
val replacementIndex = it.stringMatches!!.first().index
val domainRegister = it.method.getInstruction<OneRegisterInstruction>(
replacementIndex
).registerA
it.method.replaceInstruction( // Replace the domain name in the link sharing extension methods.
replacementIndex, linkSharingDomainHelperFingerprint.method.returnEarly(domainName)
"const-string v$domainRegister, \"https://$domainName\"",
)
}
// Replace the domain name when copying a link with "Copy link" button. // Replace the domain name when copying a link with "Copy link" button.
linkBuilderFingerprint.method.addInstructions( linkBuilderFingerprint.method.addInstructions(
@@ -76,20 +87,5 @@ val changeLinkSharingDomainPatch = bytecodePatch(
return-object p0 return-object p0
""" """
) )
// Used in the Share via... dialog.
linkResourceGetterFingerprint.method.apply {
val templateIdConstIndex = indexOfFirstLiteralInstructionOrThrow(tweetShareLinkTemplateId)
// Format the link with the new domain name register (1 instruction below the const).
val formatLinkCallIndex = templateIdConstIndex + 1
val register = getInstruction<FiveRegisterInstruction>(formatLinkCallIndex).registerE
// Replace the original method call with the new method call.
replaceInstruction(
formatLinkCallIndex,
"invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->formatResourceLink([Ljava/lang/Object;)Ljava/lang/String;",
)
}
} }
} }

View File

@@ -1,8 +1,6 @@
package app.revanced.patches.twitter.misc.links package app.revanced.patches.twitter.misc.links
import app.revanced.patcher.fingerprint import app.revanced.patcher.fingerprint
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
internal val openLinkFingerprint = fingerprint { internal val openLinkFingerprint = fingerprint {
returns("V") returns("V")
@@ -19,13 +17,8 @@ internal val linkBuilderFingerprint = fingerprint {
strings("/%1\$s/status/%2\$d") strings("/%1\$s/status/%2\$d")
} }
// Gets Resource string for share link view available by pressing "Share via" button. internal val linkSharingDomainHelperFingerprint = fingerprint {
internal val linkResourceGetterFingerprint = fingerprint { custom { method, classDef ->
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) method.name == "getShareDomain" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
parameters("Landroid/content/res/Resources;")
literal { tweetShareLinkTemplateId }
} }
internal val linkSharingDomainFingerprint = fingerprint {
strings("https://fxtwitter.com")
} }