package adapter import ( "encoding/json" "strings" "github.com/perfect-panel/server/internal/model/server" "github.com/perfect-panel/server/pkg/adapter/proxy" "github.com/perfect-panel/server/pkg/logger" "github.com/perfect-panel/server/pkg/random" "github.com/perfect-panel/server/pkg/tool" ) func addNode(data *server.Server, host string, port int) *proxy.Proxy { var option any node := proxy.Proxy{ Name: data.Name, Server: host, Port: port, Country: data.Country, Protocol: data.Protocol, } switch data.Protocol { case "shadowsocks": var ss proxy.Shadowsocks if err := json.Unmarshal([]byte(data.Config), &ss); err != nil { return nil } if port == 0 { node.Port = ss.Port } option = ss case "vless": var vless proxy.Vless if err := json.Unmarshal([]byte(data.Config), &vless); err != nil { return nil } if port == 0 { node.Port = vless.Port } option = vless case "vmess": var vmess proxy.Vmess if err := json.Unmarshal([]byte(data.Config), &vmess); err != nil { return nil } if port == 0 { node.Port = vmess.Port } option = vmess case "trojan": var trojan proxy.Trojan if err := json.Unmarshal([]byte(data.Config), &trojan); err != nil { return nil } if port == 0 { node.Port = trojan.Port } option = trojan case "hysteria2": var hysteria2 proxy.Hysteria2 if err := json.Unmarshal([]byte(data.Config), &hysteria2); err != nil { return nil } if port == 0 { node.Port = hysteria2.Port } option = hysteria2 case "tuic": var tuic proxy.Tuic if err := json.Unmarshal([]byte(data.Config), &tuic); err != nil { return nil } if port == 0 { node.Port = tuic.Port } option = tuic default: return nil } node.Option = option return &node } func addProxyToGroup(proxyName, groupName string, groups []proxy.Group) []proxy.Group { for i, group := range groups { if group.Name == groupName { groups[i].Proxies = tool.RemoveDuplicateElements(append(group.Proxies, proxyName)...) return groups } } groups = append(groups, proxy.Group{ Name: groupName, Type: proxy.GroupTypeSelect, Proxies: []string{proxyName}, }) return groups } func adapterRules(groups []*server.RuleGroup) (proxyGroup []proxy.Group, rules []string) { for _, group := range groups { 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")...) } return } func adapterTags(tags map[string][]*server.Server, group []proxy.Group) (proxyGroup []proxy.Group) { for tag, servers := range tags { proxies := adapterProxies(servers) if len(proxies) != 0 { for _, p := range proxies { group = addProxyToGroup(p.Name, tag, group) } } } return group } func generateProxyGroup(servers []proxy.Proxy) (proxyGroup []proxy.Group, region []string) { // 设置手动选择分组 proxyGroup = append(proxyGroup, []proxy.Group{ { Name: "智能线路", Type: proxy.GroupTypeURLTest, Proxies: make([]string, 0), URL: "https://www.gstatic.com/generate_204", Interval: 300, }, { Name: "手动选择", Type: proxy.GroupTypeSelect, Proxies: []string{"智能线路"}, }, }...) for _, node := range servers { if node.Country != "" { proxyGroup = addProxyToGroup(node.Name, node.Country, proxyGroup) region = append(region, node.Country) proxyGroup = addProxyToGroup(node.Country, "智能线路", proxyGroup) } proxyGroup = addProxyToGroup(node.Name, "手动选择", proxyGroup) } proxyGroup = addProxyToGroup("DIRECT", "手动选择", proxyGroup) return proxyGroup, tool.RemoveDuplicateElements(region...) } func adapterProxies(servers []*server.Server) []proxy.Proxy { var proxies []proxy.Proxy for _, node := range servers { switch node.RelayMode { case server.RelayModeAll: var relays []server.NodeRelay if err := json.Unmarshal([]byte(node.RelayNode), &relays); err != nil { logger.Errorw("Unmarshal RelayNode", logger.Field("error", err.Error()), logger.Field("node", node.Name), logger.Field("relayNode", node.RelayNode)) continue } for _, relay := range relays { n := addNode(node, relay.Host, relay.Port) if n == nil { continue } if relay.Prefix != "" { n.Name = relay.Prefix + "-" + n.Name } proxies = append(proxies, *n) } case server.RelayModeRandom: var relays []server.NodeRelay if err := json.Unmarshal([]byte(node.RelayNode), &relays); err != nil { logger.Errorw("Unmarshal RelayNode", logger.Field("error", err.Error()), logger.Field("node", node.Name), logger.Field("relayNode", node.RelayNode)) continue } randNum := random.RandomInRange(0, len(relays)-1) relay := relays[randNum] n := addNode(node, relay.Host, relay.Port) if n == nil { continue } if relay.Prefix != "" { n.Name = relay.Prefix + " - " + node.Name } proxies = append(proxies, *n) default: logger.Info("Not Relay Mode", logger.Field("node", node.Name), logger.Field("relayMode", node.RelayMode)) n := addNode(node, node.ServerAddr, 0) if n != nil { proxies = append(proxies, *n) } } } return proxies } // RemoveEmptyString 切片去除空值 func RemoveEmptyString(arr []string) []string { var result []string for _, str := range arr { if str != "" { result = append(result, str) } } return result } func RemoveEmptyGroup(arr []proxy.Group) []proxy.Group { var result []proxy.Group var removeNames []string for _, group := range arr { if group.Name == "手动选择" { group.Proxies = tool.RemoveStringElement(group.Proxies, removeNames...) } if len(group.Proxies) > 0 { result = append(result, group) } else { removeNames = append(removeNames, group.Name) } } return result }