From cdf69ce65f49d28a5823535e2d716edbcbb7a4c4 Mon Sep 17 00:00:00 2001 From: nite Date: Thu, 12 Jun 2025 10:27:22 +1000 Subject: [PATCH] Refactor proxy structure and parser implementations to streamline protocol handling; remove unused marshaler interfaces and improve YAML serialization for various proxy types. --- README.md | 4 +- common/sub.go | 8 +- model/proxy/anytls.go | 37 +------ model/proxy/hysteria.go | 43 +------- model/proxy/hysteria2.go | 37 +------ model/proxy/proxy.go | 191 ++++++++++++++++++------------------ model/proxy/registry.go | 64 ------------ model/proxy/shadowsocks.go | 37 ------- model/proxy/shadowsocksr.go | 28 ------ model/proxy/socks.go | 8 ++ model/proxy/trojan.go | 37 +------ model/proxy/vless.go | 46 +-------- model/proxy/vmess.go | 63 +----------- parser/anytls.go | 16 +-- parser/hysteria.go | 26 ++--- parser/hysteria2.go | 24 ++--- parser/shadowsocks.go | 14 +-- parser/shadowsocksr.go | 22 +++-- parser/socks.go | 14 +-- parser/trojan.go | 10 +- parser/vless.go | 10 +- parser/vmess.go | 30 +++++- server/route.go | 14 ++- 23 files changed, 235 insertions(+), 548 deletions(-) delete mode 100644 model/proxy/registry.go create mode 100644 model/proxy/socks.go diff --git a/README.md b/README.md index 4843df7..b99b174 100644 --- a/README.md +++ b/README.md @@ -81,5 +81,5 @@ 添加新协议支持需要实现以下组件: -1. 在 `parser` 目录下实现协议解析器,用于解析订阅链接 -2. 在 `model/proxy` 目录下定义协议结构体和对应的序列化器,如有新增属性需在 `model/proxy/proxy.go` 中声明 +1. 在 `parser` 目录下实现协议解析器,用于解析节点链接 +2. 在 `model/proxy` 目录下定义协议结构体 diff --git a/common/sub.go b/common/sub.go index b8d2e35..fbf77eb 100644 --- a/common/sub.go +++ b/common/sub.go @@ -190,10 +190,12 @@ func BuildSub(clashType model.ClashType, query model.SubConfig, template string, proxies := make(map[string]*P.Proxy) newProxies := make([]P.Proxy, 0, len(proxyList)) for i := range proxyList { - key := proxyList[i].Server + strconv.Itoa(proxyList[i].Port) + proxyList[i].Type + proxyList[i].UUID + proxyList[i].Password - if proxyList[i].Network == "ws" { - key += proxyList[i].WSOpts.Path + proxyList[i].WSOpts.Headers["Host"] + yamlBytes, err := yaml.Marshal(proxyList[i]) + if err != nil { + logger.Logger.Debug("marshal proxy failed", zap.Error(err)) + return nil, errors.New("marshal proxy failed: " + err.Error()) } + key := string(yamlBytes) if _, exist := proxies[key]; !exist { proxies[key] = &proxyList[i] newProxies = append(newProxies, proxyList[i]) diff --git a/model/proxy/anytls.go b/model/proxy/anytls.go index 8b382d6..685ebb5 100644 --- a/model/proxy/anytls.go +++ b/model/proxy/anytls.go @@ -1,13 +1,11 @@ package proxy type Anytls struct { - Type string `yaml:"type"` - Name string `yaml:"name"` Server string `yaml:"server"` Port int `yaml:"port"` Password string `yaml:"password,omitempty"` Alpn []string `yaml:"alpn,omitempty"` - SNI string `yaml:"sni,omitempty"` + Sni string `yaml:"sni,omitempty"` ClientFingerprint string `yaml:"client-fingerprint,omitempty"` SkipCertVerify bool `yaml:"skip-cert-verify,omitempty"` Fingerprint string `yaml:"fingerprint,omitempty"` @@ -16,36 +14,3 @@ type Anytls struct { IdleSessionTimeout int `yaml:"idle-session-timeout,omitempty"` MinIdleSession int `yaml:"min-idle-session,omitempty"` } - -func ProxyToAnytls(p Proxy) Anytls { - return Anytls{ - Type: "anytls", - Name: p.Name, - Server: p.Server, - Port: p.Port, - Password: p.Password, - Alpn: p.Alpn, - SNI: p.Sni, - ClientFingerprint: p.ClientFingerprint, - SkipCertVerify: p.SkipCertVerify, - Fingerprint: p.Fingerprint, - UDP: p.UDP, - IdleSessionCheckInterval: p.IdleSessionCheckInterval, - IdleSessionTimeout: p.IdleSessionTimeout, - MinIdleSession: p.MinIdleSession, - } -} - -type AnytlsMarshaler struct{} - -func (m *AnytlsMarshaler) GetType() string { - return "anytls" -} - -func (m *AnytlsMarshaler) MarshalProxy(p Proxy) (interface{}, error) { - return ProxyToAnytls(p), nil -} - -func init() { - RegisterMarshaler(&AnytlsMarshaler{}) -} diff --git a/model/proxy/hysteria.go b/model/proxy/hysteria.go index 14b8d1e..e148d95 100644 --- a/model/proxy/hysteria.go +++ b/model/proxy/hysteria.go @@ -1,8 +1,6 @@ package proxy type Hysteria struct { - Type string `yaml:"type"` - Name string `yaml:"name"` Server string `yaml:"server"` Port int `yaml:"port,omitempty"` Ports string `yaml:"ports,omitempty"` @@ -19,7 +17,7 @@ type Hysteria struct { SNI string `yaml:"sni,omitempty"` SkipCertVerify bool `yaml:"skip-cert-verify,omitempty"` Fingerprint string `yaml:"fingerprint,omitempty"` - ALPN []string `yaml:"alpn,omitempty"` + Alpn []string `yaml:"alpn,omitempty"` CustomCA string `yaml:"ca,omitempty"` CustomCAString string `yaml:"ca-str,omitempty"` ReceiveWindowConn int `yaml:"recv-window-conn,omitempty"` @@ -27,42 +25,5 @@ type Hysteria struct { DisableMTUDiscovery bool `yaml:"disable-mtu-discovery,omitempty"` FastOpen bool `yaml:"fast-open,omitempty"` HopInterval int `yaml:"hop-interval,omitempty"` -} - -func ProxyToHysteria(p Proxy) Hysteria { - return Hysteria{ - Type: "hysteria", - Name: p.Name, - Server: p.Server, - Port: p.Port, - Ports: p.Ports, - Protocol: p.Protocol, - Up: p.Up, - Down: p.Down, - Auth: p.Auth, - AuthStringOLD: p.AuthStringOLD, - AuthString: p.AuthString, - Obfs: p.Obfs, - SNI: p.Sni, - SkipCertVerify: p.SkipCertVerify, - Fingerprint: p.Fingerprint, - ALPN: p.Alpn, - CustomCA: p.CustomCA, - CustomCAString: p.CustomCAString, - ReceiveWindowConn: p.ReceiveWindowConn, - ReceiveWindow: p.ReceiveWindow, - DisableMTUDiscovery: p.DisableMTUDiscovery, - FastOpen: p.FastOpen, - HopInterval: p.HopInterval, - } -} - -type HysteriaMarshaler struct{} - -func (m *HysteriaMarshaler) GetType() string { - return "hysteria" -} - -func (m *HysteriaMarshaler) MarshalProxy(p Proxy) (interface{}, error) { - return ProxyToHysteria(p), nil + AllowInsecure bool `yaml:"allow-insecure,omitempty"` } diff --git a/model/proxy/hysteria2.go b/model/proxy/hysteria2.go index c0bc7e8..070285f 100644 --- a/model/proxy/hysteria2.go +++ b/model/proxy/hysteria2.go @@ -1,8 +1,6 @@ package proxy type Hysteria2 struct { - Type string `yaml:"type"` - Name string `yaml:"name"` Server string `yaml:"server"` Port int `yaml:"port"` Up string `yaml:"up,omitempty"` @@ -17,35 +15,8 @@ type Hysteria2 struct { CustomCA string `yaml:"ca,omitempty"` CustomCAString string `yaml:"ca-str,omitempty"` CWND int `yaml:"cwnd,omitempty"` -} - -func ProxyToHysteria2(p Proxy) Hysteria2 { - return Hysteria2{ - Type: "hysteria2", - Name: p.Name, - Server: p.Server, - Port: p.Port, - Up: p.Up, - Down: p.Down, - Password: p.Password, - Obfs: p.Obfs, - ObfsPassword: p.ObfsParam, - SNI: p.Sni, - SkipCertVerify: p.SkipCertVerify, - Fingerprint: p.Fingerprint, - ALPN: p.Alpn, - CustomCA: p.CustomCA, - CustomCAString: p.CustomCAString, - CWND: p.CWND, - } -} - -type Hysteria2Marshaler struct{} - -func (m *Hysteria2Marshaler) GetType() string { - return "hysteria2" -} - -func (m *Hysteria2Marshaler) MarshalProxy(p Proxy) (interface{}, error) { - return ProxyToHysteria2(p), nil + ObfsParam string `yaml:"obfs-param,omitempty"` + Sni string `yaml:"sni,omitempty"` + TLS bool `yaml:"tls,omitempty"` + Network string `yaml:"network,omitempty"` } diff --git a/model/proxy/proxy.go b/model/proxy/proxy.go index af34db5..aa81491 100644 --- a/model/proxy/proxy.go +++ b/model/proxy/proxy.go @@ -1,5 +1,7 @@ package proxy +import "fmt" + type HTTPOptions struct { Method string `yaml:"method,omitempty"` Path []string `yaml:"path,omitempty"` @@ -31,76 +33,6 @@ type SmuxStruct struct { Enabled bool `yaml:"enable"` } -type Proxy struct { - Name string `yaml:"name,omitempty"` - Server string `yaml:"server,omitempty"` - Port int `yaml:"port,omitempty"` - Type string `yaml:"type,omitempty"` - Cipher string `yaml:"cipher,omitempty"` - Username string `yaml:"username,omitempty"` - Password string `yaml:"password,omitempty"` - UDP bool `yaml:"udp,omitempty"` - UUID string `yaml:"uuid,omitempty"` - Network string `yaml:"network,omitempty"` - Flow string `yaml:"flow,omitempty"` - TLS bool `yaml:"tls,omitempty"` - ClientFingerprint string `yaml:"client-fingerprint,omitempty"` - Plugin string `yaml:"plugin,omitempty"` - PluginOpts map[string]any `yaml:"plugin-opts,omitempty"` - Smux SmuxStruct `yaml:"smux,omitempty"` - Sni string `yaml:"sni,omitempty"` - AllowInsecure bool `yaml:"allow-insecure,omitempty"` - Fingerprint string `yaml:"fingerprint,omitempty"` - SkipCertVerify bool `yaml:"skip-cert-verify,omitempty"` - Alpn []string `yaml:"alpn,omitempty"` - XUDP bool `yaml:"xudp,omitempty"` - Servername string `yaml:"servername,omitempty"` - WSOpts WSOptions `yaml:"ws-opts,omitempty"` - AlterID int `yaml:"alterId,omitempty"` - GrpcOpts GrpcOptions `yaml:"grpc-opts,omitempty"` - RealityOpts RealityOptions `yaml:"reality-opts,omitempty"` - Protocol string `yaml:"protocol,omitempty"` - Obfs string `yaml:"obfs,omitempty"` - ObfsParam string `yaml:"obfs-param,omitempty"` - ProtocolParam string `yaml:"protocol-param,omitempty"` - Remarks []string `yaml:"remarks,omitempty"` - HTTPOpts HTTPOptions `yaml:"http-opts,omitempty"` - HTTP2Opts HTTP2Options `yaml:"h2-opts,omitempty"` - PacketAddr bool `yaml:"packet-addr,omitempty"` - PacketEncoding string `yaml:"packet-encoding,omitempty"` - GlobalPadding bool `yaml:"global-padding,omitempty"` - AuthenticatedLength bool `yaml:"authenticated-length,omitempty"` - UDPOverTCP bool `yaml:"udp-over-tcp,omitempty"` - UDPOverTCPVersion int `yaml:"udp-over-tcp-version,omitempty"` - SubName string `yaml:"-"` - Up string `yaml:"up,omitempty"` - Down string `yaml:"down,omitempty"` - CustomCA string `yaml:"ca,omitempty"` - CustomCAString string `yaml:"ca-str,omitempty"` - CWND int `yaml:"cwnd,omitempty"` - Auth string `yaml:"auth,omitempty"` - ReceiveWindowConn int `yaml:"recv-window-conn,omitempty"` - ReceiveWindow int `yaml:"recv-window,omitempty"` - DisableMTUDiscovery bool `yaml:"disable-mtu-discovery,omitempty"` - FastOpen bool `yaml:"fast-open,omitempty"` - HopInterval int `yaml:"hop-interval,omitempty"` - Ports string `yaml:"ports,omitempty"` - AuthStringOLD string `yaml:"auth_str,omitempty"` - AuthString string `yaml:"auth-str,omitempty"` - Ip string `yaml:"ip,omitempty"` - Ipv6 string `yaml:"ipv6,omitempty"` - PrivateKey string `yaml:"private-key,omitempty"` - Workers int `yaml:"workers,omitempty"` - MTU int `yaml:"mtu,omitempty"` - PersistentKeepalive int `yaml:"persistent-keepalive,omitempty"` - Peers []WireGuardPeerOption `yaml:"peers,omitempty"` - RemoteDnsResolve bool `yaml:"remote-dns-resolve,omitempty"` - Dns []string `yaml:"dns,omitempty"` - IdleSessionCheckInterval int `yaml:"idle-session-check-interval,omitempty"` - IdleSessionTimeout int `yaml:"idle-session-timeout,omitempty"` - MinIdleSession int `yaml:"min-idle-session,omitempty"` -} - type WireGuardPeerOption struct { Server string `yaml:"server"` Port int `yaml:"port"` @@ -110,33 +42,104 @@ type WireGuardPeerOption struct { AllowedIPs []string `yaml:"allowed-ips,omitempty"` } -type _Proxy Proxy +type Proxy struct { + Type string + Name string + SubName string `yaml:"-"` + Anytls + Hysteria + Hysteria2 + ShadowSocks + ShadowSocksR + Trojan + Vless + Vmess + Socks +} -func (p Proxy) MarshalYAML() (interface{}, error) { - // 尝试使用注册的序列化器 - if marshaler, exists := GetMarshaler(p.Type); exists { - return marshaler.MarshalProxy(p) - } - - // 保持向后兼容,对于未注册的类型使用原有逻辑 +func (p Proxy) MarshalYAML() (any, error) { switch p.Type { - case "vmess": - return ProxyToVmess(p), nil - case "ss": - return ProxyToShadowSocks(p), nil - case "ssr": - return ProxyToShadowSocksR(p), nil - case "vless": - return ProxyToVless(p), nil - case "trojan": - return ProxyToTrojan(p), nil - case "hysteria": - return ProxyToHysteria(p), nil - case "hysteria2": - return ProxyToHysteria2(p), nil case "anytls": - return ProxyToAnytls(p), nil + return struct { + Type string `yaml:"type"` + Name string `yaml:"name"` + Anytls `yaml:",inline"` + }{ + Type: p.Type, + Name: p.Name, + Anytls: p.Anytls, + }, nil + case "hysteria": + return struct { + Type string `yaml:"type"` + Name string `yaml:"name"` + Hysteria `yaml:",inline"` + }{ + Type: p.Type, + Name: p.Name, + Hysteria: p.Hysteria, + }, nil + case "hysteria2": + return struct { + Type string `yaml:"type"` + Name string `yaml:"name"` + Hysteria2 `yaml:",inline"` + }{ + Type: p.Type, + Name: p.Name, + Hysteria2: p.Hysteria2, + }, nil + case "ss": + return struct { + Type string `yaml:"type"` + Name string `yaml:"name"` + ShadowSocks `yaml:",inline"` + }{ + Type: p.Type, + Name: p.Name, + ShadowSocks: p.ShadowSocks, + }, nil + case "ssr": + return struct { + Type string `yaml:"type"` + Name string `yaml:"name"` + ShadowSocksR `yaml:",inline"` + }{ + Type: p.Type, + Name: p.Name, + ShadowSocksR: p.ShadowSocksR, + }, nil + case "trojan": + return struct { + Type string `yaml:"type"` + Name string `yaml:"name"` + Trojan `yaml:",inline"` + }{ + Type: p.Type, + Name: p.Name, + Trojan: p.Trojan, + }, nil + case "vless": + return struct { + Type string `yaml:"type"` + Name string `yaml:"name"` + Vless `yaml:",inline"` + }{ + Type: p.Type, + Name: p.Name, + Vless: p.Vless, + }, nil + case "vmess": + return struct { + Type string `yaml:"type"` + Name string `yaml:"name"` + Vmess `yaml:",inline"` + }{ + Type: p.Type, + Name: p.Name, + Vmess: p.Vmess, + }, nil default: - return _Proxy(p), nil + return nil, fmt.Errorf("unsupported proxy type: %s", p.Type) } } diff --git a/model/proxy/registry.go b/model/proxy/registry.go deleted file mode 100644 index b334cf3..0000000 --- a/model/proxy/registry.go +++ /dev/null @@ -1,64 +0,0 @@ -package proxy - -import ( - "sync" -) - -// ProxyMarshaler 代理YAML序列化接口 -type ProxyMarshaler interface { - // MarshalProxy 将通用Proxy对象序列化为特定协议的YAML结构 - MarshalProxy(p Proxy) (interface{}, error) - // GetType 返回支持的协议类型 - GetType() string -} - -// marshalerRegistry YAML序列化器注册中心 -type marshalerRegistry struct { - mu sync.RWMutex - marshalers map[string]ProxyMarshaler // type -> marshaler -} - -var yamlRegistry = &marshalerRegistry{ - marshalers: make(map[string]ProxyMarshaler), -} - -// RegisterMarshaler 注册YAML序列化器 -func RegisterMarshaler(marshaler ProxyMarshaler) { - yamlRegistry.mu.Lock() - defer yamlRegistry.mu.Unlock() - - yamlRegistry.marshalers[marshaler.GetType()] = marshaler -} - -// GetMarshaler 根据协议类型获取序列化器 -func GetMarshaler(proxyType string) (ProxyMarshaler, bool) { - yamlRegistry.mu.RLock() - defer yamlRegistry.mu.RUnlock() - - marshaler, exists := yamlRegistry.marshalers[proxyType] - return marshaler, exists -} - -// GetAllMarshalers 获取所有注册的序列化器 -func GetAllMarshalers() map[string]ProxyMarshaler { - yamlRegistry.mu.RLock() - defer yamlRegistry.mu.RUnlock() - - result := make(map[string]ProxyMarshaler) - for k, v := range yamlRegistry.marshalers { - result[k] = v - } - return result -} - -// GetSupportedTypes 获取所有支持的协议类型 -func GetSupportedTypes() []string { - yamlRegistry.mu.RLock() - defer yamlRegistry.mu.RUnlock() - - types := make([]string, 0, len(yamlRegistry.marshalers)) - for proxyType := range yamlRegistry.marshalers { - types = append(types, proxyType) - } - return types -} diff --git a/model/proxy/shadowsocks.go b/model/proxy/shadowsocks.go index dd89d38..6b042c7 100644 --- a/model/proxy/shadowsocks.go +++ b/model/proxy/shadowsocks.go @@ -1,8 +1,6 @@ package proxy type ShadowSocks struct { - Type string `yaml:"type"` - Name string `yaml:"name"` Server string `yaml:"server"` Port int `yaml:"port"` Password string `yaml:"password"` @@ -14,38 +12,3 @@ type ShadowSocks struct { UDPOverTCPVersion int `yaml:"udp-over-tcp-version,omitempty"` ClientFingerprint string `yaml:"client-fingerprint,omitempty"` } - -func ProxyToShadowSocks(p Proxy) ShadowSocks { - return ShadowSocks{ - Type: "ss", - Name: p.Name, - Server: p.Server, - Port: p.Port, - Password: p.Password, - Cipher: p.Cipher, - UDP: p.UDP, - Plugin: p.Plugin, - PluginOpts: p.PluginOpts, - UDPOverTCP: p.UDPOverTCP, - UDPOverTCPVersion: p.UDPOverTCPVersion, - ClientFingerprint: p.ClientFingerprint, - } -} - -// ShadowsocksMarshaler Shadowsocks协议的YAML序列化器 -type ShadowsocksMarshaler struct{} - -// GetType 返回协议类型 -func (m *ShadowsocksMarshaler) GetType() string { - return "ss" -} - -// MarshalProxy 序列化Shadowsocks代理 -func (m *ShadowsocksMarshaler) MarshalProxy(p Proxy) (interface{}, error) { - return ProxyToShadowSocks(p), nil -} - -// 注册序列化器 -func init() { - RegisterMarshaler(&ShadowsocksMarshaler{}) -} diff --git a/model/proxy/shadowsocksr.go b/model/proxy/shadowsocksr.go index 22f7c3b..1f1500e 100644 --- a/model/proxy/shadowsocksr.go +++ b/model/proxy/shadowsocksr.go @@ -1,8 +1,6 @@ package proxy type ShadowSocksR struct { - Type string `yaml:"type"` - Name string `yaml:"name"` Server string `yaml:"server"` Port int `yaml:"port"` Password string `yaml:"password"` @@ -13,29 +11,3 @@ type ShadowSocksR struct { ProtocolParam string `yaml:"protocol-param,omitempty"` UDP bool `yaml:"udp,omitempty"` } - -func ProxyToShadowSocksR(p Proxy) ShadowSocksR { - return ShadowSocksR{ - Type: "ssr", - Name: p.Name, - Server: p.Server, - Port: p.Port, - Password: p.Password, - Cipher: p.Cipher, - Obfs: p.Obfs, - ObfsParam: p.ObfsParam, - Protocol: p.Protocol, - ProtocolParam: p.ProtocolParam, - UDP: p.UDP, - } -} - -type ShadowsocksRMarshaler struct{} - -func (m *ShadowsocksRMarshaler) GetType() string { - return "ssr" -} - -func (m *ShadowsocksRMarshaler) MarshalProxy(p Proxy) (interface{}, error) { - return ProxyToShadowSocksR(p), nil -} diff --git a/model/proxy/socks.go b/model/proxy/socks.go new file mode 100644 index 0000000..418f4e5 --- /dev/null +++ b/model/proxy/socks.go @@ -0,0 +1,8 @@ +package proxy + +type Socks struct { + Server string `yaml:"server,omitempty"` + Port int `yaml:"port,omitempty"` + Username string `yaml:"username,omitempty"` + Password string `yaml:"password,omitempty"` +} diff --git a/model/proxy/trojan.go b/model/proxy/trojan.go index 1a8f4ac..b696b9c 100644 --- a/model/proxy/trojan.go +++ b/model/proxy/trojan.go @@ -1,13 +1,11 @@ package proxy type Trojan struct { - Type string `yaml:"type"` - Name string `yaml:"name"` Server string `yaml:"server"` Port int `yaml:"port"` Password string `yaml:"password"` - ALPN []string `yaml:"alpn,omitempty"` - SNI string `yaml:"sni,omitempty"` + Alpn []string `yaml:"alpn,omitempty"` + Sni string `yaml:"sni,omitempty"` SkipCertVerify bool `yaml:"skip-cert-verify,omitempty"` Fingerprint string `yaml:"fingerprint,omitempty"` UDP bool `yaml:"udp,omitempty"` @@ -16,34 +14,5 @@ type Trojan struct { GrpcOpts GrpcOptions `yaml:"grpc-opts,omitempty"` WSOpts WSOptions `yaml:"ws-opts,omitempty"` ClientFingerprint string `yaml:"client-fingerprint,omitempty"` -} - -func ProxyToTrojan(p Proxy) Trojan { - return Trojan{ - Type: "trojan", - Name: p.Name, - Server: p.Server, - Port: p.Port, - Password: p.Password, - ALPN: p.Alpn, - SNI: p.Sni, - SkipCertVerify: p.SkipCertVerify, - Fingerprint: p.Fingerprint, - UDP: p.UDP, - Network: p.Network, - RealityOpts: p.RealityOpts, - GrpcOpts: p.GrpcOpts, - WSOpts: p.WSOpts, - ClientFingerprint: p.ClientFingerprint, - } -} - -type TrojanMarshaler struct{} - -func (m *TrojanMarshaler) GetType() string { - return "trojan" -} - -func (m *TrojanMarshaler) MarshalProxy(p Proxy) (interface{}, error) { - return ProxyToTrojan(p), nil + TLS bool `yaml:"tls,omitempty"` } diff --git a/model/proxy/vless.go b/model/proxy/vless.go index eea1450..27e4e47 100644 --- a/model/proxy/vless.go +++ b/model/proxy/vless.go @@ -1,14 +1,12 @@ package proxy type Vless struct { - Type string `yaml:"type"` - Name string `yaml:"name"` Server string `yaml:"server"` Port int `yaml:"port"` UUID string `yaml:"uuid"` Flow string `yaml:"flow,omitempty"` TLS bool `yaml:"tls,omitempty"` - ALPN []string `yaml:"alpn,omitempty"` + Alpn []string `yaml:"alpn,omitempty"` UDP bool `yaml:"udp,omitempty"` PacketAddr bool `yaml:"packet-addr,omitempty"` XUDP bool `yaml:"xudp,omitempty"` @@ -25,43 +23,7 @@ type Vless struct { Fingerprint string `yaml:"fingerprint,omitempty"` ServerName string `yaml:"servername,omitempty"` ClientFingerprint string `yaml:"client-fingerprint,omitempty"` -} - -func ProxyToVless(p Proxy) Vless { - return Vless{ - Type: "vless", - Name: p.Name, - Server: p.Server, - Port: p.Port, - UUID: p.UUID, - Flow: p.Flow, - TLS: p.TLS, - ALPN: p.Alpn, - UDP: p.UDP, - PacketAddr: p.PacketAddr, - XUDP: p.XUDP, - PacketEncoding: p.PacketEncoding, - Network: p.Network, - RealityOpts: p.RealityOpts, - HTTPOpts: p.HTTPOpts, - HTTP2Opts: p.HTTP2Opts, - GrpcOpts: p.GrpcOpts, - WSOpts: p.WSOpts, - WSPath: p.WSOpts.Path, - WSHeaders: p.WSOpts.Headers, - SkipCertVerify: p.SkipCertVerify, - Fingerprint: p.Fingerprint, - ServerName: p.Servername, - ClientFingerprint: p.ClientFingerprint, - } -} - -type VlessMarshaler struct{} - -func (m *VlessMarshaler) GetType() string { - return "vless" -} - -func (m *VlessMarshaler) MarshalProxy(p Proxy) (interface{}, error) { - return ProxyToVless(p), nil + Sni string `yaml:"sni,omitempty"` + AllowInsecure bool `yaml:"allow-insecure,omitempty"` + Servername string `yaml:"servername,omitempty"` } diff --git a/model/proxy/vmess.go b/model/proxy/vmess.go index c41166c..b597891 100644 --- a/model/proxy/vmess.go +++ b/model/proxy/vmess.go @@ -1,26 +1,6 @@ package proxy -type VmessJson struct { - V any `json:"v"` - Ps string `json:"ps"` - Add string `json:"add"` - Port any `json:"port"` - Id string `json:"id"` - Aid any `json:"aid"` - Scy string `json:"scy"` - Net string `json:"net"` - Type string `json:"type"` - Host string `json:"host"` - Path string `json:"path"` - Tls string `json:"tls"` - Sni string `json:"sni"` - Alpn string `json:"alpn"` - Fp string `json:"fp"` -} - type Vmess struct { - Type string `yaml:"type"` - Name string `yaml:"name"` Server string `yaml:"server"` Port int `yaml:"port"` UUID string `yaml:"uuid"` @@ -29,7 +9,7 @@ type Vmess struct { UDP bool `yaml:"udp,omitempty"` Network string `yaml:"network,omitempty"` TLS bool `yaml:"tls,omitempty"` - ALPN []string `yaml:"alpn,omitempty"` + Alpn []string `yaml:"alpn,omitempty"` SkipCertVerify bool `yaml:"skip-cert-verify,omitempty"` Fingerprint string `yaml:"fingerprint,omitempty"` ServerName string `yaml:"servername,omitempty"` @@ -44,44 +24,5 @@ type Vmess struct { GlobalPadding bool `yaml:"global-padding,omitempty"` AuthenticatedLength bool `yaml:"authenticated-length,omitempty"` ClientFingerprint string `yaml:"client-fingerprint,omitempty"` -} - -func ProxyToVmess(p Proxy) Vmess { - return Vmess{ - Type: "vmess", - Name: p.Name, - Server: p.Server, - Port: p.Port, - UUID: p.UUID, - AlterID: p.AlterID, - Cipher: p.Cipher, - UDP: p.UDP, - Network: p.Network, - TLS: p.TLS, - ALPN: p.Alpn, - SkipCertVerify: p.SkipCertVerify, - Fingerprint: p.Fingerprint, - ServerName: p.Servername, - RealityOpts: p.RealityOpts, - HTTPOpts: p.HTTPOpts, - HTTP2Opts: p.HTTP2Opts, - GrpcOpts: p.GrpcOpts, - WSOpts: p.WSOpts, - PacketAddr: p.PacketAddr, - XUDP: p.XUDP, - PacketEncoding: p.PacketEncoding, - GlobalPadding: p.GlobalPadding, - AuthenticatedLength: p.AuthenticatedLength, - ClientFingerprint: p.ClientFingerprint, - } -} - -type VmessMarshaler struct{} - -func (m *VmessMarshaler) GetType() string { - return "vmess" -} - -func (m *VmessMarshaler) MarshalProxy(p Proxy) (interface{}, error) { - return ProxyToVmess(p), nil + Servername string `yaml:"servername,omitempty"` } diff --git a/parser/anytls.go b/parser/anytls.go index 1d2ee2c..8abe820 100644 --- a/parser/anytls.go +++ b/parser/anytls.go @@ -80,13 +80,15 @@ func (p *AnytlsParser) Parse(proxy string) (P.Proxy, error) { remarks = strings.TrimSpace(remarks) result := P.Proxy{ - Type: p.GetType(), - Name: remarks, - Server: server, - Port: port, - Password: password, - Sni: sni, - SkipCertVerify: insecureBool, + Type: p.GetType(), + Name: remarks, + Anytls: P.Anytls{ + Server: server, + Port: port, + Password: password, + Sni: sni, + SkipCertVerify: insecureBool, + }, } return result, nil } diff --git a/parser/hysteria.go b/parser/hysteria.go index 7da3450..8f70c3d 100644 --- a/parser/hysteria.go +++ b/parser/hysteria.go @@ -89,18 +89,20 @@ func (p *HysteriaParser) Parse(proxy string) (P.Proxy, error) { remarks = strings.TrimSpace(remarks) result := P.Proxy{ - Type: p.GetType(), - Name: remarks, - Server: server, - Port: port, - Up: upmbps, - Down: downmbps, - Auth: auth, - Obfs: obfs, - SkipCertVerify: insecureBool, - Alpn: alpn, - Protocol: protocol, - AllowInsecure: insecureBool, + Type: p.GetType(), + Name: remarks, + Hysteria: P.Hysteria{ + Server: server, + Port: port, + Up: upmbps, + Down: downmbps, + Auth: auth, + Obfs: obfs, + SkipCertVerify: insecureBool, + Alpn: alpn, + Protocol: protocol, + AllowInsecure: insecureBool, + }, } return result, nil } diff --git a/parser/hysteria2.go b/parser/hysteria2.go index 50685c5..3d3b454 100644 --- a/parser/hysteria2.go +++ b/parser/hysteria2.go @@ -81,17 +81,19 @@ func (p *Hysteria2Parser) Parse(proxy string) (P.Proxy, error) { remarks = strings.TrimSpace(remarks) result := P.Proxy{ - Type: p.GetType(), - Name: remarks, - Server: server, - Port: port, - Password: password, - Obfs: obfs, - ObfsParam: obfsPassword, - Sni: sni, - SkipCertVerify: insecureBool, - TLS: enableTLS, - Network: network, + Type: p.GetType(), + Name: remarks, + Hysteria2: P.Hysteria2{ + Server: server, + Port: port, + Password: password, + Obfs: obfs, + ObfsParam: obfsPassword, + Sni: sni, + SkipCertVerify: insecureBool, + TLS: enableTLS, + Network: network, + }, } return result, nil } diff --git a/parser/shadowsocks.go b/parser/shadowsocks.go index 2443f73..c9ee025 100644 --- a/parser/shadowsocks.go +++ b/parser/shadowsocks.go @@ -123,12 +123,14 @@ func (p *ShadowsocksParser) Parse(proxy string) (P.Proxy, error) { remarks = strings.TrimSpace(remarks) result := P.Proxy{ - Type: p.GetType(), - Cipher: method, - Password: password, - Server: server, - Port: port, - Name: remarks, + Type: p.GetType(), + Name: remarks, + ShadowSocks: P.ShadowSocks{ + Cipher: method, + Password: password, + Server: server, + Port: port, + }, } return result, nil diff --git a/parser/shadowsocksr.go b/parser/shadowsocksr.go index 3dbf7ec..f156966 100644 --- a/parser/shadowsocksr.go +++ b/parser/shadowsocksr.go @@ -102,16 +102,18 @@ func (p *ShadowsocksRParser) Parse(proxy string) (P.Proxy, error) { } result := P.Proxy{ - Name: remarks, - Type: p.GetType(), - Server: server, - Port: port, - Protocol: protocol, - Cipher: method, - Obfs: obfs, - Password: password, - ObfsParam: obfsParam, - ProtocolParam: protoParam, + Type: p.GetType(), + Name: remarks, + ShadowSocksR: P.ShadowSocksR{ + Server: server, + Port: port, + Protocol: protocol, + Cipher: method, + Obfs: obfs, + Password: password, + ObfsParam: obfsParam, + ProtocolParam: protoParam, + }, } return result, nil diff --git a/parser/socks.go b/parser/socks.go index 5fc3985..c0c07db 100644 --- a/parser/socks.go +++ b/parser/socks.go @@ -87,12 +87,14 @@ func (p *SocksParser) Parse(proxy string) (P.Proxy, error) { } } return P.Proxy{ - Type: p.GetType(), - Name: remarks, - Server: server, - Port: port, - Username: username, - Password: password, + Type: p.GetType(), + Name: remarks, + Socks: P.Socks{ + Server: server, + Port: port, + Username: username, + Password: password, + }, }, nil } diff --git a/parser/trojan.go b/parser/trojan.go index 674f069..ff011a0 100644 --- a/parser/trojan.go +++ b/parser/trojan.go @@ -84,12 +84,10 @@ func (p *TrojanParser) Parse(proxy string) (P.Proxy, error) { alpn = nil } - result := P.Proxy{ - Type: p.GetType(), + result := P.Trojan{ Server: server, Port: port, Password: password, - Name: remarks, Network: network, } @@ -125,7 +123,11 @@ func (p *TrojanParser) Parse(proxy string) (P.Proxy, error) { } } - return result, nil + return P.Proxy{ + Type: p.GetType(), + Name: remarks, + Trojan: result, + }, nil } func init() { diff --git a/parser/vless.go b/parser/vless.go index 61c8874..8b4aace 100644 --- a/parser/vless.go +++ b/parser/vless.go @@ -76,10 +76,8 @@ func (p *VlessParser) Parse(proxy string) (P.Proxy, error) { } remarks = strings.TrimSpace(remarks) - result := P.Proxy{ - Type: p.GetType(), + result := P.Vless{ Server: server, - Name: remarks, Port: port, UUID: uuid, Flow: flow, @@ -141,7 +139,11 @@ func (p *VlessParser) Parse(proxy string) (P.Proxy, error) { } } - return result, nil + return P.Proxy{ + Type: p.GetType(), + Name: remarks, + Vless: result, + }, nil } func init() { diff --git a/parser/vmess.go b/parser/vmess.go index 3659bf0..842beb4 100644 --- a/parser/vmess.go +++ b/parser/vmess.go @@ -10,6 +10,24 @@ import ( P "github.com/bestnite/sub2clash/model/proxy" ) +type VmessJson struct { + V any `json:"v"` + Ps string `json:"ps"` + Add string `json:"add"` + Port any `json:"port"` + Id string `json:"id"` + Aid any `json:"aid"` + Scy string `json:"scy"` + Net string `json:"net"` + Type string `json:"type"` + Host string `json:"host"` + Path string `json:"path"` + Tls string `json:"tls"` + Sni string `json:"sni"` + Alpn string `json:"alpn"` + Fp string `json:"fp"` +} + type VmessParser struct{} func (p *VmessParser) SupportClash() bool { @@ -44,7 +62,7 @@ func (p *VmessParser) Parse(proxy string) (P.Proxy, error) { return P.Proxy{}, &E.ParseError{Type: E.ErrInvalidBase64, Raw: proxy, Message: err.Error()} } - var vmess P.VmessJson + var vmess VmessJson err = json.Unmarshal([]byte(base64), &vmess) if err != nil { return P.Proxy{}, &E.ParseError{Type: E.ErrInvalidStruct, Raw: proxy, Message: err.Error()} @@ -85,9 +103,7 @@ func (p *VmessParser) Parse(proxy string) (P.Proxy, error) { name = vmess.Ps } - result := P.Proxy{ - Name: name, - Type: p.GetType(), + result := P.Vmess{ Server: vmess.Add, Port: port, UUID: vmess.Id, @@ -139,7 +155,11 @@ func (p *VmessParser) Parse(proxy string) (P.Proxy, error) { result.Network = "h2" } - return result, nil + return P.Proxy{ + Type: p.GetType(), + Name: name, + Vmess: result, + }, nil } func init() { diff --git a/server/route.go b/server/route.go index 7078c80..e381a6c 100644 --- a/server/route.go +++ b/server/route.go @@ -19,8 +19,6 @@ import ( var staticFiles embed.FS func SetRoute(r *gin.Engine) { - r.Use(middleware.ZapLogger()) - tpl, err := template.ParseFS(staticFiles, "static/*") if err != nil { log.Fatalf("Error parsing templates: %v", err) @@ -42,10 +40,10 @@ func SetRoute(r *gin.Engine) { ) }, ) - r.GET("/clash", handler.SubHandler(model.Clash, config.GlobalConfig.ClashTemplate)) - r.GET("/meta", handler.SubHandler(model.ClashMeta, config.GlobalConfig.MetaTemplate)) - r.GET("/s/:hash", handler.GetRawConfHandler) - r.POST("/short", handler.GenerateLinkHandler) - r.PUT("/short", handler.UpdateLinkHandler) - r.GET("/short", handler.GetRawConfUriHandler) + r.GET("/clash", middleware.ZapLogger(), handler.SubHandler(model.Clash, config.GlobalConfig.ClashTemplate)) + r.GET("/meta", middleware.ZapLogger(), handler.SubHandler(model.ClashMeta, config.GlobalConfig.MetaTemplate)) + r.GET("/s/:hash", middleware.ZapLogger(), handler.GetRawConfHandler) + r.POST("/short", middleware.ZapLogger(), handler.GenerateLinkHandler) + r.PUT("/short", middleware.ZapLogger(), handler.UpdateLinkHandler) + r.GET("/short", middleware.ZapLogger(), handler.GetRawConfUriHandler) }