From 6f075ea44e868058ff07fe4a8f26ce26bc0bb4a7 Mon Sep 17 00:00:00 2001 From: nitezs Date: Mon, 25 Sep 2023 23:58:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=B0=86=E8=AE=A2?= =?UTF-8?q?=E9=98=85=E5=90=8D=E7=A7=B0=E6=B7=BB=E5=8A=A0=E5=88=B0=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=90=8D=E4=B8=AD=E7=9A=84=E5=8A=9F=E8=83=BD=20feat:?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E5=9C=B0=E5=8C=BA=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- API_README.md | 2 +- README.md | 1 + api/controller/default.go | 48 +++++++++++++++++++++++++++++++++------ model/proxy.go | 1 + utils/proxy.go | 9 ++++---- 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/API_README.md b/API_README.md index 0959b57..57ed577 100644 --- a/API_README.md +++ b/API_README.md @@ -4,7 +4,7 @@ | Query 参数 | 类型 | 是否必须 | 默认值 | 说明 | |--------------|--------|-------------------|-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| sub | string | sub/proxy 至少有一项存在 | - | 订阅链接(可以输入多个,用 `,` 分隔) | +| sub | string | sub/proxy 至少有一项存在 | - | 订阅链接,可以在链接结尾加上`#名称`,来给订阅中的节点加上统一前缀(可以输入多个,用 `,` 分隔) | | proxy | string | sub/proxy 至少有一项存在 | - | 节点分享链接(可以输入多个,用 `,` 分隔) | | refresh | bool | 否 | `false` | 强制刷新配置(默认缓存 5 分钟) | | template | string | 否 | - | 外部模板链接或内部模板名称 | diff --git a/README.md b/README.md index 3d87036..7d3e183 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ - `` 为添加所有节点 - `` 为添加所有国家策略组 +- `<地区二位字母代码>` 为添加指定地区所有节点,例如 `` 将添加所有香港节点 #### 默认模板 diff --git a/api/controller/default.go b/api/controller/default.go index e0eed50..0f2676f 100644 --- a/api/controller/default.go +++ b/api/controller/default.go @@ -58,6 +58,10 @@ func BuildSub(clashType model.ClashType, query validator.SubValidator, template // 加载订阅 for i := range query.Subs { data, err := utils.LoadSubscription(query.Subs[i], query.Refresh) + subName := "" + if strings.Contains(query.Subs[i], "#") { + subName = query.Subs[i][strings.LastIndex(query.Subs[i], "#")+1:] + } if err != nil { logger.Logger.Debug( "load subscription failed", zap.String("url", query.Subs[i]), zap.Error(err), @@ -66,11 +70,12 @@ func BuildSub(clashType model.ClashType, query validator.SubValidator, template } // 解析订阅 err = yaml.Unmarshal(data, &sub) + newProxies := make([]model.Proxy, 0) if err != nil { reg, _ := regexp.Compile("(ssr|ss|vmess|trojan|vless)://") if reg.Match(data) { p := utils.ParseProxy(strings.Split(string(data), "\n")...) - proxyList = append(proxyList, p...) + newProxies = p } else { // 如果无法直接解析,尝试Base64解码 base64, err := parser.DecodeBase64(string(data)) @@ -83,16 +88,28 @@ func BuildSub(clashType model.ClashType, query validator.SubValidator, template return nil, errors.New("加载订阅失败: " + err.Error()) } p := utils.ParseProxy(strings.Split(base64, "\n")...) - proxyList = append(proxyList, p...) + newProxies = p } } else { - proxyList = append(proxyList, sub.Proxies...) + newProxies = sub.Proxies } + if subName != "" { + for i := range newProxies { + newProxies[i].SubName = subName + } + } + proxyList = append(proxyList, newProxies...) } // 添加自定义节点 if len(query.Proxies) != 0 { proxyList = append(proxyList, utils.ParseProxy(query.Proxies...)...) } + // 给节点添加订阅名称 + for i := range proxyList { + if proxyList[i].SubName != "" { + proxyList[i].Name = strings.TrimSpace(proxyList[i].SubName) + " " + strings.TrimSpace(proxyList[i].Name) + } + } // 去掉配置相同的节点 proxies := make(map[string]*model.Proxy) newProxies := make([]model.Proxy, 0, len(proxyList)) @@ -233,11 +250,28 @@ func MergeSubAndTemplate(temp *model.Subscription, sub *model.Subscription) { continue } newProxies := make([]string, 0, len(temp.ProxyGroups[i].Proxies)) + countryGroupMap := make(map[string]model.ProxyGroup) + for _, v := range sub.ProxyGroups { + if v.IsCountryGrop { + countryGroupMap[v.Name] = v + } + } for j := range temp.ProxyGroups[i].Proxies { - if temp.ProxyGroups[i].Proxies[j] == "" { - newProxies = append(newProxies, proxyNames...) - } else if temp.ProxyGroups[i].Proxies[j] == "" { - newProxies = append(newProxies, countryGroupNames...) + reg := regexp.MustCompile("<(.*?)>") + if reg.Match([]byte(temp.ProxyGroups[i].Proxies[j])) { + key := reg.FindStringSubmatch(temp.ProxyGroups[i].Proxies[j])[1] + switch key { + case "all": + newProxies = append(newProxies, proxyNames...) + case "countries": + newProxies = append(newProxies, countryGroupNames...) + default: + if len(key) == 2 { + newProxies = append( + newProxies, countryGroupMap[utils.GetContryName(key)].Proxies..., + ) + } + } } else { newProxies = append(newProxies, temp.ProxyGroups[i].Proxies[j]) } diff --git a/model/proxy.go b/model/proxy.go index b6784a9..a8faee1 100644 --- a/model/proxy.go +++ b/model/proxy.go @@ -44,6 +44,7 @@ type Proxy struct { AuthenticatedLength bool `yaml:"authenticated-length,omitempty"` UDPOverTCP bool `yaml:"udp-over-tcp,omitempty"` UDPOverTCPVersion int `yaml:"udp-over-tcp-version,omitempty"` + SubName string `yaml:"-"` } func (p Proxy) MarshalYAML() (interface{}, error) { diff --git a/utils/proxy.go b/utils/proxy.go index b16f8d8..a6ba7bd 100644 --- a/utils/proxy.go +++ b/utils/proxy.go @@ -8,7 +8,7 @@ import ( "sub2clash/parser" ) -func GetContryName(proxy model.Proxy) string { +func GetContryName(countryKey string) string { // 创建一个切片包含所有的国家映射 countryMaps := []map[string]string{ model.CountryFlag, @@ -25,7 +25,7 @@ func GetContryName(proxy model.Proxy) string { splitChars := []string{"-", "_", " "} key := make([]string, 0) for _, splitChar := range splitChars { - slic := strings.Split(proxy.Name, splitChar) + slic := strings.Split(countryKey, splitChar) for _, v := range slic { if len(v) == 2 { key = append(key, v) @@ -41,12 +41,11 @@ func GetContryName(proxy model.Proxy) string { } } for k, v := range countryMap { - if strings.Contains(proxy.Name, k) { + if strings.Contains(countryKey, k) { return v } } } - return "其他地区" } @@ -62,7 +61,7 @@ func AddProxy( } sub.Proxies = append(sub.Proxies, proxy) haveProxyGroup := false - countryName := GetContryName(proxy) + countryName := GetContryName(proxy.Name) for i := range sub.ProxyGroups { group := &sub.ProxyGroups[i]