Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,19 @@

@SuppressWarnings("unused")
public final class ChangeLinkSharingDomainPatch {
private static final String DOMAIN_NAME = "https://fxtwitter.com";
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) {
String username = (String) formatArgs[0];
String tweetId = (String) formatArgs[1];
return String.format(LINK_FORMAT, DOMAIN_NAME, username, tweetId);
private static String getShareDomain() {
return "";
}

/**
* Injection point.
*/
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);
}
}
2 changes: 2 additions & 0 deletions patches/api/patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,8 @@ public final class app/revanced/patches/twitter/misc/hook/json/JsonHookPatchKt {

public final class app/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatchKt {
public static final fun getChangeLinkSharingDomainPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
public static final fun getChangeLinkSharingDomainResourcePatch ()Lapp/revanced/patcher/patch/ResourcePatch;
public static final fun getDomainNameOption ()Ljava/lang/String;
}

public final class app/revanced/patches/twitter/misc/links/OpenLinksWithAppChooserPatchKt {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,72 @@
package app.revanced.patches.twitter.misc.links

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.PatchException
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.stringOption
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.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.util.indexOfFirstLiteralInstructionOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import app.revanced.util.returnEarly
import org.w3c.dom.Element
import java.net.InetAddress
import java.net.UnknownHostException
import java.util.logging.Logger

internal var tweetShareLinkTemplateId = -1L
private set
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/twitter/patches/links/ChangeLinkSharingDomainPatch;"

internal val changeLinkSharingDomainResourcePatch = resourcePatch {
dependsOn(resourceMappingPatch)
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
}

val changeLinkSharingDomainResourcePatch = resourcePatch {
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"
}
var foundShareLinkTemplateResource = false

document("res/values/strings.xml").use {
val resources = it.documentElement.childNodes

for (i in 0 until resources.length) {
val node = resources.item(i)
if (node !is Element) continue

if (node.getAttribute("name") == "tweet_share_link") {
node.textContent = shareLinkTemplate
foundShareLinkTemplateResource = true
break
}
}
}

if (!foundShareLinkTemplateResource)
throw PatchException("Failed to find string resource 'tweet_share_link'")
}
}

private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/twitter/patches/links/ChangeLinkSharingDomainPatch;"

@Suppress("unused")
val changeLinkSharingDomainPatch = bytecodePatch(
name = PATCH_NAME_CHANGE_LINK_SHARING_DOMAIN,
Expand All @@ -46,26 +84,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 {
linkSharingDomainFingerprint.let {
val replacementIndex = it.stringMatches!!.first().index
val domainRegister = it.method.getInstruction<OneRegisterInstruction>(
replacementIndex
).registerA
val domainName = domainNameOption!!

it.method.replaceInstruction(
replacementIndex,
"const-string v$domainRegister, \"https://$domainName\"",
)
}
// Replace the domain name in the link sharing extension methods.
linkSharingDomainHelperFingerprint.method.returnEarly(domainName)

// Replace the domain name when copying a link with "Copy link" button.
linkBuilderFingerprint.method.addInstructions(
Expand All @@ -76,20 +99,5 @@ val changeLinkSharingDomainPatch = bytecodePatch(
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;",
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package app.revanced.patches.twitter.misc.links

import app.revanced.patcher.fingerprint
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags

internal val openLinkFingerprint = fingerprint {
returns("V")
Expand All @@ -19,13 +17,8 @@ internal val linkBuilderFingerprint = fingerprint {
strings("/%1\$s/status/%2\$d")
}

// Gets Resource string for share link view available by pressing "Share via" button.
internal val linkResourceGetterFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
parameters("Landroid/content/res/Resources;")
literal { tweetShareLinkTemplateId }
}

internal val linkSharingDomainFingerprint = fingerprint {
strings("https://fxtwitter.com")
internal val linkSharingDomainHelperFingerprint = fingerprint {
custom { method, classDef ->
method.name == "getShareDomain" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
}
}
Loading