From 3e7f7aa94552a9c8eb68acbf65a008a4ed00bc41 Mon Sep 17 00:00:00 2001 From: Alireza Ahmadi Date: Sat, 27 Jun 2026 12:32:06 +0200 Subject: [PATCH] use external json sub #652 --- sub/clashService.go | 15 +++----------- sub/jsonService.go | 15 +++----------- sub/linkService.go | 50 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 24 deletions(-) diff --git a/sub/clashService.go b/sub/clashService.go index 5fac424..bdb075e 100644 --- a/sub/clashService.go +++ b/sub/clashService.go @@ -73,18 +73,9 @@ func (s *ClashService) GetClash(subId string) (*string, []string, error) { return nil, nil, err } - links := s.LinkService.GetLinks(&client.Links, "external", "") - tagNumEnable := 0 - if len(links) > 1 { - tagNumEnable = 1 - } - for index, link := range links { - json, tag, err := util.GetOutbound(link, (index+1)*tagNumEnable) - if err == nil && len(tag) > 0 { - *outbounds = append(*outbounds, *json) - *outTags = append(*outTags, tag) - } - } + extOutbounds, extTags := s.LinkService.GetExternalOutbounds(&client.Links) + *outbounds = append(*outbounds, extOutbounds...) + *outTags = append(*outTags, extTags...) basicConfig, err := s.getClashConfig() if err != nil || len(basicConfig) == 0 { diff --git a/sub/jsonService.go b/sub/jsonService.go index 14e8ac1..7eb9145 100644 --- a/sub/jsonService.go +++ b/sub/jsonService.go @@ -62,18 +62,9 @@ func (j *JsonService) GetJson(subId string, format string) (*string, []string, e return nil, nil, err } - links := j.LinkService.GetLinks(&client.Links, "external", "") - tagNumEnable := 0 - if len(links) > 1 { - tagNumEnable = 1 - } - for index, link := range links { - json, tag, err := util.GetOutbound(link, (index+1)*tagNumEnable) - if err == nil && len(tag) > 0 { - *outbounds = append(*outbounds, *json) - *outTags = append(*outTags, tag) - } - } + extOutbounds, extTags := j.LinkService.GetExternalOutbounds(&client.Links) + *outbounds = append(*outbounds, extOutbounds...) + *outTags = append(*outTags, extTags...) j.addDefaultOutbounds(outbounds, outTags) diff --git a/sub/linkService.go b/sub/linkService.go index 90b7ebc..3dcba01 100644 --- a/sub/linkService.go +++ b/sub/linkService.go @@ -2,6 +2,7 @@ package sub import ( "encoding/json" + "fmt" "strings" "github.com/alireza0/s-ui/logger" @@ -40,6 +41,55 @@ func (s *LinkService) GetLinks(linkJson *json.RawMessage, types string, clientIn return result } +func (s *LinkService) GetExternalOutbounds(linkJson *json.RawMessage) ([]map[string]interface{}, []string) { + links := []Link{} + err := json.Unmarshal(*linkJson, &links) + if err != nil { + return nil, nil + } + + var outbounds []map[string]interface{} + var tags []string + + for _, link := range links { + switch link.Type { + case "external": + outbound, tag, err := util.GetOutbound(link.Uri, 0) + if err == nil && outbound != nil && len(tag) > 0 { + outbounds = append(outbounds, *outbound) + tags = append(tags, tag) + } + case "sub": + subOutbounds, err := util.GetExternalSub(link.Uri) + if err != nil { + logger.Warning("sub: Error getting external sub:", err) + continue + } + for _, outbound := range subOutbounds { + if tag, _ := outbound["tag"].(string); len(tag) > 0 { + outbounds = append(outbounds, outbound) + tags = append(tags, tag) + } + } + } + } + + // Make tags unique; sing-box and clash reject duplicate tags/names. + seen := make(map[string]int) + for i, tag := range tags { + if n := seen[tag]; n > 0 { + newTag := fmt.Sprintf("%s-%d", tag, n) + seen[tag] = n + 1 + tags[i] = newTag + outbounds[i]["tag"] = newTag + } else { + seen[tag] = 1 + } + } + + return outbounds, tags +} + func (s *LinkService) addClientInfo(uri string, clientInfo string) string { if len(clientInfo) == 0 { return uri