Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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,36 +2,34 @@

import android.annotation.SuppressLint;
import android.app.Activity;

import java.util.List;
import app.revanced.extension.shared.Utils;

@SuppressWarnings("unused")
@SuppressLint("DiscouragedApi")
public class HandleCustomDeepLinksPatch {
private static List<String> customLinkHosts = null;
private static String[] customLinkHosts = null;

public static void rewriteCustomDeepLinks(Activity activity) {
var intent = activity.getIntent();

var uri = intent.getData();
if (uri == null) return;

if (customLinkHosts == null) {
int hostsResourceId = activity.getResources().getIdentifier(
"piko_custom_deeplink_hosts",
"array",
activity.getPackageName());
String[] hosts = activity.getResources().getStringArray(hostsResourceId);

customLinkHosts = List.of(hosts);
}
if (customLinkHosts == null)
customLinkHosts = Utils.getResourceStringArray("piko_custom_deeplink_hosts");

if (!customLinkHosts.contains(uri.getHost())) return;
String host = uri.getHost();

var newUri = uri.buildUpon()
.authority("x.com")
.build();
for (String customHost : customLinkHosts) {
if (host.endsWith(customHost)) {
// Rewrite host
var newUri = uri.buildUpon()
.authority("x.com")
.build();

intent.setData(newUri);
intent.setData(newUri);
return;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,149 +1,97 @@
// TODO: Lack of skill to migrate this patch
package app.crimera.patches.twitter.link.customDeeplinks

// package app.crimera.patches.twitter.link.customDeeplinks
//
// import app.revanced.patcher.data.ResourceContext
// import app.revanced.patcher.patch.PatchException
// import app.revanced.patcher.patch.ResourcePatch
// import app.revanced.patcher.patch.annotation.CompatiblePackage
// import app.revanced.patcher.patch.annotation.Patch
// import app.revanced.patcher.patch.options.PatchOption
// import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringArrayPatchOption
// import app.revanced.util.asSequence
//
// @Patch(
// name = "Handle custom twitter links",
// description =
// "Adds support for opening custom twitter links such as vxtwitter, fxtwitter, fixupx, etc. within the app" +
// "These will have to be manually enabled under the \"Verified Links\" section of the patched app's system settings!",
// use = true,
// compatiblePackages = [CompatiblePackage("com.twitter.android")],
// dependencies = [HandleCustomDeepLinksPatch::class],
// )
// @Suppress("unused")
// object CustomDeepLinksPatch : ResourcePatch() {
// init {
// stringArrayPatchOption(
// key = "customLinkHosts",
// title = "Custom sharing domains",
// description = "The custom sharing domains to register to be opened in Twitter",
// required = true,
// default =
// arrayOf( // @formatter:off
// // Some of these are absolutely unhinged, but it's all the more reason to skip opening it in a browser
// "vxtwitter.com",
// "m.vxtwitter.com",
// "g.vxtwitter.com",
// "t.vxtwitter.com",
// "o.vxtwitter.com",
// "mobile.vxtwitter.com",
// "fixvx.com",
// "m.fixvx.com",
// "g.fixvx.com",
// "t.fixvx.com",
// "o.fixvx.com",
// "mobile.fixvx.com",
// "fxtwitter.com",
// "m.fxtwitter.com",
// "g.fxtwitter.com",
// "t.fxtwitter.com",
// "o.fxtwitter.com",
// "fixupx.com",
// "m.fxtwitter.com",
// "g.fxtwitter.com",
// "t.fxtwitter.com",
// "o.fixupx.com",
// "twittpr.com",
// "m.twittpr.com",
// "g.twittpr.com",
// "t.twittpr.com",
// "hitlerx.com",
// "m.hitlerx.com",
// "g.hitlerx.com",
// "t.hitlerx.com",
// "o.hitlerx.com",
// "girlcockx.com",
// "m.girlcockx.com",
// "g.girlcockx.com",
// "t.girlcockx.com",
// "stupidpenisx.com",
// "cunnyx.com",
// "autistic.kids",
// ),
// // @formatter:on
// )
// }
//
// override fun execute(context: ResourceContext) {
// val customLinkHosts: PatchOption<Array<String>> by options
//
// context.xmlEditor["AndroidManifest.xml"].use { editor ->
// val document = editor.file
// val activities = document.getElementsByTagName("activity")
//
// val deeplinkActivity =
// activities
// .asSequence()
// .find {
// val name = it.attributes.getNamedItem("android:name").nodeValue
// name == "com.twitter.deeplink.implementation.UrlInterpreterActivity"
// }
// ?: throw PatchException("Unable to find UrlInterpreterActivity in AndroidManifest")
//
// val newIntentFilter =
// document.createElement("intent-filter").apply {
// document
// .createElement("action")
// .apply { setAttribute("android:name", "android.intent.action.VIEW") }
// .let(::appendChild)
// document
// .createElement("category")
// .apply { setAttribute("android:name", "android.intent.category.DEFAULT") }
// .let(::appendChild)
// document
// .createElement("category")
// .apply { setAttribute("android:name", "android.intent.category.BROWSABLE") }
// .let(::appendChild)
// document
// .createElement("data")
// .apply { setAttribute("android:scheme", "http") }
// .let(::appendChild)
// document
// .createElement("data")
// .apply { setAttribute("android:scheme", "https") }
// .let(::appendChild)
// document
// .createElement("data")
// .apply { setAttribute("android:pathPattern", "/.*") }
// .let(::appendChild)
//
// for (customHost in customLinkHosts.value!!) {
// document
// .createElement("data")
// .apply { setAttribute("android:host", customHost) }
// .let(::appendChild)
// }
// }
//
// deeplinkActivity.appendChild(newIntentFilter)
// }
//
// context.xmlEditor["res/values/arrays.xml"].use { editor ->
// val document = editor.file
// val resources = document.getElementsByTagName("resources").asSequence().single()
//
// val array =
// document.createElement("string-array").apply {
// setAttribute("name", "piko_custom_deeplink_hosts")
// for (customHost in customLinkHosts.value!!) {
// document
// .createElement("item")
// .apply { textContent = customHost }
// .let(::appendChild)
// }
// }
//
// resources.appendChild(array)
// }
// }
// }
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.stringsOption
import app.revanced.util.asSequence

@Suppress("unused")
val customDeepLinksPatch = resourcePatch(
name = "Handle custom twitter links",
description = "Adds support for opening custom twitter links such as vxtwitter, fxtwitter, and fixupx within the app. " +
"These will have to be manually enabled under the \"Open by default\" section in the app info!"
) {
val customLinkHosts by stringsOption(
key = "customLinkHosts",
title = "Custom sharing domains",
description = "The custom sharing domains to register to be opened in Twitter",
required = true,
default = listOf(
// Some of these are absolutely unhinged, but it's all the more reason to skip opening it in a browser
"vxtwitter.com",
"fixvx.com",
"fxtwitter.com",
"fixupx.com",
"twittpr.com",
"hitlerx.com",
"girlcockx.com",
"stupidpenisx.com",
"cunnyx.com",
"autistic.kids",
),
)

compatibleWith("com.twitter.android")

dependsOn(handleCustomDeepLinksPatch)

execute {
document("AndroidManifest.xml").use { document ->
val activities = document.getElementsByTagName("activity")

val deeplinkActivity = activities.asSequence()
.find {
val name = it.attributes.getNamedItem("android:name").nodeValue
name == "com.twitter.deeplink.implementation.UrlInterpreterActivity"
}
?: throw PatchException("Unable to find UrlInterpreterActivity in AndroidManifest")

val newIntentFilter = document.createElement("intent-filter").apply {
document.createElement("action")
.apply { setAttribute("android:name", "android.intent.action.VIEW") }
.let(::appendChild)
document.createElement("category")
.apply { setAttribute("android:name", "android.intent.category.DEFAULT") }
.let(::appendChild)
document.createElement("category")
.apply { setAttribute("android:name", "android.intent.category.BROWSABLE") }
.let(::appendChild)
document.createElement("data")
.apply { setAttribute("android:scheme", "http") }
.let(::appendChild)
document.createElement("data")
.apply { setAttribute("android:scheme", "https") }
.let(::appendChild)
document.createElement("data")
.apply { setAttribute("android:pathPattern", "/..*") }
.let(::appendChild)

for (customHost in customLinkHosts!!) {
document.createElement("data")
.apply { setAttribute("android:host", customHost) }
.let(::appendChild)
document.createElement("data")
.apply { setAttribute("android:host", "*.$customHost") }
.let(::appendChild)
}
}

deeplinkActivity.appendChild(newIntentFilter)
}

document("res/values/arrays.xml").use { document ->
val resources = document.getElementsByTagName("resources").asSequence().single()

val array = document.createElement("string-array").apply {
setAttribute("name", "piko_custom_deeplink_hosts")
for (customHost in customLinkHosts!!) {
document.createElement("item")
.apply { textContent = customHost }
.let(::appendChild)
}
}

resources.appendChild(array)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package app.crimera.patches.twitter.link.customDeeplinks

import app.crimera.patches.twitter.misc.settings.settingsPatch
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.crimera.utils.Constants.PATCHES_DESCRIPTOR
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.fingerprint
import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.AccessFlags
Expand All @@ -15,20 +15,14 @@ private val urlInterpreterActivityCreateFingerprint =
}
}

@Suppress("unused")
val handleCustomDeepLinksPatch =
bytecodePatch(
description = "handle custom deeplink",
) {
dependsOn(settingsPatch)

execute {

val bytecode =
"""
invoke-static {p0}, Lapp/revanced/integrations/twitter/patches/links/HandleCustomDeepLinksPatch;->rewriteCustomDeepLinks(Landroid/app/Activity;)V
""".trimIndent()

urlInterpreterActivityCreateFingerprint.method.addInstructions(0, bytecode)
urlInterpreterActivityCreateFingerprint.method.addInstruction(
0,
"invoke-static {p0}, $PATCHES_DESCRIPTOR/links/HandleCustomDeepLinksPatch;->rewriteCustomDeepLinks(Landroid/app/Activity;)V"
)
}
}
Loading