package clash import ( "fmt" "github.com/perfect-panel/server/pkg/adapter/proxy" "github.com/perfect-panel/server/pkg/logger" "gopkg.in/yaml.v3" ) type Clash struct { proxy.Adapter } func NewClash(adapter proxy.Adapter) *Clash { return &Clash{ Adapter: adapter, } } func (c *Clash) Build(uuid string) ([]byte, error) { var proxies []Proxy for _, v := range c.Proxies { p, err := c.parseProxy(v, uuid) if err != nil { logger.Errorf("Failed to parse proxy for %s: %s", v.Name, err.Error()) continue } proxies = append(proxies, *p) } var rawConfig RawConfig if err := yaml.Unmarshal([]byte(DefaultTemplate), &rawConfig); err != nil { return nil, fmt.Errorf("failed to unmarshal template: %w", err) } rawConfig.Proxies = proxies // generate proxy groups var groups []ProxyGroup for _, group := range c.Group { groups = append(groups, ProxyGroup{ Name: group.Name, Type: string(group.Type), Proxies: group.Proxies, Url: group.URL, Interval: group.Interval, }) } rawConfig.ProxyGroups = groups rawConfig.Rules = append(c.Rules, "MATCH,手动选择") return yaml.Marshal(&rawConfig) } func (c *Clash) parseProxy(p proxy.Proxy, uuid string) (*Proxy, error) { parseFuncs := map[string]func(proxy.Proxy, string) (*Proxy, error){ "shadowsocks": parseShadowsocks, "trojan": parseTrojan, "vless": parseVless, "vmess": parseVmess, "hysteria2": parseHysteria2, "tuic": parseTuic, } if parseFunc, exists := parseFuncs[p.Protocol]; exists { return parseFunc(p, uuid) } logger.Errorw("Unknown protocol", logger.Field("protocol", p.Protocol), logger.Field("server", p.Name)) return nil, fmt.Errorf("unknown protocol: %s", p.Protocol) }