From 1650ab2ae36160a34ea27e7b59c38875ca191d69 Mon Sep 17 00:00:00 2001 From: PuerNya Date: Fri, 5 Jul 2024 04:01:44 +0800 Subject: [PATCH] support multi `clash_mode` item in rule item (cherry picked from commit 2ef85aafb5b94883af2d9305913f35296375b648) --- experimental/clashapi.go | 8 ++------ option/rule.go | 2 +- option/rule_dns.go | 2 +- route/rule_default.go | 2 +- route/rule_dns.go | 2 +- route/rule_item_clash_mode.go | 17 ++++++++++++----- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/experimental/clashapi.go b/experimental/clashapi.go index 872d9b99..54975258 100644 --- a/experimental/clashapi.go +++ b/experimental/clashapi.go @@ -55,9 +55,7 @@ func extraClashModeFromRule(rules []option.Rule) []string { for _, rule := range rules { switch rule.Type { case C.RuleTypeDefault: - if rule.DefaultOptions.ClashMode != "" { - clashMode = append(clashMode, rule.DefaultOptions.ClashMode) - } + clashMode = append(clashMode, rule.DefaultOptions.ClashMode...) case C.RuleTypeLogical: clashMode = append(clashMode, extraClashModeFromRule(rule.LogicalOptions.Rules)...) } @@ -70,9 +68,7 @@ func extraClashModeFromDNSRule(rules []option.DNSRule) []string { for _, rule := range rules { switch rule.Type { case C.RuleTypeDefault: - if rule.DefaultOptions.ClashMode != "" { - clashMode = append(clashMode, rule.DefaultOptions.ClashMode) - } + clashMode = append(clashMode, rule.DefaultOptions.ClashMode...) case C.RuleTypeLogical: clashMode = append(clashMode, extraClashModeFromDNSRule(rule.LogicalOptions.Rules)...) } diff --git a/option/rule.go b/option/rule.go index 03b55576..b66703e3 100644 --- a/option/rule.go +++ b/option/rule.go @@ -92,7 +92,7 @@ type _DefaultRule struct { PackageName Listable[string] `json:"package_name,omitempty"` User Listable[string] `json:"user,omitempty"` UserID Listable[int32] `json:"user_id,omitempty"` - ClashMode string `json:"clash_mode,omitempty"` + ClashMode Listable[string] `json:"clash_mode,omitempty"` WIFISSID Listable[string] `json:"wifi_ssid,omitempty"` WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"` RuleSet Listable[string] `json:"rule_set,omitempty"` diff --git a/option/rule_dns.go b/option/rule_dns.go index 2e03b425..0500a32f 100644 --- a/option/rule_dns.go +++ b/option/rule_dns.go @@ -93,7 +93,7 @@ type _DefaultDNSRule struct { User Listable[string] `json:"user,omitempty"` UserID Listable[int32] `json:"user_id,omitempty"` Outbound Listable[string] `json:"outbound,omitempty"` - ClashMode string `json:"clash_mode,omitempty"` + ClashMode Listable[string] `json:"clash_mode,omitempty"` WIFISSID Listable[string] `json:"wifi_ssid,omitempty"` WIFIBSSID Listable[string] `json:"wifi_bssid,omitempty"` RuleSet Listable[string] `json:"rule_set,omitempty"` diff --git a/route/rule_default.go b/route/rule_default.go index 4bf24472..df1adec6 100644 --- a/route/rule_default.go +++ b/route/rule_default.go @@ -203,7 +203,7 @@ func NewDefaultRule(router adapter.Router, logger log.ContextLogger, options opt rule.items = append(rule.items, item) rule.allItems = append(rule.allItems, item) } - if options.ClashMode != "" { + if len(options.ClashMode) > 0 { item := NewClashModeItem(router, options.ClashMode) rule.items = append(rule.items, item) rule.allItems = append(rule.allItems, item) diff --git a/route/rule_dns.go b/route/rule_dns.go index 455312da..9492e5a7 100644 --- a/route/rule_dns.go +++ b/route/rule_dns.go @@ -211,7 +211,7 @@ func NewDefaultDNSRule(router adapter.Router, logger log.ContextLogger, options rule.items = append(rule.items, item) rule.allItems = append(rule.allItems, item) } - if options.ClashMode != "" { + if len(options.ClashMode) > 0 { item := NewClashModeItem(router, options.ClashMode) rule.items = append(rule.items, item) rule.allItems = append(rule.allItems, item) diff --git a/route/rule_item_clash_mode.go b/route/rule_item_clash_mode.go index 70141f11..451587a3 100644 --- a/route/rule_item_clash_mode.go +++ b/route/rule_item_clash_mode.go @@ -4,19 +4,20 @@ import ( "strings" "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing/common" ) var _ RuleItem = (*ClashModeItem)(nil) type ClashModeItem struct { router adapter.Router - mode string + modes []string } -func NewClashModeItem(router adapter.Router, mode string) *ClashModeItem { +func NewClashModeItem(router adapter.Router, modes []string) *ClashModeItem { return &ClashModeItem{ router: router, - mode: mode, + modes: modes, } } @@ -25,9 +26,15 @@ func (r *ClashModeItem) Match(metadata *adapter.InboundContext) bool { if clashServer == nil { return false } - return strings.EqualFold(clashServer.Mode(), r.mode) + return common.Any(r.modes, func(mode string) bool { + return strings.EqualFold(clashServer.Mode(), mode) + }) } func (r *ClashModeItem) String() string { - return "clash_mode=" + r.mode + modeStr := r.modes[0] + if len(r.modes) > 1 { + modeStr = "[" + strings.Join(r.modes, ", ") + "]" + } + return "clash_mode=" + modeStr }