diff --git a/pkg/adapter/surfboard/build.go b/pkg/adapter/surfboard/build.go index db3c63c..0c7ea4d 100644 --- a/pkg/adapter/surfboard/build.go +++ b/pkg/adapter/surfboard/build.go @@ -4,7 +4,6 @@ import ( "bytes" "embed" "fmt" - "net/url" "strings" "text/template" "time" @@ -23,42 +22,22 @@ var shadowsocksSupportMethod = []string{"aes-128-gcm", "aes-192-gcm", "aes-256-g func BuildSurfboard(servers proxy.Adapter, siteName string, user UserInfo) []byte { var proxies, proxyGroup string var removed []string - for _, node := range servers.Proxies { - if uri := buildProxy(node, user.UUID); uri != "" { - proxies += uri - } else { - removed = append(removed, node.Name) + var ps []string + + for _, p := range servers.Proxies { + switch p.Protocol { + case "shadowsocks": + proxies += buildShadowsocks(p, user.UUID) + case "trojan": + proxies += buildTrojan(p, user.UUID) + case "vmess": + proxies += buildVMess(p, user.UUID) + default: + removed = append(removed, p.Name) } + ps = append(ps, p.Name) } - for _, group := range servers.Group { - - if len(removed) > 0 { - group.Proxies = tool.RemoveStringElement(group.Proxies, removed...) - } - - if group.Type == proxy.GroupTypeSelect { - proxyGroup += fmt.Sprintf("%s = select, %s", group.Name, strings.Join(group.Proxies, ", ")) + "\r\n" - } else if group.Type == proxy.GroupTypeURLTest { - proxyGroup += fmt.Sprintf("%s = url-test, %s, url=%s, interval=%d", group.Name, strings.Join(group.Proxies, ", "), group.URL, group.Interval) + "\r\n" - } else if group.Type == proxy.GroupTypeFallback { - proxyGroup += fmt.Sprintf("%s = fallback, %s, url=%s, interval=%d", group.Name, strings.Join(group.Proxies, ", "), group.URL, group.Interval) + "\r\n" - } else { - logger.Errorf("[BuildSurfboard] unknown group type: %s", group.Type) - } - } - - var rules string - for _, rule := range servers.Rules { - if rule == "" { - continue - } - rules += rule + "\r\n" - } - - //final rule - rules += "FINAL, 手动选择" - file, err := configFiles.ReadFile("default.tpl") if err != nil { logger.Errorf("read default surfboard config error: %v", err.Error()) @@ -78,42 +57,24 @@ func BuildSurfboard(servers proxy.Adapter, siteName string, user UserInfo) []byt } else { expiredAt = user.ExpiredDate.Format("2006-01-02 15:04:05") } + + ps = tool.RemoveStringElement(ps, removed...) + proxyGroup = strings.Join(ps, ",") + // convert traffic upload := traffic.AutoConvert(user.Upload, false) download := traffic.AutoConvert(user.Download, false) total := traffic.AutoConvert(user.TotalTraffic, false) unusedTraffic := traffic.AutoConvert(user.TotalTraffic-user.Upload-user.Download, false) // query Host - urlParse, err := url.Parse(user.SubscribeURL) - if err != nil { - return nil - } if err := tpl.Execute(&buf, map[string]interface{}{ - "Proxies": proxies, - "ProxyGroup": proxyGroup, - "SubscribeURL": user.SubscribeURL, - "SubscribeInfo": fmt.Sprintf("title=%s订阅信息, content=上传流量:%s\\n下载流量:%s\\n剩余流量: %s\\n套餐流量:%s\\n到期时间:%s", siteName, upload, download, unusedTraffic, total, expiredAt), - "SubscribeDomain": urlParse.Host, - "Rules": rules, + "Proxies": proxies, + "ProxyGroup": proxyGroup, + "SubscribeURL": user.SubscribeURL, + "SubscribeInfo": fmt.Sprintf("title=%s订阅信息, content=上传流量:%s\\n下载流量:%s\\n剩余流量: %s\\n套餐流量:%s\\n到期时间:%s", siteName, upload, download, unusedTraffic, total, expiredAt), }); err != nil { - logger.Errorf("build surfboard config error: %v", err.Error()) + logger.Errorf("build Surge config error: %v", err.Error()) return nil } return buf.Bytes() } - -func buildProxy(data proxy.Proxy, uuid string) string { - var p string - switch data.Protocol { - case "vmess": - p = buildVMess(data, uuid) - case "shadowsocks": - if !tool.Contains(shadowsocksSupportMethod, data.Option.(proxy.Shadowsocks).Method) { - return "" - } - p = buildShadowsocks(data, uuid) - case "trojan": - p = buildTrojan(data, uuid) - } - return p -} diff --git a/pkg/adapter/surfboard/default.tpl b/pkg/adapter/surfboard/default.tpl index e30aac0..89c48fe 100644 --- a/pkg/adapter/surfboard/default.tpl +++ b/pkg/adapter/surfboard/default.tpl @@ -1,29 +1,62 @@ -#!MANAGED-CONFIG {{ .SubscribeURL }} interval=43200 strict=true +#!MANAGED-CONFIG {{.SubscribeURL}} interval=43200 strict=true [General] -loglevel = notify -ipv6 = false -skip-proxy = localhost, *.local, injections.adguard.org, local.adguard.org, 0.0.0.0/8, 10.0.0.0/8, 17.0.0.0/8, 100.64.0.0/10, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.2.0/24, 192.168.0.0/16, 192.88.99.0/24, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 224.0.0.0/4, 240.0.0.0/4, 255.255.255.255/32 -tls-provider = default -show-error-page-for-reject = true -dns-server = 223.6.6.6, 119.29.29.29, 119.28.28.28 +dns-server = system, 119.29.29.29, 223.5.5.5 +skip-proxy = 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 127.0.0.0/8, localhost, *.local +always-real-ip = *.lan, lens.l.google.com, *.srv.nintendo.net, *.stun.playstation.net, *.xboxlive.com, xbox.*.*.microsoft.com, *.msftncsi.com, *.msftconnecttest.com +proxy-test-url = http://www.gstatic.com/generate_204 +internet-test-url = http://connectivitycheck.platform.hicloud.com/generate_204 test-timeout = 5 -internet-test-url = http://bing.com -proxy-test-url = http://bing.com +http-listen = 0.0.0.0:6088 +socks5-listen = 0.0.0.0:6089 [Panel] -SubscribeInfo = {{ .SubscribeInfo }}, style=info - -# Surfboard 配置文档:https://manual.getsurfboard.com/ +SubscribeInfo = {{.SubscribeInfo}}, style=info [Proxy] -# 代理列表 -{{ .Proxies }} +{{.Proxies}} [Proxy Group] -# 代理组列表 -{{ .ProxyGroup }} +🚀 Proxy = select, 🌏 Auto, 🎯 Direct, include-other-group=🇺🇳 Nodes +🍎 Apple = select, 🚀 Proxy, 🎯 Direct, include-other-group=🇺🇳 Nodes +🔍 Google = select, 🚀 Proxy, 🎯 Direct, include-other-group=🇺🇳 Nodes +🪟 Microsoft = select, 🚀 Proxy, 🎯 Direct, include-other-group=🇺🇳 Nodes +📺 GlobalMedia = select, 🚀 Proxy, 🎯 Direct, include-other-group=🇺🇳 Nodes +🤖 AI = select, 🚀 Proxy, 🎯 Direct, include-other-group=🇺🇳 Nodes +🪙 Crypto = select, 🚀 Proxy, 🎯 Direct, include-other-group=🇺🇳 Nodes +🎮 Game = select, 🚀 Proxy, 🎯 Direct, include-other-group=🇺🇳 Nodes +📟 Telegram = select, 🚀 Proxy, 🎯 Direct, include-other-group=🇺🇳 Nodes +🇨🇳 China = select, 🎯 Direct, 🚀 Proxy, include-other-group=🇺🇳 Nodes +🐠 Final = select, 🎯 Direct, 🚀 Proxy, include-other-group=🇺🇳 Nodes +🌏 Auto = fallback, include-other-group=🇺🇳 Nodes, url=http://www.gstatic.com/generate_204, interval=600, timeout=5 +🎯 Direct = select, DIRECT, hidden=1 +🇺🇳 Nodes = select, {{.ProxyGroup}}, hidden=1 [Rule] -# 规则列表 -{{ .Rules }} +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Apple/Apple_All.list, 🍎 Apple +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Google/Google.list, 🔍 Google +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/GitHub/GitHub.list, 🪟 Microsoft +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Microsoft/Microsoft.list, 🪟 Microsoft +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/HBO/HBO.list, 📺 GlobalMedia +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Disney/Disney.list, 📺 GlobalMedia +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/TikTok/TikTok.list, 📺 GlobalMedia +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Netflix/Netflix.list, 📺 GlobalMedia +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/GlobalMedia/GlobalMedia_All_No_Resolve.list, 📺 GlobalMedia +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Telegram/Telegram.list, 📟 Telegram +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/OpenAI/OpenAI.list, 🤖 AI +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Gemini/Gemini.list, 🤖 AI +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Copilot/Copilot.list, 🤖 AI +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Claude/Claude.list, 🤖 AI +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Crypto/Crypto.list, 🪙 Crypto +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Cryptocurrency/Cryptocurrency.list, 🪙 Crypto +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Game/Game.list, 🎮 Game +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Global/Global_All_No_Resolve.list, 🚀 Proxy +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/ChinaMax/ChinaMax_All_No_Resolve.list, 🇨🇳 China +RULE-SET, https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/refs/heads/master/rule/Surge/Lan/Lan.list, 🎯 Direct + +GEOIP, CN, 🇨🇳 China +FINAL, 🐠 Final, dns-failed + +[URL Rewrite] +^https?:\/\/(www.)?g\.cn https://www.google.com 302 +^https?:\/\/(www.)?google\.cn https://www.google.com 302 \ No newline at end of file