Reapply SingboxForPanel integration on upstream stable
This commit is contained in:
112
service/xboard/multi_service.go
Normal file
112
service/xboard/multi_service.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package xboard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
boxService "github.com/sagernet/sing-box/adapter/service"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
)
|
||||
|
||||
type multiNodeService struct {
|
||||
boxService.Adapter
|
||||
services []adapter.Service
|
||||
}
|
||||
|
||||
func newMultiNodeService(ctx context.Context, logger log.ContextLogger, tag string, options option.XBoardServiceOptions) (adapter.Service, error) {
|
||||
expanded := expandNodeOptions(options)
|
||||
services := make([]adapter.Service, 0, len(expanded))
|
||||
for i, node := range expanded {
|
||||
nodeTag := expandedNodeTag(tag, i, options.Nodes[i], node)
|
||||
service, err := newSingleService(ctx, logger, nodeTag, node)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create xboard node service %s: %w", nodeTag, err)
|
||||
}
|
||||
services = append(services, service)
|
||||
}
|
||||
return &multiNodeService{
|
||||
Adapter: boxService.NewAdapter(C.TypeXBoard, tag),
|
||||
services: services,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func expandNodeOptions(base option.XBoardServiceOptions) []option.XBoardServiceOptions {
|
||||
if len(base.Nodes) == 0 {
|
||||
return []option.XBoardServiceOptions{base}
|
||||
}
|
||||
result := make([]option.XBoardServiceOptions, 0, len(base.Nodes))
|
||||
for _, node := range base.Nodes {
|
||||
child := base
|
||||
child.Nodes = nil
|
||||
if node.PanelURL != "" {
|
||||
child.PanelURL = node.PanelURL
|
||||
}
|
||||
if node.ConfigPanelURL != "" {
|
||||
child.ConfigPanelURL = node.ConfigPanelURL
|
||||
}
|
||||
if node.UserPanelURL != "" {
|
||||
child.UserPanelURL = node.UserPanelURL
|
||||
}
|
||||
if node.Key != "" {
|
||||
child.Key = node.Key
|
||||
}
|
||||
if node.NodeID != 0 {
|
||||
child.NodeID = node.NodeID
|
||||
}
|
||||
if node.ConfigNodeID != 0 {
|
||||
child.ConfigNodeID = node.ConfigNodeID
|
||||
}
|
||||
if node.UserNodeID != 0 {
|
||||
child.UserNodeID = node.UserNodeID
|
||||
}
|
||||
if node.NodeType != "" {
|
||||
child.NodeType = node.NodeType
|
||||
}
|
||||
if node.SyncInterval != 0 {
|
||||
child.SyncInterval = node.SyncInterval
|
||||
}
|
||||
if node.ReportInterval != 0 {
|
||||
child.ReportInterval = node.ReportInterval
|
||||
}
|
||||
result = append(result, child)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func expandedNodeTag(baseTag string, index int, entry option.XBoardNodeOptions, node option.XBoardServiceOptions) string {
|
||||
nodeTag := ""
|
||||
if entry.Tag != "" {
|
||||
nodeTag = entry.Tag
|
||||
}
|
||||
if nodeTag == "" && node.NodeID != 0 {
|
||||
nodeTag = fmt.Sprintf("%d", node.NodeID)
|
||||
}
|
||||
if nodeTag == "" {
|
||||
nodeTag = fmt.Sprintf("%d", index+1)
|
||||
}
|
||||
if baseTag == "" {
|
||||
return "xboard-" + nodeTag
|
||||
}
|
||||
return fmt.Sprintf("%s-%s", baseTag, nodeTag)
|
||||
}
|
||||
|
||||
func (s *multiNodeService) Start(stage adapter.StartStage) error {
|
||||
for _, service := range s.services {
|
||||
if err := service.Start(stage); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *multiNodeService) Close() error {
|
||||
for i := len(s.services) - 1; i >= 0; i-- {
|
||||
if err := s.services[i].Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user