94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
package render
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/peterqiu0516/sub-store/internal/model"
|
|
)
|
|
|
|
// RenderQxProxies renders proxies as Quantumult X text lines.
|
|
func RenderQxProxies(proxies []model.ProxyNode) (string, error) {
|
|
return RenderTextProxyList(proxies, model.TargetQX, func(p model.ProxyNode) string {
|
|
return ToQxProxyLine(p)
|
|
})
|
|
}
|
|
|
|
// ToQxProxyLine converts a single proxy node to a Quantumult X proxy line.
|
|
// Returns "" for unsupported proxy types.
|
|
func ToQxProxyLine(proxy model.ProxyNode) string {
|
|
ptype := getString(proxy, "type")
|
|
server := getString(proxy, "server")
|
|
port := getInt(proxy, "port")
|
|
|
|
entries := CommonTextOptions(proxy)
|
|
entries = append(entries, [2]any{"tag", sanitizeQxTag(getString(proxy, "name"))})
|
|
|
|
switch ptype {
|
|
case "ss":
|
|
entries = unshift(entries,
|
|
[2]any{"method", strOr(proxy, "cipher", "none")},
|
|
[2]any{"password", proxy["password"]},
|
|
)
|
|
entries = AppendQxObfs(entries, proxy)
|
|
return JoinTextProxy("shadowsocks="+server+":"+itoa(port), entries)
|
|
|
|
case "ssr":
|
|
entries = unshift(entries,
|
|
[2]any{"method", strOr(proxy, "cipher", "aes-256-cfb")},
|
|
[2]any{"password", proxy["password"]},
|
|
[2]any{"ssr-protocol", strOr(proxy, "protocol", "origin")},
|
|
[2]any{"obfs", strOr(proxy, "obfs", "plain")},
|
|
)
|
|
return JoinTextProxy("shadowsocks="+server+":"+itoa(port), entries)
|
|
|
|
case "vmess", "vless":
|
|
method := strOr(proxy, "cipher", "auto")
|
|
if ptype == "vless" {
|
|
method = "none"
|
|
}
|
|
entries = unshift(entries,
|
|
[2]any{"method", method},
|
|
[2]any{"password", proxy["uuid"]},
|
|
[2]any{"over-tls", proxy["tls"]},
|
|
[2]any{"tls-host", proxy["servername"]},
|
|
[2]any{"flow", proxy["flow"]},
|
|
)
|
|
entries = AppendQxTransport(entries, proxy)
|
|
entries = AppendQxRealityOptions(entries, proxy)
|
|
return JoinTextProxy(ptype+"="+server+":"+itoa(port), entries)
|
|
|
|
case "trojan", "anytls":
|
|
entries = unshift(entries,
|
|
[2]any{"password", proxy["password"]},
|
|
[2]any{"over-tls", true},
|
|
[2]any{"tls-host", sniOr(proxy, "sni", "servername")},
|
|
)
|
|
entries = AppendQxRealityOptions(entries, proxy)
|
|
return JoinTextProxy(ptype+"="+server+":"+itoa(port), entries)
|
|
|
|
case "http", "socks5":
|
|
entries = unshift(entries,
|
|
[2]any{"username", proxy["username"]},
|
|
[2]any{"password", proxy["password"]},
|
|
[2]any{"over-tls", proxy["tls"]},
|
|
)
|
|
qxType := ptype
|
|
if ptype == "socks5" {
|
|
qxType = "socks5"
|
|
}
|
|
return JoinTextProxy(qxType+"="+server+":"+itoa(port), entries)
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// sanitizeQxTag replaces comma/CR/LF (but not =) with spaces.
|
|
func sanitizeQxTag(name string) string {
|
|
r := strings.NewReplacer(",", " ", "\r", " ", "\n", " ")
|
|
s := strings.TrimSpace(r.Replace(name))
|
|
if s == "" {
|
|
return "proxy"
|
|
}
|
|
return s
|
|
}
|