package generator import ( "encoding/json" "fmt" "github.com/subconverter-go/internal/logging" "github.com/subconverter-go/internal/parser" ) // V2RayGenerator V2Ray格式生成器 // 实现V2Ray代理配置的生成功能 type V2RayGenerator struct { logger *logging.Logger } // NewV2RayGenerator 创建新的V2Ray生成器 // 返回初始化好的V2RayGenerator实例 func NewV2RayGenerator(logger *logging.Logger) *V2RayGenerator { return &V2RayGenerator{ logger: logger, } } // Generate 生成V2Ray配置 func (g *V2RayGenerator) Generate(configs []*parser.ProxyConfig, options *GenerationOptions) (string, error) { g.logger.Debugf("Generating V2Ray configuration") // 创建V2Ray配置结构 v2rayConfig := g.createV2RayConfig(configs, options) // 转换为JSON jsonData, err := json.MarshalIndent(v2rayConfig, "", " ") if err != nil { return "", fmt.Errorf("failed to marshal V2Ray configuration: %v", err) } return string(jsonData), nil } // ValidateOptions 验证V2Ray生成选项 func (g *V2RayGenerator) ValidateOptions(options *GenerationOptions) error { g.logger.Debugf("Validating V2Ray generation options") // 验证基本信息 if options.Name == "" { return fmt.Errorf("configuration name is required") } // 验证端口 if options.MixedPort < 0 || options.MixedPort > 65535 { return fmt.Errorf("invalid mixed port: %d", options.MixedPort) } return nil } // GetSupportedFormats 获取支持的格式 func (g *V2RayGenerator) GetSupportedFormats() []string { return []string{"v2ray"} } // V2RayConfig V2Ray配置结构体 type V2RayConfig struct { Log *V2RayLog `json:"log,omitempty"` Inbound *V2RayInbound `json:"inbounds"` Outbound *V2RayOutbound `json:"outbounds"` Routing *V2RayRouting `json:"routing,omitempty"` } // V2RayLog 日志配置 type V2RayLog struct { Loglevel string `json:"loglevel,omitempty"` } // V2RayInbound 入站配置 type V2RayInbound struct { Protocol string `json:"protocol"` Listen string `json:"listen"` Port int `json:"port"` Settings *V2RayInSettings `json:"settings,omitempty"` Sniffing *V2RaySniffing `json:"sniffing,omitempty"` Stream *V2RayStream `json:"streamSettings,omitempty"` } // V2RayInSettings 入站设置 type V2RayInSettings struct { Auth string `json:"auth,omitempty"` UDP bool `json:"udp,omitempty"` UserLevel int `json:"userLevel,omitempty"` Accounts []V2RayAccount `json:"accounts,omitempty"` } // V2RayAccount 账户信息 type V2RayAccount struct { User string `json:"user"` Pass string `json:"pass"` } // V2RaySniffing 流量嗅探 type V2RaySniffing struct { Enabled bool `json:"enabled"` DestOverride []string `json:"destOverride,omitempty"` } // V2RayStream 流媒体设置 type V2RayStream struct { Network string `json:"network,omitempty"` } // V2RayOutbound 出站配置 type V2RayOutbound struct { Protocol string `json:"protocol"` Settings *V2RayOutSettings `json:"settings,omitempty"` Stream *V2RayStream `json:"streamSettings,omitempty"` Tag string `json:"tag,omitempty"` } // V2RayOutSettings 出站设置 type V2RayOutSettings struct { VNext []V2RayVNext `json:"vnext,omitempty"` Servers []V2RayServer `json:"servers,omitempty"` Users []V2RayUser `json:"users,omitempty"` } // V2RayVNext 服务器节点 type V2RayVNext struct { Address string `json:"address"` Port int `json:"port"` Users []V2RayUser `json:"users"` } // V2RayUser 用户信息 type V2RayUser struct { ID string `json:"id"` AlterID int `json:"alterId,omitempty"` Email string `json:"email,omitempty"` Security string `json:"security,omitempty"` Level int `json:"level,omitempty"` } // V2RayServer 服务器信息 type V2RayServer struct { Address string `json:"address"` Port int `json:"port"` Method string `json:"method,omitempty"` Password string `json:"password,omitempty"` OTA bool `json:"ota,omitempty"` Users []V2RayUser `json:"users,omitempty"` } // V2RayRouting 路由配置 type V2RayRouting struct { Rules []V2RayRule `json:"rules"` } // V2RayRule 路由规则 type V2RayRule struct { Type string `json:"type"` InboundTag []string `json:"inboundTag,omitempty"` OutboundTag string `json:"outboundTag,omitempty"` Domain []string `json:"domain,omitempty"` IP []string `json:"ip,omitempty"` } // createV2RayConfig 创建V2Ray配置结构 func (g *V2RayGenerator) createV2RayConfig(configs []*parser.ProxyConfig, options *GenerationOptions) *V2RayConfig { config := &V2RayConfig{ Log: &V2RayLog{ Loglevel: "info", }, Inbound: g.createInbound(options), Outbound: g.createOutbound(configs), Routing: g.createRouting(), } return config } // createInbound 创建入站配置 func (g *V2RayGenerator) createInbound(options *GenerationOptions) *V2RayInbound { port := 10808 if options.MixedPort > 0 { port = options.MixedPort } return &V2RayInbound{ Protocol: "socks", Listen: "127.0.0.1", Port: port, Settings: &V2RayInSettings{ Auth: "noauth", UDP: true, UserLevel: 0, }, Sniffing: &V2RaySniffing{ Enabled: true, DestOverride: []string{"http", "tls"}, }, } } // createOutbound 创建出站配置 func (g *V2RayGenerator) createOutbound(configs []*parser.ProxyConfig) *V2RayOutbound { // 代理节点列表 vnext := make([]V2RayVNext, 0) servers := make([]V2RayServer, 0) for _, config := range configs { switch config.Protocol { case "vmess": vnext = append(vnext, g.createVMessVNext(config)) case "ss": servers = append(servers, g.createShadowsocksServer(config)) case "trojan": servers = append(servers, g.createTrojanServer(config)) } } outbound := &V2RayOutbound{ Protocol: "freedom", Tag: "direct", } // 如果有代理节点,创建代理出站 if len(vnext) > 0 || len(servers) > 0 { if len(vnext) > 0 { outbound = &V2RayOutbound{ Protocol: "vmess", Tag: "proxy", Settings: &V2RayOutSettings{ VNext: vnext, }, } } else { outbound = &V2RayOutbound{ Protocol: "shadowsocks", Tag: "proxy", Settings: &V2RayOutSettings{ Servers: servers, }, } } } return outbound } // createVMessVNext 创建VMess节点配置 func (g *V2RayGenerator) createVMessVNext(config *parser.ProxyConfig) V2RayVNext { uuid, _ := config.Settings["uuid"].(string) alterId, _ := config.Settings["alterId"].(int) if alterId == 0 { alterId = 0 } return V2RayVNext{ Address: config.Server, Port: config.Port, Users: []V2RayUser{ { ID: uuid, AlterID: alterId, Security: "auto", }, }, } } // createShadowsocksServer 创建Shadowsocks服务器配置 func (g *V2RayGenerator) createShadowsocksServer(config *parser.ProxyConfig) V2RayServer { method, _ := config.Settings["method"].(string) password, _ := config.Settings["password"].(string) return V2RayServer{ Address: config.Server, Port: config.Port, Method: method, Password: password, OTA: false, } } // createTrojanServer 创建Trojan服务器配置 func (g *V2RayGenerator) createTrojanServer(config *parser.ProxyConfig) V2RayServer { password, _ := config.Settings["password"].(string) return V2RayServer{ Address: config.Server, Port: config.Port, Method: "chacha20-ietf-poly1305", Password: password, OTA: false, } } // createRouting 创建路由配置 func (g *V2RayGenerator) createRouting() *V2RayRouting { return &V2RayRouting{ Rules: []V2RayRule{ { Type: "field", InboundTag: []string{"inbound"}, OutboundTag: "proxy", }, { Type: "field", Domain: []string{"geosite:cn"}, OutboundTag: "direct", }, { Type: "field", IP: []string{"geoip:cn", "geoip:private"}, OutboundTag: "direct", }, { Type: "field", OutboundTag: "proxy", }, }, } }