feat(adapter): add support for additional parameters in Adapter and Client structs

This commit is contained in:
Tension 2025-12-30 14:39:15 +08:00
parent 8436c2d6ee
commit 77a5373d44
5 changed files with 96 additions and 64 deletions

View File

@ -8,16 +8,24 @@ import (
) )
type Adapter struct { type Adapter struct {
SiteName string // 站点名称 Type string // 协议类型
Servers []*node.Node // 服务器列表 SiteName string // 站点名称
UserInfo User // 用户信息 Servers []*node.Node // 服务器列表
ClientTemplate string // 客户端配置模板 UserInfo User // 用户信息
OutputFormat string // 输出格式,默认是 base64 ClientTemplate string // 客户端配置模板
SubscribeName string // 订阅名称 OutputFormat string // 输出格式,默认是 base64
SubscribeName string // 订阅名称
Params map[string]string // 其他参数
} }
type Option func(*Adapter) type Option func(*Adapter)
func WithParams(params map[string]string) Option {
return func(opts *Adapter) {
opts.Params = params
}
}
// WithServers 设置服务器列表 // WithServers 设置服务器列表
func WithServers(servers []*node.Node) Option { func WithServers(servers []*node.Node) Option {
return func(opts *Adapter) { return func(opts *Adapter) {
@ -76,6 +84,7 @@ func (adapter *Adapter) Client() (*Client, error) {
OutputFormat: adapter.OutputFormat, OutputFormat: adapter.OutputFormat,
Proxies: []Proxy{}, Proxies: []Proxy{},
UserInfo: adapter.UserInfo, UserInfo: adapter.UserInfo,
Params: adapter.Params,
} }
proxies, err := adapter.Proxies(adapter.Servers) proxies, err := adapter.Proxies(adapter.Servers)
@ -101,55 +110,58 @@ func (adapter *Adapter) Proxies(servers []*node.Node) ([]Proxy, error) {
} }
for _, protocol := range protocols { for _, protocol := range protocols {
if protocol.Type == item.Protocol { if protocol.Type == item.Protocol {
proxies = append(proxies, Proxy{ proxies = append(
Sort: item.Sort, proxies,
Name: item.Name, Proxy{
Server: item.Address, Sort: item.Sort,
Port: item.Port, Name: item.Name,
Type: item.Protocol, Server: item.Address,
Tags: strings.Split(item.Tags, ","), Port: item.Port,
Security: protocol.Security, Type: item.Protocol,
SNI: protocol.SNI, Tags: strings.Split(item.Tags, ","),
AllowInsecure: protocol.AllowInsecure, Security: protocol.Security,
Fingerprint: protocol.Fingerprint, SNI: protocol.SNI,
RealityServerAddr: protocol.RealityServerAddr, AllowInsecure: protocol.AllowInsecure,
RealityServerPort: protocol.RealityServerPort, Fingerprint: protocol.Fingerprint,
RealityPrivateKey: protocol.RealityPrivateKey, RealityServerAddr: protocol.RealityServerAddr,
RealityPublicKey: protocol.RealityPublicKey, RealityServerPort: protocol.RealityServerPort,
RealityShortId: protocol.RealityShortId, RealityPrivateKey: protocol.RealityPrivateKey,
Transport: protocol.Transport, RealityPublicKey: protocol.RealityPublicKey,
Host: protocol.Host, RealityShortId: protocol.RealityShortId,
Path: protocol.Path, Transport: protocol.Transport,
ServiceName: protocol.ServiceName, Host: protocol.Host,
Method: protocol.Cipher, Path: protocol.Path,
ServerKey: protocol.ServerKey, ServiceName: protocol.ServiceName,
Flow: protocol.Flow, Method: protocol.Cipher,
HopPorts: protocol.HopPorts, ServerKey: protocol.ServerKey,
HopInterval: protocol.HopInterval, Flow: protocol.Flow,
ObfsPassword: protocol.ObfsPassword, HopPorts: protocol.HopPorts,
UpMbps: protocol.UpMbps, HopInterval: protocol.HopInterval,
DownMbps: protocol.DownMbps, ObfsPassword: protocol.ObfsPassword,
DisableSNI: protocol.DisableSNI, UpMbps: protocol.UpMbps,
ReduceRtt: protocol.ReduceRtt, DownMbps: protocol.DownMbps,
UDPRelayMode: protocol.UDPRelayMode, DisableSNI: protocol.DisableSNI,
CongestionController: protocol.CongestionController, ReduceRtt: protocol.ReduceRtt,
PaddingScheme: protocol.PaddingScheme, UDPRelayMode: protocol.UDPRelayMode,
Multiplex: protocol.Multiplex, CongestionController: protocol.CongestionController,
XhttpMode: protocol.XhttpMode, PaddingScheme: protocol.PaddingScheme,
XhttpExtra: protocol.XhttpExtra, Multiplex: protocol.Multiplex,
Encryption: protocol.Encryption, XhttpMode: protocol.XhttpMode,
EncryptionMode: protocol.EncryptionMode, XhttpExtra: protocol.XhttpExtra,
EncryptionRtt: protocol.EncryptionRtt, Encryption: protocol.Encryption,
EncryptionTicket: protocol.EncryptionTicket, EncryptionMode: protocol.EncryptionMode,
EncryptionServerPadding: protocol.EncryptionServerPadding, EncryptionRtt: protocol.EncryptionRtt,
EncryptionPrivateKey: protocol.EncryptionPrivateKey, EncryptionTicket: protocol.EncryptionTicket,
EncryptionClientPadding: protocol.EncryptionClientPadding, EncryptionServerPadding: protocol.EncryptionServerPadding,
EncryptionPassword: protocol.EncryptionPassword, EncryptionPrivateKey: protocol.EncryptionPrivateKey,
Ratio: protocol.Ratio, EncryptionClientPadding: protocol.EncryptionClientPadding,
CertMode: protocol.CertMode, EncryptionPassword: protocol.EncryptionPassword,
CertDNSProvider: protocol.CertDNSProvider, Ratio: protocol.Ratio,
CertDNSEnv: protocol.CertDNSEnv, CertMode: protocol.CertMode,
}) CertDNSProvider: protocol.CertDNSProvider,
CertDNSEnv: protocol.CertDNSEnv,
},
)
} }
} }
} }

