diff --git a/adapter/outboundgroup/fallback.go b/adapter/outboundgroup/fallback.go index a433d54d..0a4dab41 100644 --- a/adapter/outboundgroup/fallback.go +++ b/adapter/outboundgroup/fallback.go @@ -131,6 +131,7 @@ func NewFallback(option *GroupCommonOption, providers []provider.ProxyProvider) RoutingMark: option.RoutingMark, }, option.Filter, + option.ExcludeFilter, providers, }), disableUDP: option.DisableUDP, diff --git a/adapter/outboundgroup/groupbase.go b/adapter/outboundgroup/groupbase.go index fbe887e3..8dd57861 100644 --- a/adapter/outboundgroup/groupbase.go +++ b/adapter/outboundgroup/groupbase.go @@ -18,23 +18,30 @@ import ( type GroupBase struct { *outbound.Base - filterRegs []*regexp2.Regexp - providers []provider.ProxyProvider - failedTestMux sync.Mutex - failedTimes int - failedTime time.Time - failedTesting *atomic.Bool - proxies [][]C.Proxy - versions []atomic.Uint32 + filterRegs []*regexp2.Regexp + excludeFilterReg *regexp2.Regexp + providers []provider.ProxyProvider + failedTestMux sync.Mutex + failedTimes int + failedTime time.Time + failedTesting *atomic.Bool + proxies [][]C.Proxy + versions []atomic.Uint32 } type GroupBaseOption struct { outbound.BaseOption - filter string - providers []provider.ProxyProvider + filter string + excludeFilter string + providers []provider.ProxyProvider } func NewGroupBase(opt GroupBaseOption) *GroupBase { + var excludeFilterReg *regexp2.Regexp + if opt.excludeFilter != "" { + excludeFilterReg = regexp2.MustCompile(opt.excludeFilter, 0) + } + var filterRegs []*regexp2.Regexp if opt.filter != "" { for _, filter := range strings.Split(opt.filter, "`") { @@ -44,10 +51,11 @@ func NewGroupBase(opt GroupBaseOption) *GroupBase { } gb := &GroupBase{ - Base: outbound.NewBase(opt.BaseOption), - filterRegs: filterRegs, - providers: opt.providers, - failedTesting: atomic.NewBool(false), + Base: outbound.NewBase(opt.BaseOption), + filterRegs: filterRegs, + excludeFilterReg: excludeFilterReg, + providers: opt.providers, + failedTesting: atomic.NewBool(false), } gb.proxies = make([][]C.Proxy, len(opt.providers)) @@ -146,6 +154,18 @@ func (gb *GroupBase) GetProxies(touch bool) []C.Proxy { proxies = newProxies } + if gb.excludeFilterReg != nil { + var newProxies []C.Proxy + for _, p := range proxies { + name := p.Name() + if mat, _ := gb.excludeFilterReg.FindStringMatch(name); mat != nil { + continue + } + newProxies = append(newProxies, p) + } + proxies = newProxies + } + return proxies } diff --git a/adapter/outboundgroup/loadbalance.go b/adapter/outboundgroup/loadbalance.go index 87d7de7b..a396f420 100644 --- a/adapter/outboundgroup/loadbalance.go +++ b/adapter/outboundgroup/loadbalance.go @@ -228,6 +228,7 @@ func NewLoadBalance(option *GroupCommonOption, providers []provider.ProxyProvide RoutingMark: option.RoutingMark, }, option.Filter, + option.ExcludeFilter, providers, }), strategyFn: strategyFn, diff --git a/adapter/outboundgroup/parser.go b/adapter/outboundgroup/parser.go index b808079b..53a82a60 100644 --- a/adapter/outboundgroup/parser.go +++ b/adapter/outboundgroup/parser.go @@ -21,15 +21,16 @@ var ( type GroupCommonOption struct { outbound.BasicOption - Name string `group:"name"` - Type string `group:"type"` - Proxies []string `group:"proxies,omitempty"` - Use []string `group:"use,omitempty"` - URL string `group:"url,omitempty"` - Interval int `group:"interval,omitempty"` - Lazy bool `group:"lazy,omitempty"` - DisableUDP bool `group:"disable-udp,omitempty"` - Filter string `group:"filter,omitempty"` + Name string `group:"name"` + Type string `group:"type"` + Proxies []string `group:"proxies,omitempty"` + Use []string `group:"use,omitempty"` + URL string `group:"url,omitempty"` + Interval int `group:"interval,omitempty"` + Lazy bool `group:"lazy,omitempty"` + DisableUDP bool `group:"disable-udp,omitempty"` + Filter string `group:"filter,omitempty"` + ExcludeFilter string `group:"exclude-filter,omitempty"` } func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, providersMap map[string]types.ProxyProvider) (C.ProxyAdapter, error) { diff --git a/adapter/outboundgroup/relay.go b/adapter/outboundgroup/relay.go index 729f4137..66954375 100644 --- a/adapter/outboundgroup/relay.go +++ b/adapter/outboundgroup/relay.go @@ -185,6 +185,7 @@ func NewRelay(option *GroupCommonOption, providers []provider.ProxyProvider) *Re RoutingMark: option.RoutingMark, }, "", + "", providers, }), } diff --git a/adapter/outboundgroup/selector.go b/adapter/outboundgroup/selector.go index dcf07707..71ebacce 100644 --- a/adapter/outboundgroup/selector.go +++ b/adapter/outboundgroup/selector.go @@ -99,6 +99,7 @@ func NewSelector(option *GroupCommonOption, providers []provider.ProxyProvider) RoutingMark: option.RoutingMark, }, option.Filter, + option.ExcludeFilter, providers, }), selected: "COMPATIBLE", diff --git a/adapter/outboundgroup/urltest.go b/adapter/outboundgroup/urltest.go index 1e69652c..55c1cc7c 100644 --- a/adapter/outboundgroup/urltest.go +++ b/adapter/outboundgroup/urltest.go @@ -143,6 +143,7 @@ func NewURLTest(option *GroupCommonOption, providers []provider.ProxyProvider, o }, option.Filter, + option.ExcludeFilter, providers, }), fastSingle: singledo.NewSingle[C.Proxy](time.Second * 10), diff --git a/adapter/provider/provider.go b/adapter/provider/provider.go index b5969071..6f16a813 100644 --- a/adapter/provider/provider.go +++ b/adapter/provider/provider.go @@ -6,7 +6,7 @@ import ( "errors" "fmt" "github.com/Dreamacro/clash/common/convert" - netHttp "github.com/Dreamacro/clash/component/http" + clashHttp "github.com/Dreamacro/clash/component/http" "github.com/Dreamacro/clash/component/resource" "github.com/Dreamacro/clash/log" "github.com/dlclark/regexp2" @@ -110,7 +110,7 @@ func (pp *proxySetProvider) getSubscriptionInfo() { go func() { ctx, cancel := context.WithTimeout(context.Background(), time.Second*90) defer cancel() - resp, err := netHttp.HttpRequest(ctx, pp.Vehicle().(*resource.HTTPVehicle).Url(), + resp, err := clashHttp.HttpRequest(ctx, pp.Vehicle().(*resource.HTTPVehicle).Url(), http.MethodGet, http.Header{"User-Agent": {"clash"}}, nil) if err != nil { return @@ -119,7 +119,7 @@ func (pp *proxySetProvider) getSubscriptionInfo() { userInfoStr := strings.TrimSpace(resp.Header.Get("subscription-userinfo")) if userInfoStr == "" { - resp2, err := netHttp.HttpRequest(ctx, pp.Vehicle().(*resource.HTTPVehicle).Url(), + resp2, err := clashHttp.HttpRequest(ctx, pp.Vehicle().(*resource.HTTPVehicle).Url(), http.MethodGet, http.Header{"User-Agent": {"Quantumultx"}}, nil) if err != nil { return diff --git a/component/resource/vehicle.go b/component/resource/vehicle.go index 5e05a403..927a9604 100644 --- a/component/resource/vehicle.go +++ b/component/resource/vehicle.go @@ -2,7 +2,7 @@ package resource import ( "context" - netHttp "github.com/Dreamacro/clash/component/http" + clashHttp "github.com/Dreamacro/clash/component/http" types "github.com/Dreamacro/clash/constant/provider" "io" "net/http" @@ -50,7 +50,7 @@ func (h *HTTPVehicle) Path() string { func (h *HTTPVehicle) Read() ([]byte, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) defer cancel() - resp, err := netHttp.HttpRequest(ctx, h.url, http.MethodGet, nil, nil) + resp, err := clashHttp.HttpRequest(ctx, h.url, http.MethodGet, nil, nil) if err != nil { return nil, err }