clashapi.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package experimental
  2. import (
  3. "context"
  4. "os"
  5. "github.com/sagernet/sing-box/adapter"
  6. C "github.com/sagernet/sing-box/constant"
  7. "github.com/sagernet/sing-box/log"
  8. "github.com/sagernet/sing-box/option"
  9. "github.com/sagernet/sing/common"
  10. )
  11. type ClashServerConstructor = func(ctx context.Context, router adapter.Router, logFactory log.ObservableFactory, options option.ClashAPIOptions) (adapter.ClashServer, error)
  12. var clashServerConstructor ClashServerConstructor
  13. func RegisterClashServerConstructor(constructor ClashServerConstructor) {
  14. clashServerConstructor = constructor
  15. }
  16. func NewClashServer(ctx context.Context, router adapter.Router, logFactory log.ObservableFactory, options option.ClashAPIOptions) (adapter.ClashServer, error) {
  17. if clashServerConstructor == nil {
  18. return nil, os.ErrInvalid
  19. }
  20. return clashServerConstructor(ctx, router, logFactory, options)
  21. }
  22. func CalculateClashModeList(options option.Options) []string {
  23. var clashMode []string
  24. clashMode = append(clashMode, extraClashModeFromRule(common.PtrValueOrDefault(options.Route).Rules)...)
  25. clashMode = append(clashMode, extraClashModeFromDNSRule(common.PtrValueOrDefault(options.DNS).Rules)...)
  26. clashMode = common.FilterNotDefault(common.Uniq(clashMode))
  27. return clashMode
  28. }
  29. func extraClashModeFromRule(rules []option.Rule) []string {
  30. var clashMode []string
  31. for _, rule := range rules {
  32. switch rule.Type {
  33. case C.RuleTypeDefault:
  34. if rule.DefaultOptions.ClashMode != "" {
  35. clashMode = append(clashMode, rule.DefaultOptions.ClashMode)
  36. }
  37. case C.RuleTypeLogical:
  38. clashMode = append(clashMode, extraClashModeFromRule(rule.LogicalOptions.Rules)...)
  39. }
  40. }
  41. return clashMode
  42. }
  43. func extraClashModeFromDNSRule(rules []option.DNSRule) []string {
  44. var clashMode []string
  45. for _, rule := range rules {
  46. switch rule.Type {
  47. case C.RuleTypeDefault:
  48. if rule.DefaultOptions.ClashMode != "" {
  49. clashMode = append(clashMode, rule.DefaultOptions.ClashMode)
  50. }
  51. case C.RuleTypeLogical:
  52. clashMode = append(clashMode, extraClashModeFromDNSRule(rule.LogicalOptions.Rules)...)
  53. }
  54. }
  55. return clashMode
  56. }