View File

@ -93,12 +93,13 @@ type User struct {
} }
type Client struct { type Client struct {
SiteName string // Name of the site SiteName string // Name of the site
SubscribeName string // Name of the subscription SubscribeName string // Name of the subscription
ClientTemplate string // Template for the entire client configuration ClientTemplate string // Template for the entire client configuration
OutputFormat string // json, yaml, etc. OutputFormat string // json, yaml, etc.
Proxies []Proxy // List of proxy configurations Proxies []Proxy // List of proxy configurations
UserInfo User // User information UserInfo User // User information
Params map[string]string // Additional parameters
} }
func (c *Client) Build() ([]byte, error) { func (c *Client) Build() ([]byte, error) {
@ -119,6 +120,7 @@ func (c *Client) Build() ([]byte, error) {
"OutputFormat": c.OutputFormat, "OutputFormat": c.OutputFormat,
"Proxies": proxies, "Proxies": proxies,
"UserInfo": c.UserInfo, "UserInfo": c.UserInfo,
"Params": c.Params,
}) })
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -23,6 +23,10 @@ func SubscribeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
ua := c.GetHeader("User-Agent") ua := c.GetHeader("User-Agent")
req.UA = c.Request.Header.Get("User-Agent") req.UA = c.Request.Header.Get("User-Agent")
req.Flag = c.Query("flag") req.Flag = c.Query("flag")
req.Type = c.Query("type")
// 获取所有查询参数
req.Params = getQueryMap(c.Request)
if svcCtx.Config.Subscribe.PanDomain { if svcCtx.Config.Subscribe.PanDomain {
domain := c.Request.Host domain := c.Request.Host
domainArr := strings.Split(domain, ".") domainArr := strings.Split(domain, ".")
@ -94,3 +98,14 @@ func RegisterSubscribeHandlers(router *gin.Engine, serverCtx *svc.ServiceContext
} }
router.GET(path, SubscribeHandler(serverCtx)) router.GET(path, SubscribeHandler(serverCtx))
} }
// GetQueryMap 将 http.Request 的查询参数转换为 map[string]string
func getQueryMap(r *http.Request) map[string]string {
result := make(map[string]string)
for k, v := range r.URL.Query() {
if len(v) > 0 {
result[k] = v[0]
}
}
return result
}

View File

@ -108,6 +108,7 @@ func (l *SubscribeLogic) Handler(req *types.SubscribeRequest) (resp *types.Subsc
Traffic: userSubscribe.Traffic, Traffic: userSubscribe.Traffic,
SubscribeURL: l.getSubscribeV2URL(req.Token), SubscribeURL: l.getSubscribeV2URL(req.Token),
}), }),
adapter.WithParams(req.Params),
) )
// Get client config // Get client config

View File

@ -2,9 +2,11 @@ package types
type ( type (
SubscribeRequest struct { SubscribeRequest struct {
Flag string Flag string
Token string Token string
UA string Type string
UA string
Params map[string]string
} }
SubscribeResponse struct { SubscribeResponse struct {
Config []byte Config []byte