mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-05-14 00:51:12 +03:00
Add MTProxy, MASQUE, VPN, Link parser. Update AmneziaWG. Remove Tunneling
This commit is contained in:
129
provider/local/provider.go
Normal file
129
provider/local/provider.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/fswatch"
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/adapter/provider"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/parser"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
"github.com/sagernet/sing/service"
|
||||
"github.com/sagernet/sing/service/filemanager"
|
||||
)
|
||||
|
||||
func RegisterProviderLocal(registry *provider.Registry) {
|
||||
provider.Register[option.ProviderLocalOptions](registry, C.ProviderTypeLocal, NewProviderLocal)
|
||||
}
|
||||
|
||||
func RegisterProviderInline(registry *provider.Registry) {
|
||||
provider.Register[option.ProviderInlineOptions](registry, C.ProviderTypeInline, NewProviderInline)
|
||||
}
|
||||
|
||||
var _ adapter.Provider = (*ProviderLocal)(nil)
|
||||
|
||||
type ProviderLocal struct {
|
||||
provider.Adapter
|
||||
ctx context.Context
|
||||
logger log.ContextLogger
|
||||
provider adapter.ProviderManager
|
||||
path string
|
||||
lastOutOpts []option.Outbound
|
||||
lastUpdated time.Time
|
||||
watcher *fswatch.Watcher
|
||||
}
|
||||
|
||||
func NewProviderInline(ctx context.Context, router adapter.Router, logFactory log.Factory, tag string, options option.ProviderInlineOptions) (adapter.Provider, error) {
|
||||
var (
|
||||
outbound = service.FromContext[adapter.OutboundManager](ctx)
|
||||
logger = logFactory.NewLogger(F.ToString("provider/inline", "[", tag, "]"))
|
||||
)
|
||||
provider := &ProviderLocal{
|
||||
Adapter: provider.NewAdapter(ctx, router, outbound, logFactory, logger, tag, C.ProviderTypeInline, options.HealthCheck),
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
}
|
||||
provider.UpdateOutbounds(nil, options.Outbounds)
|
||||
return provider, nil
|
||||
}
|
||||
|
||||
func NewProviderLocal(ctx context.Context, router adapter.Router, logFactory log.Factory, tag string, options option.ProviderLocalOptions) (adapter.Provider, error) {
|
||||
if options.Path == "" {
|
||||
return nil, E.New("provider path is required")
|
||||
}
|
||||
var (
|
||||
outbound = service.FromContext[adapter.OutboundManager](ctx)
|
||||
logger = logFactory.NewLogger(F.ToString("provider/local", "[", tag, "]"))
|
||||
)
|
||||
provider := &ProviderLocal{
|
||||
Adapter: provider.NewAdapter(ctx, router, outbound, logFactory, logger, tag, C.ProviderTypeLocal, options.HealthCheck),
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
provider: service.FromContext[adapter.ProviderManager](ctx),
|
||||
}
|
||||
filePath := filemanager.BasePath(ctx, options.Path)
|
||||
provider.path, _ = filepath.Abs(filePath)
|
||||
watcher, err := fswatch.NewWatcher(fswatch.Options{
|
||||
Path: []string{filePath},
|
||||
Callback: func(path string) {
|
||||
uErr := provider.reloadFile(path)
|
||||
if uErr != nil {
|
||||
logger.Error(E.Cause(uErr, "reload provider ", tag))
|
||||
}
|
||||
provider.UpdateGroups()
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
provider.watcher = watcher
|
||||
return provider, nil
|
||||
}
|
||||
|
||||
func (s *ProviderLocal) Start() error {
|
||||
err := s.reloadFile(s.path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.UpdateGroups()
|
||||
if s.watcher != nil {
|
||||
err := s.watcher.Start()
|
||||
if err != nil {
|
||||
s.logger.Error(E.Cause(err, "watch provider file"))
|
||||
}
|
||||
}
|
||||
return s.Adapter.Start()
|
||||
}
|
||||
|
||||
func (s *ProviderLocal) UpdatedAt() time.Time {
|
||||
return s.lastUpdated
|
||||
}
|
||||
|
||||
func (s *ProviderLocal) reloadFile(path string) error {
|
||||
if fileInfo, err := os.Stat(path); err == nil {
|
||||
s.lastUpdated = fileInfo.ModTime()
|
||||
}
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outboundOpts, err := parser.ParseSubscription(s.ctx, string(content))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.UpdateOutbounds(s.lastOutOpts, outboundOpts)
|
||||
s.lastOutOpts = outboundOpts
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ProviderLocal) Close() error {
|
||||
return common.Close(&s.Adapter, common.PtrOrNil(s.watcher))
|
||||
}
|
||||
Reference in New Issue
Block a user