mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-16 13:20:27 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a6a1e0a31 | ||
|
|
217f77643f | ||
|
|
7afda58818 | ||
|
|
64605fc47a | ||
|
|
08703c9035 |
@@ -43,7 +43,7 @@ type CacheFile interface {
|
||||
|
||||
StoreWARPConfig() bool
|
||||
StoreMASQUEConfig() bool
|
||||
StoreProviders() bool
|
||||
StoreSubscriptions() bool
|
||||
|
||||
StoreDNS() bool
|
||||
DNSCacheStore
|
||||
|
||||
@@ -36,11 +36,12 @@ type Adapter struct {
|
||||
callbackAccess sync.Mutex
|
||||
callbacks list.List[adapter.ProviderUpdateCallback]
|
||||
|
||||
link string
|
||||
enabled bool
|
||||
removeEmojis bool
|
||||
timeout time.Duration
|
||||
interval time.Duration
|
||||
link string
|
||||
enabled bool
|
||||
removeEmojis bool
|
||||
overrideDialerOptions *option.DialerOptions
|
||||
timeout time.Duration
|
||||
interval time.Duration
|
||||
}
|
||||
|
||||
func NewAdapter(ctx context.Context, router adapter.Router, outbound adapter.OutboundManager, logFactory log.Factory, logger log.ContextLogger, providerTag string, providerType string, options option.ProviderHealthCheckOptions) Adapter {
|
||||
@@ -75,6 +76,10 @@ func (a *Adapter) SetRemoveEmojis(remove bool) {
|
||||
a.removeEmojis = remove
|
||||
}
|
||||
|
||||
func (a *Adapter) SetOverrideDialerOptions(options *option.DialerOptions) {
|
||||
a.overrideDialerOptions = options
|
||||
}
|
||||
|
||||
func (a *Adapter) Start() error {
|
||||
a.history = service.PtrFromContext[urltest.HistoryStorage](a.ctx)
|
||||
if a.history == nil {
|
||||
@@ -119,6 +124,11 @@ func (a *Adapter) UpdateOutbounds(oldOpts []option.Outbound, newOpts []option.Ou
|
||||
oldOptByTag[opt.Tag] = opt
|
||||
}
|
||||
for i, opt := range newOpts {
|
||||
if a.overrideDialerOptions != nil {
|
||||
if wrapper, ok := opt.Options.(option.DialerOptionsWrapper); ok {
|
||||
wrapper.ReplaceDialerOptions(*a.overrideDialerOptions)
|
||||
}
|
||||
}
|
||||
var tag string
|
||||
if opt.Tag != "" {
|
||||
tag = F.ToString(a.providerTag, "/", opt.Tag)
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
"path": "subscriptions/my-sub.txt",
|
||||
// Remove emoji flags from proxy names.
|
||||
"remove_emojis": true,
|
||||
// Override dial fields on every outbound from this provider.
|
||||
"override_dialer_options": {
|
||||
// Dial fields
|
||||
},
|
||||
"health_check": {
|
||||
"enabled": true,
|
||||
"url": "https://www.gstatic.com/generate_204",
|
||||
|
||||
@@ -82,6 +82,10 @@
|
||||
"include": "(?i)hk|jp|sg|us",
|
||||
// Remove emoji flags from proxy names.
|
||||
"remove_emojis": true,
|
||||
// Override dial fields on every outbound from this provider.
|
||||
"override_dialer_options": {
|
||||
// Dial fields
|
||||
},
|
||||
"health_check": {
|
||||
"enabled": true,
|
||||
"url": "https://www.gstatic.com/generate_204",
|
||||
@@ -98,7 +102,7 @@
|
||||
"experimental": {
|
||||
"cache_file": {
|
||||
"enabled": true,
|
||||
"store_providers": true // For persisting fetched subscriptions across restarts
|
||||
"store_subscriptions": true // For persisting fetched subscriptions across restarts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ type CacheFile struct {
|
||||
storeDNS bool
|
||||
storeWARPConfig bool
|
||||
storeMASQUEConfig bool
|
||||
storeProviders bool
|
||||
storeSubscriptions bool
|
||||
disableExpire bool
|
||||
rdrcTimeout time.Duration
|
||||
optimisticTimeout time.Duration
|
||||
@@ -106,23 +106,23 @@ func New(ctx context.Context, logger logger.Logger, options option.CacheFileOpti
|
||||
}
|
||||
}
|
||||
return &CacheFile{
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
path: filemanager.BasePath(ctx, path),
|
||||
cacheID: cacheIDBytes,
|
||||
cacheIDText: options.CacheID,
|
||||
storeFakeIP: options.StoreFakeIP,
|
||||
storeRDRC: options.StoreRDRC,
|
||||
storeDNS: options.StoreDNS,
|
||||
storeWARPConfig: options.StoreWARPConfig,
|
||||
storeMASQUEConfig: options.StoreMASQUEConfig,
|
||||
storeProviders: options.StoreProviders,
|
||||
rdrcTimeout: rdrcTimeout,
|
||||
saveDomain: make(map[netip.Addr]string),
|
||||
saveAddress4: make(map[string]netip.Addr),
|
||||
saveAddress6: make(map[string]netip.Addr),
|
||||
saveRDRC: make(map[saveCacheKey]bool),
|
||||
saveDNSCache: make(map[saveCacheKey]saveDNSCacheEntry),
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
path: filemanager.BasePath(ctx, path),
|
||||
cacheID: cacheIDBytes,
|
||||
cacheIDText: options.CacheID,
|
||||
storeFakeIP: options.StoreFakeIP,
|
||||
storeRDRC: options.StoreRDRC,
|
||||
storeDNS: options.StoreDNS,
|
||||
storeWARPConfig: options.StoreWARPConfig,
|
||||
storeMASQUEConfig: options.StoreMASQUEConfig,
|
||||
storeSubscriptions: options.StoreSubscriptions,
|
||||
rdrcTimeout: rdrcTimeout,
|
||||
saveDomain: make(map[netip.Addr]string),
|
||||
saveAddress4: make(map[string]netip.Addr),
|
||||
saveAddress6: make(map[string]netip.Addr),
|
||||
saveRDRC: make(map[saveCacheKey]bool),
|
||||
saveDNSCache: make(map[saveCacheKey]saveDNSCacheEntry),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,8 +487,8 @@ func (c *CacheFile) StoreMASQUEConfig() bool {
|
||||
return c.storeMASQUEConfig
|
||||
}
|
||||
|
||||
func (c *CacheFile) StoreProviders() bool {
|
||||
return c.storeProviders
|
||||
func (c *CacheFile) StoreSubscriptions() bool {
|
||||
return c.storeSubscriptions
|
||||
}
|
||||
|
||||
func (c *CacheFile) LoadWARPConfig(tag string) *adapter.SavedBinary {
|
||||
|
||||
@@ -76,7 +76,7 @@ require (
|
||||
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1
|
||||
github.com/sagernet/smux v1.5.50-sing-box-mod.1
|
||||
github.com/sagernet/tailscale v1.102.1-sing-box-1.14-mod.4
|
||||
github.com/sagernet/wireguard-go v0.0.5-0.20260823125007-8bd032a91a30
|
||||
github.com/sagernet/wireguard-go v0.0.5-extended-1.6.1
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854
|
||||
github.com/shtorm-7/go-cache/v2 v2.1.0-extended-1.0.2
|
||||
github.com/shtorm-7/workerpool v0.5.0
|
||||
@@ -271,7 +271,7 @@ require (
|
||||
zombiezen.com/go/capnproto2 v2.18.2+incompatible // indirect
|
||||
)
|
||||
|
||||
replace github.com/sagernet/wireguard-go => github.com/shtorm-7/wireguard-go v0.0.5-extended-1.6.0
|
||||
replace github.com/sagernet/wireguard-go => github.com/shtorm-7/wireguard-go v0.0.5-extended-1.6.1
|
||||
|
||||
replace github.com/sagernet/tailscale => github.com/shtorm-7/tailscale v1.102.1-sing-box-1.14-mod.4-extended-1.0.3
|
||||
|
||||
|
||||
@@ -519,6 +519,8 @@ github.com/shtorm-7/tailscale v1.102.1-sing-box-1.14-mod.4-extended-1.0.3 h1:AG4
|
||||
github.com/shtorm-7/tailscale v1.102.1-sing-box-1.14-mod.4-extended-1.0.3/go.mod h1:+1R9TnmCDbxb7h7ZOBKxi5UI6aWf+polOO/fc0WB/4o=
|
||||
github.com/shtorm-7/wireguard-go v0.0.5-extended-1.6.0 h1:cLCyRR5mVNuhR6iNkcDHItt0SZ6O1GYWfP86XmVmjUo=
|
||||
github.com/shtorm-7/wireguard-go v0.0.5-extended-1.6.0/go.mod h1:1VZmkU7yPAZVE0XKufUqqAhEY1RnWUcyZLmry85y+7A=
|
||||
github.com/shtorm-7/wireguard-go v0.0.5-extended-1.6.1 h1:lLd8c5SNbm01idBlaSc18Urn4i4/ME/Umu8BeQLJ/io=
|
||||
github.com/shtorm-7/wireguard-go v0.0.5-extended-1.6.1/go.mod h1:1VZmkU7yPAZVE0XKufUqqAhEY1RnWUcyZLmry85y+7A=
|
||||
github.com/shtorm-7/workerpool v0.5.0 h1:NPZuNgyH0EUm4aQsTL09xR1iV+7GCFw6jX9Z4aAVp2s=
|
||||
github.com/shtorm-7/workerpool v0.5.0/go.mod h1:NI0pUZgmGu0BdKO9j3mct1DNZmgXbyTS9foorljdH6E=
|
||||
github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU=
|
||||
|
||||
+10
-10
@@ -11,16 +11,16 @@ type ExperimentalOptions struct {
|
||||
}
|
||||
|
||||
type CacheFileOptions struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
CacheID string `json:"cache_id,omitempty"`
|
||||
StoreFakeIP bool `json:"store_fakeip,omitempty"`
|
||||
StoreRDRC bool `json:"store_rdrc,omitempty" schema:"omit"`
|
||||
StoreWARPConfig bool `json:"store_warp_config,omitempty"`
|
||||
StoreMASQUEConfig bool `json:"store_masque_config,omitempty"`
|
||||
StoreProviders bool `json:"store_providers,omitempty"`
|
||||
RDRCTimeout badoption.Duration `json:"rdrc_timeout,omitempty"`
|
||||
StoreDNS bool `json:"store_dns,omitempty"`
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
CacheID string `json:"cache_id,omitempty"`
|
||||
StoreFakeIP bool `json:"store_fakeip,omitempty"`
|
||||
StoreRDRC bool `json:"store_rdrc,omitempty" schema:"omit"`
|
||||
StoreWARPConfig bool `json:"store_warp_config,omitempty"`
|
||||
StoreMASQUEConfig bool `json:"store_masque_config,omitempty"`
|
||||
StoreSubscriptions bool `json:"store_subscriptions,omitempty"`
|
||||
RDRCTimeout badoption.Duration `json:"rdrc_timeout,omitempty"`
|
||||
StoreDNS bool `json:"store_dns,omitempty"`
|
||||
}
|
||||
|
||||
type ClashAPIOptions struct {
|
||||
|
||||
+18
-15
@@ -47,28 +47,31 @@ func (h *Provider) UnmarshalJSONContext(ctx context.Context, content []byte) err
|
||||
}
|
||||
|
||||
type ProviderLocalOptions struct {
|
||||
Path string `json:"path"`
|
||||
RemoveEmojis bool `json:"remove_emojis,omitempty"`
|
||||
HealthCheck ProviderHealthCheckOptions `json:"health_check,omitempty"`
|
||||
Path string `json:"path"`
|
||||
RemoveEmojis bool `json:"remove_emojis,omitempty"`
|
||||
HealthCheck ProviderHealthCheckOptions `json:"health_check,omitempty"`
|
||||
OverrideDialerOptions *DialerOptions `json:"override_dialer_options,omitempty"`
|
||||
}
|
||||
|
||||
type ProviderRemoteOptions struct {
|
||||
URL string `json:"url"`
|
||||
UserAgent string `json:"user_agent,omitempty"`
|
||||
Headers badoption.HTTPHeader `json:"headers,omitempty"`
|
||||
DownloadDetour string `json:"download_detour,omitempty"`
|
||||
UpdateInterval badoption.Duration `json:"update_interval,omitempty"`
|
||||
URL string `json:"url"`
|
||||
UserAgent string `json:"user_agent,omitempty"`
|
||||
Headers badoption.HTTPHeader `json:"headers,omitempty"`
|
||||
DownloadDetour string `json:"download_detour,omitempty"`
|
||||
UpdateInterval badoption.Duration `json:"update_interval,omitempty"`
|
||||
|
||||
Exclude *badoption.Regexp `json:"exclude,omitempty"`
|
||||
Include *badoption.Regexp `json:"include,omitempty"`
|
||||
RemoveEmojis bool `json:"remove_emojis,omitempty"`
|
||||
HealthCheck ProviderHealthCheckOptions `json:"health_check,omitempty"`
|
||||
Exclude *badoption.Regexp `json:"exclude,omitempty"`
|
||||
Include *badoption.Regexp `json:"include,omitempty"`
|
||||
RemoveEmojis bool `json:"remove_emojis,omitempty"`
|
||||
HealthCheck ProviderHealthCheckOptions `json:"health_check,omitempty"`
|
||||
OverrideDialerOptions *DialerOptions `json:"override_dialer_options,omitempty"`
|
||||
}
|
||||
|
||||
type ProviderInlineOptions struct {
|
||||
Outbounds []Outbound `json:"outbounds,omitempty"`
|
||||
RemoveEmojis bool `json:"remove_emojis,omitempty"`
|
||||
HealthCheck ProviderHealthCheckOptions `json:"health_check,omitempty"`
|
||||
Outbounds []Outbound `json:"outbounds,omitempty"`
|
||||
RemoveEmojis bool `json:"remove_emojis,omitempty"`
|
||||
HealthCheck ProviderHealthCheckOptions `json:"health_check,omitempty"`
|
||||
OverrideDialerOptions *DialerOptions `json:"override_dialer_options,omitempty"`
|
||||
}
|
||||
|
||||
type ProviderHealthCheckOptions struct {
|
||||
|
||||
@@ -27,6 +27,7 @@ type Failover struct {
|
||||
outbound.Adapter
|
||||
ctx context.Context
|
||||
outbound adapter.OutboundManager
|
||||
outbounds []adapter.Outbound
|
||||
logger logger.ContextLogger
|
||||
dial DialStrategy
|
||||
uotClient *uot.Client
|
||||
@@ -50,11 +51,12 @@ func NewFailover(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
outbound := &Failover{
|
||||
Adapter: outbound.NewAdapter(C.TypeFailover, tag, []string{N.NetworkTCP, N.NetworkUDP}, []string{}),
|
||||
ctx: ctx,
|
||||
outbound: service.FromContext[adapter.OutboundManager](ctx),
|
||||
logger: logger,
|
||||
dial: dial,
|
||||
Adapter: outbound.NewAdapter(C.TypeFailover, tag, []string{N.NetworkTCP, N.NetworkUDP}, []string{}),
|
||||
ctx: ctx,
|
||||
outbound: service.FromContext[adapter.OutboundManager](ctx),
|
||||
outbounds: outbounds,
|
||||
logger: logger,
|
||||
dial: dial,
|
||||
}
|
||||
outbound.uotClient = &uot.Client{
|
||||
Dialer: outbound,
|
||||
@@ -63,6 +65,16 @@ func NewFailover(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
func (f *Failover) Start(stage adapter.StartStage) error {
|
||||
for _, outbound := range f.outbounds {
|
||||
err := adapter.LegacyStart(outbound, stage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Failover) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
if N.NetworkName(network) == N.NetworkUDP {
|
||||
return f.uotClient.DialContext(ctx, network, destination)
|
||||
|
||||
@@ -24,6 +24,8 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.BandwidthLimiterOutboundOptions](registry, C.TypeBandwidthLimiter, NewOutbound)
|
||||
}
|
||||
|
||||
var _ adapter.Lifecycle = (*Outbound)(nil)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
ctx context.Context
|
||||
@@ -87,19 +89,19 @@ func (h *Outbound) Network() []string {
|
||||
return []string{N.NetworkTCP, N.NetworkUDP}
|
||||
}
|
||||
|
||||
func (h *Outbound) Start() error {
|
||||
detour, loaded := h.outbound.Outbound(h.outboundTag)
|
||||
if !loaded {
|
||||
return E.New("outbound not found: ", h.outboundTag)
|
||||
}
|
||||
h.detour = detour
|
||||
for _, stage := range []adapter.StartStage{adapter.StartStateStart, adapter.StartStatePostStart, adapter.StartStateStarted} {
|
||||
err := h.router.Start(stage)
|
||||
if err != nil {
|
||||
return err
|
||||
func (h *Outbound) Start(stage adapter.StartStage) error {
|
||||
if stage == adapter.StartStateStart {
|
||||
detour, loaded := h.outbound.Outbound(h.outboundTag)
|
||||
if !loaded {
|
||||
return E.New("outbound not found: ", h.outboundTag)
|
||||
}
|
||||
h.detour = detour
|
||||
}
|
||||
return nil
|
||||
return h.router.Start(stage)
|
||||
}
|
||||
|
||||
func (h *Outbound) Close() error {
|
||||
return h.router.Close()
|
||||
}
|
||||
|
||||
func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
|
||||
@@ -24,6 +24,8 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.ConnectionLimiterOutboundOptions](registry, C.TypeConnectionLimiter, NewOutbound)
|
||||
}
|
||||
|
||||
var _ adapter.Lifecycle = (*Outbound)(nil)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
ctx context.Context
|
||||
@@ -87,19 +89,19 @@ func (h *Outbound) Network() []string {
|
||||
return []string{N.NetworkTCP, N.NetworkUDP}
|
||||
}
|
||||
|
||||
func (h *Outbound) Start() error {
|
||||
detour, loaded := h.outbound.Outbound(h.outboundTag)
|
||||
if !loaded {
|
||||
return E.New("outbound not found: ", h.outboundTag)
|
||||
}
|
||||
h.detour = detour
|
||||
for _, stage := range []adapter.StartStage{adapter.StartStateStart, adapter.StartStatePostStart, adapter.StartStateStarted} {
|
||||
err := h.router.Start(stage)
|
||||
if err != nil {
|
||||
return err
|
||||
func (h *Outbound) Start(stage adapter.StartStage) error {
|
||||
if stage == adapter.StartStateStart {
|
||||
detour, loaded := h.outbound.Outbound(h.outboundTag)
|
||||
if !loaded {
|
||||
return E.New("outbound not found: ", h.outboundTag)
|
||||
}
|
||||
h.detour = detour
|
||||
}
|
||||
return nil
|
||||
return h.router.Start(stage)
|
||||
}
|
||||
|
||||
func (h *Outbound) Close() error {
|
||||
return h.router.Close()
|
||||
}
|
||||
|
||||
func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
|
||||
@@ -85,19 +85,19 @@ func (h *Outbound) Network() []string {
|
||||
return []string{N.NetworkTCP, N.NetworkUDP}
|
||||
}
|
||||
|
||||
func (h *Outbound) Start() error {
|
||||
detour, loaded := h.outbound.Outbound(h.outboundTag)
|
||||
if !loaded {
|
||||
return E.New("outbound not found: ", h.outboundTag)
|
||||
}
|
||||
h.detour = detour
|
||||
for _, stage := range []adapter.StartStage{adapter.StartStateStart, adapter.StartStatePostStart, adapter.StartStateStarted} {
|
||||
err := h.router.Start(stage)
|
||||
if err != nil {
|
||||
return err
|
||||
func (h *Outbound) Start(stage adapter.StartStage) error {
|
||||
if stage == adapter.StartStateStart {
|
||||
detour, loaded := h.outbound.Outbound(h.outboundTag)
|
||||
if !loaded {
|
||||
return E.New("outbound not found: ", h.outboundTag)
|
||||
}
|
||||
h.detour = detour
|
||||
}
|
||||
return nil
|
||||
return h.router.Start(stage)
|
||||
}
|
||||
|
||||
func (h *Outbound) Close() error {
|
||||
return h.router.Close()
|
||||
}
|
||||
|
||||
func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
|
||||
@@ -23,6 +23,8 @@ func RegisterOutbound(registry *outbound.Registry) {
|
||||
outbound.Register[option.TrafficLimiterOutboundOptions](registry, C.TypeTrafficLimiter, NewOutbound)
|
||||
}
|
||||
|
||||
var _ adapter.Lifecycle = (*Outbound)(nil)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
ctx context.Context
|
||||
@@ -63,19 +65,19 @@ func (h *Outbound) Network() []string {
|
||||
return []string{N.NetworkTCP, N.NetworkUDP}
|
||||
}
|
||||
|
||||
func (h *Outbound) Start() error {
|
||||
detour, loaded := h.outbound.Outbound(h.outboundTag)
|
||||
if !loaded {
|
||||
return E.New("outbound not found: ", h.outboundTag)
|
||||
}
|
||||
h.detour = detour
|
||||
for _, stage := range []adapter.StartStage{adapter.StartStateStart, adapter.StartStatePostStart, adapter.StartStateStarted} {
|
||||
err := h.router.Start(stage)
|
||||
if err != nil {
|
||||
return err
|
||||
func (h *Outbound) Start(stage adapter.StartStage) error {
|
||||
if stage == adapter.StartStateStart {
|
||||
detour, loaded := h.outbound.Outbound(h.outboundTag)
|
||||
if !loaded {
|
||||
return E.New("outbound not found: ", h.outboundTag)
|
||||
}
|
||||
h.detour = detour
|
||||
}
|
||||
return nil
|
||||
return h.router.Start(stage)
|
||||
}
|
||||
|
||||
func (h *Outbound) Close() error {
|
||||
return h.router.Close()
|
||||
}
|
||||
|
||||
func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
|
||||
@@ -78,6 +78,10 @@ func NewClientEndpoint(ctx context.Context, router adapter.Router, logger log.Co
|
||||
}
|
||||
|
||||
func (c *ClientEndpoint) Start(stage adapter.StartStage) error {
|
||||
err := adapter.LegacyStart(c.outbound, stage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if stage != adapter.StartStatePostStart {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ func NewProviderInline(ctx context.Context, router adapter.Router, logFactory lo
|
||||
logger: logger,
|
||||
}
|
||||
p.SetRemoveEmojis(options.RemoveEmojis)
|
||||
p.SetOverrideDialerOptions(options.OverrideDialerOptions)
|
||||
p.UpdateOutbounds(nil, options.Outbounds)
|
||||
return p, nil
|
||||
}
|
||||
@@ -71,6 +72,7 @@ func NewProviderLocal(ctx context.Context, router adapter.Router, logFactory log
|
||||
provider: service.FromContext[adapter.ProviderManager](ctx),
|
||||
}
|
||||
provider.SetRemoveEmojis(options.RemoveEmojis)
|
||||
provider.SetOverrideDialerOptions(options.OverrideDialerOptions)
|
||||
filePath := filemanager.BasePath(ctx, options.Path)
|
||||
provider.path, _ = filepath.Abs(filePath)
|
||||
watcher, err := fswatch.NewWatcher(fswatch.Options{
|
||||
|
||||
@@ -101,12 +101,13 @@ func NewProviderRemote(ctx context.Context, router adapter.Router, logFactory lo
|
||||
include: (*regexp.Regexp)(options.Include),
|
||||
}
|
||||
p.SetRemoveEmojis(options.RemoveEmojis)
|
||||
p.SetOverrideDialerOptions(options.OverrideDialerOptions)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (s *ProviderRemote) Start() error {
|
||||
s.cacheFile = service.FromContext[adapter.CacheFile](s.ctx)
|
||||
if s.cacheFile != nil && s.cacheFile.StoreProviders() {
|
||||
if s.cacheFile != nil && s.cacheFile.StoreSubscriptions() {
|
||||
if saveSub := s.cacheFile.LoadSubscription(s.Tag()); saveSub != nil {
|
||||
content, _ := boxCommon.DecodeBase64URLSafe(string(saveSub.Content))
|
||||
firstLine, others := getFirstLine(content)
|
||||
@@ -207,7 +208,7 @@ func (s *ProviderRemote) fetch(ctx context.Context) error {
|
||||
case http.StatusNotModified:
|
||||
s.subscriptionInfo = info
|
||||
s.lastUpdated = time.Now()
|
||||
if s.cacheFile != nil && s.cacheFile.StoreProviders() {
|
||||
if s.cacheFile != nil && s.cacheFile.StoreSubscriptions() {
|
||||
saveSub := s.cacheFile.LoadSubscription(s.Tag())
|
||||
if saveSub != nil {
|
||||
if hasInfo {
|
||||
@@ -251,7 +252,7 @@ func (s *ProviderRemote) fetch(ctx context.Context) error {
|
||||
s.UpdateGroups()
|
||||
s.subscriptionInfo = info
|
||||
s.lastUpdated = time.Now()
|
||||
if s.cacheFile != nil && s.cacheFile.StoreProviders() {
|
||||
if s.cacheFile != nil && s.cacheFile.StoreSubscriptions() {
|
||||
content, _ := json.Marshal(option.Options{
|
||||
Outbounds: s.lastOutOpts,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user