feat(proxy): enhance proxy group handling and sorting logic
This commit is contained in:
parent
979e39b9e5
commit
97024dd1df
@ -9,11 +9,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RelayModeNone = "none"
|
RelayModeNone = "none"
|
||||||
RelayModeAll = "all"
|
RelayModeAll = "all"
|
||||||
RelayModeRandom = "random"
|
RelayModeRandom = "random"
|
||||||
RuleGroupType = "ban"
|
RuleGroupTypeBan = "ban"
|
||||||
RuleGroupAuto = "auto"
|
RuleGroupTypeAuto = "auto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerFilter struct {
|
type ServerFilter struct {
|
||||||
|
|||||||
@ -26,17 +26,21 @@ type Adapter struct {
|
|||||||
func NewAdapter(cfg *Config) *Adapter {
|
func NewAdapter(cfg *Config) *Adapter {
|
||||||
// 转换服务器列表
|
// 转换服务器列表
|
||||||
proxies := adapterProxies(cfg.Nodes)
|
proxies := adapterProxies(cfg.Nodes)
|
||||||
// 生成代理组
|
defaultGroup := FindDefaultGroup(cfg.Rules)
|
||||||
proxyGroup, nodes := generateProxyGroup(proxies)
|
|
||||||
|
|
||||||
// 转换规则组
|
// 转换规则组
|
||||||
g, r := adapterRules(cfg.Rules)
|
g, r := adapterRules(cfg.Rules)
|
||||||
|
|
||||||
|
// 生成代理组
|
||||||
|
proxyGroup, nodes := generateProxyGroup(proxies)
|
||||||
|
|
||||||
// 加入兜底节点
|
// 加入兜底节点
|
||||||
for i, group := range g {
|
for i, group := range g {
|
||||||
|
if group.Direct {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if len(group.Proxies) == 0 {
|
if len(group.Proxies) == 0 {
|
||||||
p := append([]string{"智能线路"}, nodes...)
|
p := append([]string{"Auto Select", "Selection"}, nodes...)
|
||||||
g[i].Proxies = append(p, "REJECT", "DIRECT")
|
g[i].Proxies = append(p, "DIRECT")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,12 +48,14 @@ func NewAdapter(cfg *Config) *Adapter {
|
|||||||
proxyGroup = RemoveEmptyGroup(append(proxyGroup, g...))
|
proxyGroup = RemoveEmptyGroup(append(proxyGroup, g...))
|
||||||
// 处理标签
|
// 处理标签
|
||||||
proxyGroup = adapterTags(cfg.Tags, proxyGroup)
|
proxyGroup = adapterTags(cfg.Tags, proxyGroup)
|
||||||
|
|
||||||
return &Adapter{
|
return &Adapter{
|
||||||
Adapter: proxy.Adapter{
|
Adapter: proxy.Adapter{
|
||||||
Proxies: proxies,
|
Proxies: proxies,
|
||||||
Group: proxyGroup,
|
Group: SortGroups(proxyGroup, defaultGroup),
|
||||||
Rules: r,
|
Rules: r,
|
||||||
Nodes: nodes,
|
Nodes: nodes,
|
||||||
|
Default: defaultGroup,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@ func (c *Clash) Build(uuid string) ([]byte, error) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
rawConfig.ProxyGroups = groups
|
rawConfig.ProxyGroups = groups
|
||||||
rawConfig.Rules = append(c.Rules, "MATCH,手动选择")
|
rawConfig.Rules = append(c.Rules, fmt.Sprintf("MATCH,%s", c.Default))
|
||||||
return yaml.Marshal(&rawConfig)
|
return yaml.Marshal(&rawConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,7 @@ type Group struct {
|
|||||||
Proxies []string
|
Proxies []string
|
||||||
URL string
|
URL string
|
||||||
Interval int
|
Interval int
|
||||||
|
Direct bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type GroupType string
|
type GroupType string
|
||||||
|
|||||||
@ -79,7 +79,7 @@ func BuildSingbox(adapter proxy.Adapter, uuid string) ([]byte, error) {
|
|||||||
|
|
||||||
rawConfig["outbounds"] = proxies
|
rawConfig["outbounds"] = proxies
|
||||||
route := RouteOptions{
|
route := RouteOptions{
|
||||||
Final: "手动选择",
|
Final: adapter.Default,
|
||||||
Rules: []Rule{
|
Rules: []Rule{
|
||||||
{
|
{
|
||||||
Inbound: []string{
|
Inbound: []string{
|
||||||
@ -114,7 +114,7 @@ func BuildSingbox(adapter proxy.Adapter, uuid string) ([]byte, error) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
ClashMode: "global",
|
ClashMode: "global",
|
||||||
Outbound: "手动选择",
|
Outbound: adapter.Default,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
IPIsPrivate: true,
|
IPIsPrivate: true,
|
||||||
|
|||||||
@ -99,11 +99,29 @@ func addProxyToGroup(proxyName, groupName string, groups []proxy.Group) []proxy.
|
|||||||
|
|
||||||
func adapterRules(groups []*server.RuleGroup) (proxyGroup []proxy.Group, rules []string) {
|
func adapterRules(groups []*server.RuleGroup) (proxyGroup []proxy.Group, rules []string) {
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
proxyGroup = append(proxyGroup, proxy.Group{
|
switch group.Type {
|
||||||
Name: group.Name,
|
case server.RuleGroupTypeBan:
|
||||||
Type: proxy.GroupTypeSelect,
|
proxyGroup = append(proxyGroup, proxy.Group{
|
||||||
Proxies: RemoveEmptyString(strings.Split(group.Tags, ",")),
|
Name: group.Name,
|
||||||
})
|
Type: proxy.GroupTypeSelect,
|
||||||
|
Proxies: []string{"REJECT", "DIRECT"},
|
||||||
|
Direct: true,
|
||||||
|
})
|
||||||
|
case server.RuleGroupTypeAuto:
|
||||||
|
proxyGroup = append(proxyGroup, proxy.Group{
|
||||||
|
Name: group.Name,
|
||||||
|
Type: proxy.GroupTypeURLTest,
|
||||||
|
URL: "https://www.gstatic.com/generate_204",
|
||||||
|
Proxies: RemoveEmptyString(strings.Split(group.Tags, ",")),
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
proxyGroup = append(proxyGroup, proxy.Group{
|
||||||
|
Name: group.Name,
|
||||||
|
Type: proxy.GroupTypeSelect,
|
||||||
|
Proxies: RemoveEmptyString(strings.Split(group.Tags, ",")),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
rules = append(rules, strings.Split(group.Rules, "\n")...)
|
rules = append(rules, strings.Split(group.Rules, "\n")...)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -122,29 +140,26 @@ func adapterTags(tags map[string][]*server.Server, group []proxy.Group) (proxyGr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateProxyGroup(servers []proxy.Proxy) (proxyGroup []proxy.Group, nodes []string) {
|
func generateProxyGroup(servers []proxy.Proxy) (proxyGroup []proxy.Group, nodes []string) {
|
||||||
|
proxyGroup = append(proxyGroup, proxy.Group{
|
||||||
|
Name: "Auto Select",
|
||||||
|
Type: proxy.GroupTypeURLTest,
|
||||||
|
Proxies: make([]string, 0),
|
||||||
|
URL: "https://www.gstatic.com/generate_204",
|
||||||
|
Interval: 300,
|
||||||
|
})
|
||||||
|
|
||||||
// 设置手动选择分组
|
// 设置手动选择分组
|
||||||
proxyGroup = append(proxyGroup, []proxy.Group{
|
proxyGroup = append(proxyGroup, proxy.Group{
|
||||||
{
|
Name: "Selection",
|
||||||
Name: "智能线路",
|
Type: proxy.GroupTypeSelect,
|
||||||
Type: proxy.GroupTypeURLTest,
|
Proxies: []string{"Auto Select"},
|
||||||
Proxies: make([]string, 0),
|
})
|
||||||
URL: "https://www.gstatic.com/generate_204",
|
|
||||||
Interval: 300,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "手动选择",
|
|
||||||
Type: proxy.GroupTypeSelect,
|
|
||||||
Proxies: []string{"智能线路"},
|
|
||||||
},
|
|
||||||
}...)
|
|
||||||
|
|
||||||
for _, node := range servers {
|
for _, node := range servers {
|
||||||
proxyGroup = addProxyToGroup(node.Name, "智能线路", proxyGroup)
|
proxyGroup = addProxyToGroup(node.Name, "Auto Select", proxyGroup)
|
||||||
proxyGroup = addProxyToGroup(node.Name, "手动选择", proxyGroup)
|
proxyGroup = addProxyToGroup(node.Name, "Selection", proxyGroup)
|
||||||
nodes = append(nodes, node.Name)
|
nodes = append(nodes, node.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyGroup = addProxyToGroup("DIRECT", "手动选择", proxyGroup)
|
|
||||||
return proxyGroup, tool.RemoveDuplicateElements(nodes...)
|
return proxyGroup, tool.RemoveDuplicateElements(nodes...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,6 +221,7 @@ func RemoveEmptyString(arr []string) []string {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveEmptyGroup removes empty groups from the provided slice of proxy groups.
|
||||||
func RemoveEmptyGroup(arr []proxy.Group) []proxy.Group {
|
func RemoveEmptyGroup(arr []proxy.Group) []proxy.Group {
|
||||||
var result []proxy.Group
|
var result []proxy.Group
|
||||||
var removeNames []string
|
var removeNames []string
|
||||||
@ -221,3 +237,56 @@ func RemoveEmptyGroup(arr []proxy.Group) []proxy.Group {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindDefaultGroup finds the default rule group from a list of rule groups.
|
||||||
|
func FindDefaultGroup(groups []*server.RuleGroup) string {
|
||||||
|
for _, group := range groups {
|
||||||
|
if group.Default {
|
||||||
|
return group.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "智能线路"
|
||||||
|
}
|
||||||
|
|
||||||
|
// SortGroups sorts the provided slice of proxy groups by their names.
|
||||||
|
func SortGroups(groups []proxy.Group, defaultName string) []proxy.Group {
|
||||||
|
var sortedGroups []proxy.Group
|
||||||
|
var selectedGroup proxy.Group
|
||||||
|
// 在所有分组找到默认分组并将他放到第一个
|
||||||
|
for _, group := range groups {
|
||||||
|
if group.Name == defaultName {
|
||||||
|
group.Proxies = tool.RemoveStringElement(group.Proxies, defaultName, "REJECT")
|
||||||
|
sortedGroups = append([]proxy.Group{group}, sortedGroups...)
|
||||||
|
continue
|
||||||
|
} else if group.Name == "Selection" {
|
||||||
|
group.Proxies = tool.RemoveStringElement(group.Proxies, defaultName)
|
||||||
|
selectedGroup = group
|
||||||
|
continue
|
||||||
|
} else if group.Name == "Auto Select" {
|
||||||
|
group.Proxies = tool.RemoveStringElement(group.Proxies, defaultName, group.Name)
|
||||||
|
sortedGroups = append([]proxy.Group{group}, sortedGroups...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sortedGroups = append(sortedGroups, group)
|
||||||
|
}
|
||||||
|
// 将手动选择分组放到最后
|
||||||
|
if selectedGroup.Name != "" {
|
||||||
|
sortedGroups = append(sortedGroups, selectedGroup)
|
||||||
|
}
|
||||||
|
return sortedGroups
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveElementByName removes elements from the slice of proxy groups by their names.
|
||||||
|
func RemoveElementByName(groups []proxy.Group, names ...string) []proxy.Group {
|
||||||
|
for i := 0; i < len(groups); i++ {
|
||||||
|
for _, name := range names {
|
||||||
|
if groups[i].Name == name {
|
||||||
|
groups = append(groups[:i], groups[i+1:]...)
|
||||||
|
i-- // Adjust index after removal
|
||||||
|
break // Exit inner loop to avoid index out of range
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groups
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user