Skip to content

Commit

Permalink
feat: add sharelink for TUIC
Browse files Browse the repository at this point in the history
  • Loading branch information
HystericalDragon authored and arm64v8a committed Aug 16, 2023
1 parent e300558 commit 9b49ffd
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import io.nekohasekai.sagernet.fmt.trojan_go.TrojanGoBean
import io.nekohasekai.sagernet.fmt.trojan_go.buildTrojanGoConfig
import io.nekohasekai.sagernet.fmt.trojan_go.toUri
import io.nekohasekai.sagernet.fmt.tuic.TuicBean
import io.nekohasekai.sagernet.fmt.tuic.toUri
import io.nekohasekai.sagernet.fmt.tuic.buildTuicConfig
import io.nekohasekai.sagernet.fmt.v2ray.*
import io.nekohasekai.sagernet.fmt.wireguard.WireGuardBean
Expand Down Expand Up @@ -225,7 +226,6 @@ data class ProxyEntity(

fun haveStandardLink(): Boolean {
return when (requireBean()) {
is TuicBean -> false
is SSHBean -> false
is WireGuardBean -> false
is ShadowTLSBean -> false
Expand All @@ -245,6 +245,7 @@ data class ProxyEntity(
is TrojanGoBean -> toUri()
is NaiveBean -> toUri()
is HysteriaBean -> toUri()
is TuicBean -> toUri()
is NekoBean -> shareLink()
else -> toUniversalLink()
}
Expand Down
54 changes: 53 additions & 1 deletion app/src/main/java/io/nekohasekai/sagernet/fmt/tuic/TuicFmt.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,66 @@
package io.nekohasekai.sagernet.fmt.tuic

import io.nekohasekai.sagernet.fmt.LOCALHOST
import io.nekohasekai.sagernet.ktx.isIpAddress
import io.nekohasekai.sagernet.ktx.*
import moe.matsuri.nb4a.SingBoxOptions
import moe.matsuri.nb4a.utils.JavaUtil
import moe.matsuri.nb4a.utils.Util
import moe.matsuri.nb4a.utils.listByLineOrComma
import org.json.JSONArray
import org.json.JSONObject
import java.io.File
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull

fun parseTuic(url: String): TuicBean {
// https://github.com/daeuniverse/dae/discussions/182
var link = url.replace("tuic://", "https://").toHttpUrlOrNull() ?: error(
"invalid tuic link $url"
)
return TuicBean().apply {
protocolVersion = 5

name = link.fragment
uuid = link.username
token = link.password
serverAddress = link.host
serverPort = link.port

link.queryParameter("sni")?.let {
sni = it
}
link.queryParameter("congestion_control")?.let {
congestionController = it
}
link.queryParameter("udp_relay_mode")?.let {
udpRelayMode = it
}
link.queryParameter("alpn")?.let {
alpn = it
}
link.queryParameter("allow_insecure")?.let {
if (it == "1") allowInsecure = true
}
link.queryParameter("disable_sni")?.let {
if (it == "1") disableSNI =true
}
}
}

fun TuicBean.toUri(): String {
val builder = linkBuilder().username(uuid).password(token).host(serverAddress).port(serverPort)

builder.addQueryParameter("congestion_control", congestionController)
builder.addQueryParameter("udp_relay_mode", udpRelayMode)

if (sni.isNotBlank()) builder.addQueryParameter("sni", sni)
if (alpn.isNotBlank()) builder.addQueryParameter("alpn", alpn)
if (allowInsecure) builder.addQueryParameter("allow_insecure", "1")
if (disableSNI) builder.addQueryParameter("disable_sni", "1")
if (name.isNotBlank()) builder.encodedFragment(name.urlSafe())

return builder.toLink("tuic")
}

fun buildSingBoxOutboundTuicBean(bean: TuicBean): SingBoxOptions.Outbound_TUICOptions {
return SingBoxOptions.Outbound_TUICOptions().apply {
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/io/nekohasekai/sagernet/ktx/Formats.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import io.nekohasekai.sagernet.fmt.parseUniversal
import io.nekohasekai.sagernet.fmt.shadowsocks.parseShadowsocks
import io.nekohasekai.sagernet.fmt.socks.parseSOCKS
import io.nekohasekai.sagernet.fmt.trojan.parseTrojan
import io.nekohasekai.sagernet.fmt.tuic.parseTuic
import io.nekohasekai.sagernet.fmt.trojan_go.parseTrojanGo
import io.nekohasekai.sagernet.fmt.v2ray.parseV2Ray
import moe.matsuri.nb4a.plugin.NekoPluginManager
Expand Down Expand Up @@ -187,6 +188,13 @@ suspend fun parseProxies(text: String): List<AbstractBean> {
}.onFailure {
Logs.w(it)
}
} else if (startsWith("tuic://")) {
Logs.d("Try parse TUIC link: $this")
runCatching {
entities.add(parseTuic(this))
}.onFailure {
Logs.w(it)
}
} else { // Neko Plugins
NekoPluginManager.getProtocols().forEach { obj ->
obj.protocolConfig.optJSONArray("links")?.forEach { _, any ->
Expand Down

0 comments on commit 9b49ffd

Please sign in to comment.