mirror of
https://github.com/MatsuriDayo/NekoBoxForAndroid.git
synced 2025-12-19 06:30:05 +08:00
feat: add sharelink for TUIC
This commit is contained in:
parent
e300558912
commit
9b49ffd20e
@ -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.buildTrojanGoConfig
|
||||||
import io.nekohasekai.sagernet.fmt.trojan_go.toUri
|
import io.nekohasekai.sagernet.fmt.trojan_go.toUri
|
||||||
import io.nekohasekai.sagernet.fmt.tuic.TuicBean
|
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.tuic.buildTuicConfig
|
||||||
import io.nekohasekai.sagernet.fmt.v2ray.*
|
import io.nekohasekai.sagernet.fmt.v2ray.*
|
||||||
import io.nekohasekai.sagernet.fmt.wireguard.WireGuardBean
|
import io.nekohasekai.sagernet.fmt.wireguard.WireGuardBean
|
||||||
@ -225,7 +226,6 @@ data class ProxyEntity(
|
|||||||
|
|
||||||
fun haveStandardLink(): Boolean {
|
fun haveStandardLink(): Boolean {
|
||||||
return when (requireBean()) {
|
return when (requireBean()) {
|
||||||
is TuicBean -> false
|
|
||||||
is SSHBean -> false
|
is SSHBean -> false
|
||||||
is WireGuardBean -> false
|
is WireGuardBean -> false
|
||||||
is ShadowTLSBean -> false
|
is ShadowTLSBean -> false
|
||||||
@ -245,6 +245,7 @@ data class ProxyEntity(
|
|||||||
is TrojanGoBean -> toUri()
|
is TrojanGoBean -> toUri()
|
||||||
is NaiveBean -> toUri()
|
is NaiveBean -> toUri()
|
||||||
is HysteriaBean -> toUri()
|
is HysteriaBean -> toUri()
|
||||||
|
is TuicBean -> toUri()
|
||||||
is NekoBean -> shareLink()
|
is NekoBean -> shareLink()
|
||||||
else -> toUniversalLink()
|
else -> toUniversalLink()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package io.nekohasekai.sagernet.fmt.tuic
|
package io.nekohasekai.sagernet.fmt.tuic
|
||||||
|
|
||||||
import io.nekohasekai.sagernet.fmt.LOCALHOST
|
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.SingBoxOptions
|
||||||
import moe.matsuri.nb4a.utils.JavaUtil
|
import moe.matsuri.nb4a.utils.JavaUtil
|
||||||
import moe.matsuri.nb4a.utils.Util
|
import moe.matsuri.nb4a.utils.Util
|
||||||
@ -9,6 +9,58 @@ import moe.matsuri.nb4a.utils.listByLineOrComma
|
|||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.io.File
|
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 {
|
fun buildSingBoxOutboundTuicBean(bean: TuicBean): SingBoxOptions.Outbound_TUICOptions {
|
||||||
return SingBoxOptions.Outbound_TUICOptions().apply {
|
return SingBoxOptions.Outbound_TUICOptions().apply {
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import io.nekohasekai.sagernet.fmt.parseUniversal
|
|||||||
import io.nekohasekai.sagernet.fmt.shadowsocks.parseShadowsocks
|
import io.nekohasekai.sagernet.fmt.shadowsocks.parseShadowsocks
|
||||||
import io.nekohasekai.sagernet.fmt.socks.parseSOCKS
|
import io.nekohasekai.sagernet.fmt.socks.parseSOCKS
|
||||||
import io.nekohasekai.sagernet.fmt.trojan.parseTrojan
|
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.trojan_go.parseTrojanGo
|
||||||
import io.nekohasekai.sagernet.fmt.v2ray.parseV2Ray
|
import io.nekohasekai.sagernet.fmt.v2ray.parseV2Ray
|
||||||
import moe.matsuri.nb4a.plugin.NekoPluginManager
|
import moe.matsuri.nb4a.plugin.NekoPluginManager
|
||||||
@ -187,6 +188,13 @@ suspend fun parseProxies(text: String): List<AbstractBean> {
|
|||||||
}.onFailure {
|
}.onFailure {
|
||||||
Logs.w(it)
|
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
|
} else { // Neko Plugins
|
||||||
NekoPluginManager.getProtocols().forEach { obj ->
|
NekoPluginManager.getProtocols().forEach { obj ->
|
||||||
obj.protocolConfig.optJSONArray("links")?.forEach { _, any ->
|
obj.protocolConfig.optJSONArray("links")?.forEach { _, any ->
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user