V2bX/core/selector.go
wyx2685 2f1362067b
Some checks failed
Build and Release / build (386, freebsd) (push) Has been cancelled
Build and Release / build (386, linux) (push) Has been cancelled
Build and Release / build (386, windows) (push) Has been cancelled
Build and Release / build (amd64, darwin) (push) Has been cancelled
Build and Release / build (amd64, freebsd) (push) Has been cancelled
Build and Release / build (amd64, linux) (push) Has been cancelled
Build and Release / build (amd64, windows) (push) Has been cancelled
Build and Release / build (arm, 5, linux) (push) Has been cancelled
Build and Release / build (arm, 6, linux) (push) Has been cancelled
Build and Release / build (arm, 7, freebsd) (push) Has been cancelled
Build and Release / build (arm, 7, linux) (push) Has been cancelled
Build and Release / build (arm64, android) (push) Has been cancelled
Build and Release / build (arm64, darwin) (push) Has been cancelled
Build and Release / build (arm64, freebsd) (push) Has been cancelled
Build and Release / build (arm64, linux) (push) Has been cancelled
Build and Release / build (mips, linux) (push) Has been cancelled
Build and Release / build (mips64, linux) (push) Has been cancelled
Build and Release / build (mips64le, linux) (push) Has been cancelled
Build and Release / build (mipsle, linux) (push) Has been cancelled
Build and Release / build (ppc64, linux) (push) Has been cancelled
Build and Release / build (ppc64le, linux) (push) Has been cancelled
Build and Release / build (riscv64, linux) (push) Has been cancelled
Build and Release / build (s390x, linux) (push) Has been cancelled
sing内核支持面板rule规则
2025-01-10 16:33:05 +09:00

173 lines
3.2 KiB
Go

package core
import (
"errors"
"fmt"
"strings"
"sync"
"github.com/hashicorp/go-multierror"
"github.com/InazumaV/V2bX/api/panel"
"github.com/InazumaV/V2bX/conf"
)
type Selector struct {
cores map[string]Core
nodes sync.Map
}
func NewSelector(c []conf.CoreConfig) (Core, error) {
cs := make(map[string]Core, len(c))
for _, t := range c {
f, ok := cores[strings.ToLower(t.Type)]
if !ok {
return nil, errors.New("unknown core type: " + t.Type)
}
core1, err := f(&t)
if err != nil {
return nil, err
}
if t.Name == "" {
cs[t.Type] = core1
} else {
cs[t.Name] = core1
}
}
return &Selector{
cores: cs,
}, nil
}
func (s *Selector) Start() error {
for i := range s.cores {
err := s.cores[i].Start()
if err != nil {
return err
}
}
return nil
}
func (s *Selector) Close() error {
var errs error
for i := range s.cores {
err := s.cores[i].Close()
if err != nil {
errs = multierror.Append(errs, err)
}
}
return errs
}
func isSupported(protocol string, protocols []string) bool {
for i := range protocols {
if protocol == protocols[i] {
return true
}
}
return false
}
func (s *Selector) AddNode(tag string, info *panel.NodeInfo, option *conf.Options) error {
var core Core
if len(option.CoreName) > 0 {
// use name to select core
if c, ok := s.cores[option.CoreName]; ok {
core = c
}
} else {
// use type to select core
for _, c := range s.cores {
if len(option.Core) == 0 {
if !isSupported(info.Type, c.Protocols()) {
continue
}
} else if option.Core != c.Type() {
continue
}
core = c
}
}
if core == nil {
return errors.New("the node type is not support")
}
if len(option.Core) == 0 {
option.Core = core.Type()
err := option.UnmarshalJSON(option.RawOptions)
if err != nil {
return fmt.Errorf("unmarshal option error: %s", err)
}
option.RawOptions = nil
}
err := core.AddNode(tag, info, option)
if err != nil {
return err
}
s.nodes.Store(tag, core)
return nil
}
func (s *Selector) DelNode(tag string) error {
if t, e := s.nodes.Load(tag); e {
err := t.(Core).DelNode(tag)
if err != nil {
return err
}
s.nodes.Delete(tag)
return nil
}
return errors.New("the node is not have")
}
func (s *Selector) AddUsers(p *AddUsersParams) (added int, err error) {
t, e := s.nodes.Load(p.Tag)
if !e {
return 0, errors.New("the node is not have")
}
return t.(Core).AddUsers(p)
}
func (s *Selector) GetUserTraffic(tag, uuid string, reset bool) (up int64, down int64) {
t, e := s.nodes.Load(tag)
if !e {
return 0, 0
}
return t.(Core).GetUserTraffic(tag, uuid, reset)
}
func (s *Selector) DelUsers(users []panel.UserInfo, tag string, info *panel.NodeInfo) error {
t, e := s.nodes.Load(tag)
if !e {
return errors.New("the node is not have")
}
return t.(Core).DelUsers(users, tag, info)
}
func (s *Selector) Protocols() []string {
protocols := make([]string, 0)
for i := range s.cores {
protocols = append(protocols, s.cores[i].Protocols()...)
}
return protocols
}
func (s *Selector) Type() string {
t := "Selector("
var flag bool
for n, c := range s.cores {
if flag {
t += " "
} else {
flag = true
}
if len(n) == 0 {
t += c.Type()
} else {
t += n
}
}
t += ")"
return t
}