diff --git a/internal/filter/collection_rename.go b/internal/filter/collection_rename.go index 93a588c..278fc40 100644 --- a/internal/filter/collection_rename.go +++ b/internal/filter/collection_rename.go @@ -30,17 +30,18 @@ func resolveRenameOptions(opts *model.RenameOptions) model.RenameOptions { // RenameCollectionNodes renames proxy nodes in the collection-level format: // -// [emoji country flag] [alias] [country name] [city] [-1...-N] +// [emoji country flag] [alias] [country name] [city] [01...NN] // // The alias is read from each node's "_sourceAlias" field (tagged by the // subscription service from the source's Alias). Geographic info (flag, // country, city) is auto-detected from the node's original name and server. // // Nodes are grouped by their **display baseName** (the name without the index -// suffix) and numbered sequentially within each group, starting at 1. This -// ensures that nodes producing the same display name get unique suffixes -// (-1, -2, -3, …) in a single pass, so EnsureUniqueProxyNames never needs to -// append a secondary suffix. +// suffix) and numbered sequentially within each group, starting at 1. +// +// Nodes whose geographic info cannot be detected (no country found) are +// dropped from the output — they cannot be meaningfully renamed and would +// appear as unlabelled entries in the collection. // // opts controls which fields are included in the output. A nil opts means all // fields are included (full default format). @@ -54,13 +55,12 @@ func RenameCollectionNodes(proxies []model.ProxyNode, opts *model.RenameOptions) // First pass: compute display baseName (without index) for each node. type nodeInfo struct { proxy model.ProxyNode - baseName string // display name without index suffix; "" means skip rename + baseName string // display name without index suffix; "" means geo failed } - infos := make([]nodeInfo, len(proxies)) - for i, proxy := range proxies { + infos := make([]nodeInfo, 0, len(proxies)) + for _, proxy := range proxies { if proxy == nil { - infos[i] = nodeInfo{proxy: proxy} continue } @@ -70,7 +70,7 @@ func RenameCollectionNodes(proxies []model.ProxyNode, opts *model.RenameOptions) geo := util.DetectGeoWithServer(name, server) if geo.CountryName == "" { - infos[i] = nodeInfo{proxy: proxy} + // Geo detection failed — skip this node continue } @@ -96,34 +96,22 @@ func RenameCollectionNodes(proxies []model.ProxyNode, opts *model.RenameOptions) parts = append(parts, geo.CityCN) } - infos[i] = nodeInfo{ + infos = append(infos, nodeInfo{ proxy: proxy, baseName: strings.Join(parts, " "), - } + }) } // Count group sizes by baseName. baseCounts := make(map[string]int) for _, info := range infos { - if info.baseName != "" { - baseCounts[info.baseName]++ - } + baseCounts[info.baseName]++ } // Second pass: assign names with sequential numbering. counters := make(map[string]int) - results := make([]model.ProxyNode, len(proxies)) - for i, info := range infos { - if info.proxy == nil { - results[i] = info.proxy - continue - } - if info.baseName == "" { - // Geo detection failed — keep original name. - results[i] = info.proxy - continue - } - + results := make([]model.ProxyNode, 0, len(infos)) + for _, info := range infos { counters[info.baseName]++ total := baseCounts[info.baseName] @@ -135,7 +123,7 @@ func RenameCollectionNodes(proxies []model.ProxyNode, opts *model.RenameOptions) next := cloneProxy(info.proxy) delete(next, "_sourceAlias") next["name"] = name - results[i] = next + results = append(results, next) } return results diff --git a/internal/filter/collection_rename_test.go b/internal/filter/collection_rename_test.go index 4c9cd87..c54b42c 100644 --- a/internal/filter/collection_rename_test.go +++ b/internal/filter/collection_rename_test.go @@ -110,12 +110,8 @@ func TestRenameCollectionNodes_UnknownCountry(t *testing.T) { {"name": "Unknown Node", "type": "ss", "_sourceAlias": "A"}, } result := RenameCollectionNodes(proxies, nil) - if len(result) != 1 { - t.Fatalf("expected 1 node, got %d", len(result)) - } - // Should keep original name - if result[0]["name"] != "Unknown Node" { - t.Errorf("expected original name, got %q", result[0]["name"]) + if len(result) != 0 { + t.Fatalf("expected 0 nodes (geo detection failed, should be filtered), got %d", len(result)) } }