feat: merge default proxy groups of all subscription

This commit is contained in:
2026-07-20 15:00:11 +08:00
parent 2b73f83a2a
commit 7ff3daa9d3
4 changed files with 172 additions and 2 deletions

View File

@ -1,5 +1,7 @@
package corecfg
import "gitea.epss.net.cn/klesh/ss/internal/automation"
// deepMerge merges dict2 into dict1 in place and returns dict1, mirroring
// corecfg_manager.py's module-level deep_merge(): nested maps recurse,
// matching lists are concatenated, everything else is overwritten by dict2.
@ -25,3 +27,74 @@ func deepMerge(dict1, dict2 map[string]interface{}) map[string]interface{} {
}
return dict1
}
// popFirstProxyGroup removes and returns data["proxy-groups"]' first entry —
// by convention a subscription's default selector group, the one its own
// rules point at — so mergeProxySelection can fold every subscription's
// default selector into one combined group. Returns nil if there is none.
func popFirstProxyGroup(data map[string]interface{}) map[string]interface{} {
groupsRaw, ok := data["proxy-groups"].([]interface{})
if !ok || len(groupsRaw) == 0 {
return nil
}
group, ok := groupsRaw[0].(map[string]interface{})
if !ok {
return nil
}
data["proxy-groups"] = groupsRaw[1:]
return group
}
// selectionGroupName is the name given to the proxy-group produced by
// folding every merged subscription's default selector group together.
const selectionGroupName = "Proxy Selection"
// mergeProxySelection collapses each subscription's default selector group
// (already popped off by popFirstProxyGroup) into a single combined group
// named selectionGroupName, covering every subscription's proxies, and
// rewrites every rule/group reference to the old per-subscription groups so
// they point at it instead.
func mergeProxySelection(combined map[string]interface{}, groups []map[string]interface{}) {
if len(groups) == 0 {
return
}
rename := make(map[string]string, len(groups))
seen := make(map[string]bool)
var groupType interface{}
var mergedProxies []interface{}
for _, group := range groups {
if name, ok := group["name"].(string); ok {
rename[name] = selectionGroupName
}
if groupType == nil {
groupType = group["type"]
}
if list, ok := group["proxies"].([]interface{}); ok {
for _, p := range list {
name, ok := p.(string)
if ok && seen[name] {
continue
}
if ok {
seen[name] = true
}
mergedProxies = append(mergedProxies, p)
}
}
}
merged := map[string]interface{}{
"name": selectionGroupName,
"type": groupType,
"proxies": mergedProxies,
}
existing, _ := combined["proxy-groups"].([]interface{})
combined["proxy-groups"] = append([]interface{}{merged}, existing...)
automation.RewriteReferences(combined, rename)
}