Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
237 lines
7.7 KiB
Go
237 lines
7.7 KiB
Go
package generator
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/subconverter-go/internal/logging"
|
|
"github.com/subconverter-go/internal/parser"
|
|
)
|
|
|
|
// Generator 生成器接口
|
|
// 定义了所有代理配置生成器必须实现的方法
|
|
type Generator interface {
|
|
// Generate 生成代理配置
|
|
// config: 代理配置列表
|
|
// options: 生成选项
|
|
// 返回生成的配置字符串和错误信息
|
|
Generate(configs []*parser.ProxyConfig, options *GenerationOptions) (string, error)
|
|
|
|
// ValidateOptions 验证生成选项
|
|
// options: 需要验证的生成选项
|
|
// 返回验证结果和错误信息
|
|
ValidateOptions(options *GenerationOptions) error
|
|
|
|
// GetSupportedFormats 获取支持的格式
|
|
// 返回该生成器支持的格式列表
|
|
GetSupportedFormats() []string
|
|
}
|
|
|
|
// GenerationOptions 生成选项结构体
|
|
// 包含所有生成格式的通用配置选项
|
|
type GenerationOptions struct {
|
|
// 基本信息
|
|
Name string `json:"name"` // 配置名称
|
|
Group string `json:"group"` // 代理组名称
|
|
Location string `json:"location"` // 地理位置
|
|
|
|
// 代理设置
|
|
ProxyTest bool `json:"proxyTest"` // 是否启用代理测试
|
|
ProxyURL string `json:"proxyURL"` // 测试代理URL
|
|
|
|
// 规则设置
|
|
Rules []string `json:"rules"` // 规则列表
|
|
|
|
// 性能设置
|
|
EnableLan bool `json:"enableLan"` // 是否启用局域网连接
|
|
IPv6 bool `json:"ipv6"` // 是否启用IPv6
|
|
|
|
// 高级设置
|
|
MixedPort int `json:"mixedPort"` // 混合端口
|
|
AllowLan bool `json:"allowLan"` // 是否允许局域网连接
|
|
Mode string `json:"mode"` // 模式 (global/rule/direct)
|
|
LogLevel string `json:"logLevel"` // 日志级别
|
|
ExternalController string `json:"externalController"` // 外部控制器地址
|
|
Secret string `json:"secret"` // 密钥
|
|
|
|
// 兼容扩展设置
|
|
AppendType bool `json:"appendType"`
|
|
TFO bool `json:"tfo"`
|
|
Script bool `json:"script"`
|
|
SkipCert bool `json:"skipCertVerify"`
|
|
FilterDeprecated bool `json:"filterDeprecated"`
|
|
ExpandRules bool `json:"expandRules"`
|
|
AppendInfo bool `json:"appendInfo"`
|
|
Prepend bool `json:"prepend"`
|
|
Classic bool `json:"classic"`
|
|
TLS13 bool `json:"tls13"`
|
|
AddEmoji bool `json:"addEmoji"`
|
|
RemoveEmoji bool `json:"removeEmoji"`
|
|
EmojiRules []string `json:"emojiRules"`
|
|
RenameRules []string `json:"renameRules"`
|
|
CustomGroups []string `json:"customGroups"`
|
|
CustomRulesets []string `json:"customRulesets"`
|
|
CustomProviders []string `json:"customProviders"`
|
|
GroupDefinitions []*GroupDefinition `json:"-"`
|
|
Providers []*ProviderDefinition `json:"-"`
|
|
FilterScript string `json:"filterScript"`
|
|
Upload bool `json:"upload"`
|
|
UploadPath string `json:"uploadPath"`
|
|
DeviceID string `json:"deviceId"`
|
|
Interval string `json:"interval"`
|
|
BasePath string `json:"-"`
|
|
}
|
|
|
|
// GeneratorManager 生成器管理器
|
|
// 管理所有代理配置生成器,提供统一的生成接口
|
|
type GeneratorManager struct {
|
|
logger *logging.Logger
|
|
generators map[string]Generator // 格式名称到生成器的映射
|
|
}
|
|
|
|
// NewGeneratorManager 创建新的生成器管理器
|
|
// 返回初始化好的GeneratorManager实例
|
|
func NewGeneratorManager(logger *logging.Logger) *GeneratorManager {
|
|
gm := &GeneratorManager{
|
|
logger: logger,
|
|
generators: make(map[string]Generator),
|
|
}
|
|
|
|
// 注册所有生成器
|
|
gm.registerGenerators()
|
|
|
|
return gm
|
|
}
|
|
|
|
// registerGenerators 注册所有生成器
|
|
// 将各种代理配置生成器注册到管理器中
|
|
func (gm *GeneratorManager) registerGenerators() {
|
|
// 注册Clash生成器
|
|
clashGen := NewClashGenerator(gm.logger)
|
|
gm.generators["clash"] = clashGen
|
|
gm.generators["clashr"] = clashGen
|
|
|
|
// 注册Surge生成器
|
|
gm.generators["surge"] = NewSurgeGenerator(gm.logger)
|
|
|
|
// 注册Quantumult X生成器
|
|
quantumultxGen := NewQuantumultXGenerator(gm.logger)
|
|
gm.generators["quantumultx"] = quantumultxGen
|
|
gm.generators["quanx"] = quantumultxGen
|
|
|
|
// 注册Loon生成器
|
|
gm.generators["loon"] = NewLoonGenerator(gm.logger)
|
|
|
|
// 注册Surfboard生成器
|
|
gm.generators["surfboard"] = NewSurfboardGenerator(gm.logger)
|
|
|
|
// 注册V2Ray生成器
|
|
gm.generators["v2ray"] = NewV2RayGenerator(gm.logger)
|
|
|
|
gm.logger.Info("Registered generators: clash, clashr, surge, quantumultx, loon, surfboard, v2ray")
|
|
}
|
|
|
|
// Generate 生成代理配置
|
|
// 自动识别格式并调用相应的生成器
|
|
func (gm *GeneratorManager) Generate(configs []*parser.ProxyConfig, format string, options *GenerationOptions) (string, error) {
|
|
gm.logger.Debugf("Generating proxy configuration for format: %s with %d proxies", format, len(configs))
|
|
|
|
// 验证输入参数
|
|
if len(configs) == 0 {
|
|
return "", fmt.Errorf("no proxy configurations provided")
|
|
}
|
|
|
|
if format == "" {
|
|
return "", fmt.Errorf("format is required")
|
|
}
|
|
|
|
// 获取对应的生成器
|
|
generator, exists := gm.generators[format]
|
|
if !exists {
|
|
gm.logger.Errorf("No generator found for format: %s", format)
|
|
return "", fmt.Errorf("unsupported format: %s", format)
|
|
}
|
|
|
|
// 验证生成选项
|
|
if options == nil {
|
|
options = &GenerationOptions{
|
|
Name: "SubConverter-Go",
|
|
Group: "proxy",
|
|
IPv6: true,
|
|
Mode: "rule",
|
|
BasePath: "",
|
|
}
|
|
}
|
|
|
|
if err := generator.ValidateOptions(options); err != nil {
|
|
gm.logger.WithError(err).Errorf("Invalid generation options for format: %s", format)
|
|
return "", fmt.Errorf("invalid generation options: %v", err)
|
|
}
|
|
|
|
// 调用生成器进行生成
|
|
result, err := generator.Generate(configs, options)
|
|
if err != nil {
|
|
gm.logger.WithError(err).Errorf("Failed to generate %s configuration", format)
|
|
return "", fmt.Errorf("failed to generate %s configuration: %v", format, err)
|
|
}
|
|
|
|
gm.logger.Infof("Successfully generated %s configuration with %d proxies", format, len(configs))
|
|
return result, nil
|
|
}
|
|
|
|
// GetSupportedFormats 获取所有支持的格式
|
|
// 返回管理器支持的所有生成格式列表
|
|
func (gm *GeneratorManager) GetSupportedFormats() []string {
|
|
formats := make([]string, 0, len(gm.generators))
|
|
for format := range gm.generators {
|
|
formats = append(formats, format)
|
|
}
|
|
|
|
// 按字母顺序排序
|
|
for i := range formats {
|
|
for j := i + 1; j < len(formats); j++ {
|
|
if formats[i] > formats[j] {
|
|
formats[i], formats[j] = formats[j], formats[i]
|
|
}
|
|
}
|
|
}
|
|
return formats
|
|
}
|
|
|
|
// GetGenerator 获取指定格式的生成器
|
|
// 返回对应格式的生成器实例
|
|
func (gm *GeneratorManager) GetGenerator(format string) (Generator, error) {
|
|
generator, exists := gm.generators[format]
|
|
if !exists {
|
|
return nil, fmt.Errorf("generator not found for format: %s", format)
|
|
}
|
|
return generator, nil
|
|
}
|
|
|
|
// ValidateOptions 验证生成选项
|
|
// 使用对应的生成器验证选项的有效性
|
|
func (gm *GeneratorManager) ValidateOptions(format string, options *GenerationOptions) error {
|
|
generator, err := gm.GetGenerator(format)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return generator.ValidateOptions(options)
|
|
}
|
|
|
|
// GetDefaultOptions 获取默认生成选项
|
|
// 返回指定格式的默认生成选项
|
|
func (gm *GeneratorManager) GetDefaultOptions(format string) (*GenerationOptions, error) {
|
|
_, err := gm.GetGenerator(format)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 返回通用的默认选项
|
|
return &GenerationOptions{
|
|
Name: "SubConverter-Go",
|
|
Group: "proxy",
|
|
IPv6: true,
|
|
Mode: "rule",
|
|
}, nil
|
|
}
|