sublinker / node /surge.go
YimoEx
init
bb9df9e
package node
import (
"fmt"
"io"
"log"
"net/http"
"os"
"regexp"
"strings"
)
func EncodeSurge(urls []string, sqlconfig SqlConfig) (string, error) {
var proxys, groups []string
for _, link := range urls {
Scheme := strings.Split(link, "://")[0]
switch {
case Scheme == "ss":
ss, err := DecodeSSURL(link)
if err != nil {
log.Println(err)
continue
}
proxy := map[string]interface{}{
"name": ss.Name,
"server": ss.Server,
"port": ss.Port,
"cipher": ss.Param.Cipher,
"password": ss.Param.Password,
"udp": sqlconfig.Udp,
}
ssproxy := fmt.Sprintf("%s = ss, %s, %d, encrypt-method=%s, password=%s, udp-relay=%t",
proxy["name"], proxy["server"], proxy["port"], proxy["cipher"], proxy["password"], proxy["udp"])
groups = append(groups, ss.Name)
proxys = append(proxys, ssproxy)
case Scheme == "vmess":
vmess, err := DecodeVMESSURL(link)
if err != nil {
log.Println(err)
continue
}
tls := false
if vmess.Tls != "none" && vmess.Tls != "" {
tls = true
}
port, _ := convertToInt(vmess.Port)
proxy := map[string]interface{}{
"name": vmess.Ps,
"server": vmess.Add,
"port": port,
"uuid": vmess.Id,
"tls": tls,
"network": vmess.Net,
"ws-path": vmess.Path,
"ws-host": vmess.Host,
"udp": sqlconfig.Udp,
"skip-cert-verify": sqlconfig.Cert,
}
vmessproxy := fmt.Sprintf("%s = vmess, %s, %d, username=%s , tls=%t, vmess-aead=true, udp-relay=%t , skip-cert-verify=%t",
proxy["name"], proxy["server"], proxy["port"], proxy["uuid"], proxy["tls"], proxy["udp"], proxy["skip-cert-verify"])
if vmess.Net == "ws" {
vmessproxy = fmt.Sprintf("%s, ws=true,ws-path=%s", vmessproxy, proxy["ws-path"])
if vmess.Host != "" && vmess.Host != "none" {
vmessproxy = fmt.Sprintf("%s, ws-headers=Host:%s", vmessproxy, proxy["ws-host"])
}
}
if vmess.Sni != "" {
vmessproxy = fmt.Sprintf("%s, sni=%s", vmessproxy, vmess.Sni)
}
groups = append(groups, vmess.Ps)
proxys = append(proxys, vmessproxy)
case Scheme == "trojan":
trojan, err := DecodeTrojanURL(link)
if err != nil {
log.Println(err)
continue
}
proxy := map[string]interface{}{
"name": trojan.Name,
"server": trojan.Hostname,
"port": trojan.Port,
"password": trojan.Password,
"udp": sqlconfig.Udp,
"skip-cert-verify": sqlconfig.Cert,
}
trojanproxy := fmt.Sprintf("%s = trojan, %s, %d, password=%s, udp-relay=%t, skip-cert-verify=%t",
proxy["name"], proxy["server"], proxy["port"], proxy["password"], proxy["udp"], proxy["skip-cert-verify"])
if trojan.Query.Sni != "" {
trojanproxy = fmt.Sprintf("%s, sni=%s", trojanproxy, trojan.Query.Sni)
}
groups = append(groups, trojan.Name)
proxys = append(proxys, trojanproxy)
case Scheme == "hysteria2" || Scheme == "hy2":
hy2, err := DecodeHY2URL(link)
if err != nil {
log.Println(err)
continue
}
proxy := map[string]interface{}{
"name": hy2.Name,
"server": hy2.Host,
"port": hy2.Port,
"password": hy2.Password,
"udp": sqlconfig.Udp,
"skip-cert-verify": sqlconfig.Cert,
}
hy2proxy := fmt.Sprintf("%s = hysteria2, %s, %d, password=%s, udp-relay=%t, skip-cert-verify=%t",
proxy["name"], proxy["server"], proxy["port"], proxy["password"], proxy["udp"], proxy["skip-cert-verify"])
if hy2.Sni != "" {
hy2proxy = fmt.Sprintf("%s, sni=%s", hy2proxy, hy2.Sni)
}
groups = append(groups, hy2.Name)
proxys = append(proxys, hy2proxy)
case Scheme == "tuic":
tuic, err := DecodeTuicURL(link)
if err != nil {
log.Println(err)
continue
}
proxy := map[string]interface{}{
"name": tuic.Name,
"server": tuic.Host,
"port": tuic.Port,
"password": tuic.Password,
"udp": sqlconfig.Udp,
"skip-cert-verify": sqlconfig.Cert,
}
tuicproxy := fmt.Sprintf("%s = tuic, %s, %d, token=%s, udp-relay=%t, skip-cert-verify=%t",
proxy["name"], proxy["server"], proxy["port"], proxy["password"], proxy["udp"], proxy["skip-cert-verify"])
groups = append(groups, tuic.Name)
proxys = append(proxys, tuicproxy)
}
}
return DecodeSurge(proxys, groups, sqlconfig.Surge)
}
func DecodeSurge(proxys, groups []string, file string) (string, error) {
var surge []byte
var err error
if strings.Contains(file, "://") {
resp, err := http.Get(file)
if err != nil {
log.Println("http.Get error", err)
return "", err
}
defer resp.Body.Close()
surge, err = io.ReadAll(resp.Body)
if err != nil {
log.Printf("error: %v", err)
return "", err
}
} else {
surge, err = os.ReadFile(file)
if err != nil {
log.Println(err)
return "", err
}
}
proxyReg := regexp.MustCompile(`(?s)\[Proxy\](.*?)\[*]`)
groupReg := regexp.MustCompile(`(?s)\[Proxy Group\](.*?)\[*]`)
proxyPart := proxyReg.ReplaceAllStringFunc(string(surge), func(s string) string {
text := strings.Join(proxys, "\n")
return "[Proxy]\n" + text + s[len("[Proxy]"):]
})
groupPart := groupReg.ReplaceAllStringFunc(proxyPart, func(s string) string {
lines := strings.Split(s, "\n")
grouplist := strings.Join(groups, ",")
for i, line := range lines {
if strings.Contains(line, "=") {
lines[i] = strings.TrimSpace(line) + ", " + grouplist
// lines[i] = line + "," + grouplist
}
}
return strings.Join(lines, "\n") + s[len("[Proxy Group]"):]
})
return groupPart, nil
}