Refactor proxy structure and parser implementations to streamline protocol handling; remove unused marshaler interfaces and improve YAML serialization for various proxy types.

This commit is contained in:
2025-06-12 10:27:22 +10:00
parent 2d8508f390
commit cdf69ce65f
23 changed files with 235 additions and 548 deletions

View File

@ -81,5 +81,5 @@
添加新协议支持需要实现以下组件:
1.`parser` 目录下实现协议解析器,用于解析订阅链接
2.`model/proxy` 目录下定义协议结构体和对应的序列化器,如有新增属性需在 `model/proxy/proxy.go` 中声明
1.`parser` 目录下实现协议解析器,用于解析节点链接
2.`model/proxy` 目录下定义协议结构体

View File

@ -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])

View File

@ -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{})
}

View File

@ -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"`
}

View File

@ -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"`
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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{})
}

View File

@ -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
}

8
model/proxy/socks.go Normal file
View File

@ -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"`
}

View File

@ -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"`
}

View File

@ -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"`
}

View File

@ -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"`
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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)
}