server/pkg/adapter/uilts.go
2025-04-28 17:31:07 +09:00

226 lines
5.7 KiB
Go

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: "select",
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: "select",
Proxies: RemoveEmptyString(strings.Split(group.Tags, ",")),
})
rules = append(rules, strings.Split(group.Rules, "/n")...)
}
return
}
func generateProxyGroup(servers []proxy.Proxy) (proxyGroup []proxy.Group, region []string) {
// 设置手动选择分组
proxyGroup = append(proxyGroup, []proxy.Group{
{
Name: "智能线路",
Type: "url-test",
Proxies: make([]string, 0),
URL: "https://www.gstatic.com/generate_204",
Interval: 300,
},
{
Name: "手动选择",
Type: "select",
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
}
// RemoveElement 移除指定元素
func RemoveElement(arr []string, element ...string) []string {
var result []string
for _, str := range arr {
if !tool.Contains(element, str) {
logger.Infof("Remove Element: %s", 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 = RemoveElement(group.Proxies, removeNames...)
}
if len(group.Proxies) > 0 {
result = append(result, group)
} else {
removeNames = append(removeNames, group.Name)
}
}
return result
}