diff --git a/adapter/outboundgroup/fallback.go b/adapter/outboundgroup/fallback.go index 0a4dab41..22ca6db9 100644 --- a/adapter/outboundgroup/fallback.go +++ b/adapter/outboundgroup/fallback.go @@ -132,6 +132,7 @@ func NewFallback(option *GroupCommonOption, providers []provider.ProxyProvider) }, option.Filter, option.ExcludeFilter, + option.ExcludeType, providers, }), disableUDP: option.DisableUDP, diff --git a/adapter/outboundgroup/groupbase.go b/adapter/outboundgroup/groupbase.go index 426a1282..53c08ad6 100644 --- a/adapter/outboundgroup/groupbase.go +++ b/adapter/outboundgroup/groupbase.go @@ -20,6 +20,7 @@ type GroupBase struct { *outbound.Base filterRegs []*regexp2.Regexp excludeFilterReg *regexp2.Regexp + excludeTypeArray []string providers []provider.ProxyProvider failedTestMux sync.Mutex failedTimes int @@ -33,6 +34,7 @@ type GroupBaseOption struct { outbound.BaseOption filter string excludeFilter string + excludeType string providers []provider.ProxyProvider } @@ -41,6 +43,10 @@ func NewGroupBase(opt GroupBaseOption) *GroupBase { if opt.excludeFilter != "" { excludeFilterReg = regexp2.MustCompile(opt.excludeFilter, 0) } + var excludeTypeArray []string + if opt.excludeType!="" { + excludeTypeArray=strings.Split(opt.excludeType,"|") + } var filterRegs []*regexp2.Regexp if opt.filter != "" { @@ -54,6 +60,7 @@ func NewGroupBase(opt GroupBaseOption) *GroupBase { Base: outbound.NewBase(opt.BaseOption), filterRegs: filterRegs, excludeFilterReg: excludeFilterReg, + excludeTypeArray: excludeTypeArray, providers: opt.providers, failedTesting: atomic.NewBool(false), } @@ -148,6 +155,24 @@ func (gb *GroupBase) GetProxies(touch bool) []C.Proxy { } proxies = newProxies } + if gb.excludeTypeArray !=nil{ + var newProxies []C.Proxy + for _, p := range proxies { + mType := p.Type().String() + flag:=false + for i := range gb.excludeTypeArray { + if(strings.EqualFold(mType,gb.excludeTypeArray[i])){ + flag=true + } + + } + if(flag){ + continue + } + newProxies = append(newProxies, p) + } + proxies = newProxies + } if gb.excludeFilterReg != nil { var newProxies []C.Proxy diff --git a/adapter/outboundgroup/loadbalance.go b/adapter/outboundgroup/loadbalance.go index 7f875451..0098c505 100644 --- a/adapter/outboundgroup/loadbalance.go +++ b/adapter/outboundgroup/loadbalance.go @@ -229,6 +229,7 @@ func NewLoadBalance(option *GroupCommonOption, providers []provider.ProxyProvide }, option.Filter, option.ExcludeFilter, + option.ExcludeType, providers, }), strategyFn: strategyFn, diff --git a/adapter/outboundgroup/parser.go b/adapter/outboundgroup/parser.go index 53a82a60..d8c6db51 100644 --- a/adapter/outboundgroup/parser.go +++ b/adapter/outboundgroup/parser.go @@ -31,6 +31,7 @@ type GroupCommonOption struct { DisableUDP bool `group:"disable-udp,omitempty"` Filter string `group:"filter,omitempty"` ExcludeFilter string `group:"exclude-filter,omitempty"` + ExcludeType string `group:"exclude-type,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 43ef81c9..908204a5 100644 --- a/adapter/outboundgroup/relay.go +++ b/adapter/outboundgroup/relay.go @@ -191,6 +191,7 @@ func NewRelay(option *GroupCommonOption, providers []provider.ProxyProvider) *Re }, "", "", + "", providers, }), } diff --git a/adapter/outboundgroup/selector.go b/adapter/outboundgroup/selector.go index 71ebacce..de0e3c50 100644 --- a/adapter/outboundgroup/selector.go +++ b/adapter/outboundgroup/selector.go @@ -100,6 +100,7 @@ func NewSelector(option *GroupCommonOption, providers []provider.ProxyProvider) }, option.Filter, option.ExcludeFilter, + option.ExcludeType, providers, }), selected: "COMPATIBLE", diff --git a/adapter/outboundgroup/urltest.go b/adapter/outboundgroup/urltest.go index 55c1cc7c..1ded1656 100644 --- a/adapter/outboundgroup/urltest.go +++ b/adapter/outboundgroup/urltest.go @@ -144,6 +144,7 @@ func NewURLTest(option *GroupCommonOption, providers []provider.ProxyProvider, o option.Filter, option.ExcludeFilter, + option.ExcludeType, providers, }), fastSingle: singledo.NewSingle[C.Proxy](time.Second * 10), diff --git a/adapter/provider/parser.go b/adapter/provider/parser.go index e55ab914..3fdedce7 100644 --- a/adapter/provider/parser.go +++ b/adapter/provider/parser.go @@ -27,6 +27,7 @@ type proxyProviderSchema struct { Interval int `provider:"interval,omitempty"` Filter string `provider:"filter,omitempty"` ExcludeFilter string `provider:"exclude-filter,omitempty"` + ExcludeType string `provider:"exclude-type,omitempty"` HealthCheck healthCheckSchema `provider:"health-check,omitempty"` } @@ -63,5 +64,7 @@ func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvide interval := time.Duration(uint(schema.Interval)) * time.Second filter := schema.Filter excludeFilter := schema.ExcludeFilter - return NewProxySetProvider(name, interval, filter, excludeFilter, vehicle, hc) + excludeType:=schema.ExcludeType + + return NewProxySetProvider(name, interval, filter, excludeFilter,excludeType,vehicle, hc) } diff --git a/adapter/provider/provider.go b/adapter/provider/provider.go index 51f536fe..e32c2bec 100644 --- a/adapter/provider/provider.go +++ b/adapter/provider/provider.go @@ -141,11 +141,16 @@ func stopProxyProvider(pd *ProxySetProvider) { _ = pd.Fetcher.Destroy() } -func NewProxySetProvider(name string, interval time.Duration, filter string, excludeFilter string, vehicle types.Vehicle, hc *HealthCheck) (*ProxySetProvider, error) { +func NewProxySetProvider(name string, interval time.Duration, filter string, excludeFilter string,excludeType string, vehicle types.Vehicle, hc *HealthCheck) (*ProxySetProvider, error) { excludeFilterReg, err := regexp2.Compile(excludeFilter, 0) if err != nil { return nil, fmt.Errorf("invalid excludeFilter regex: %w", err) } + var excludeTypeArray []string + if excludeType !=""{ + excludeTypeArray=strings.Split(excludeType,"|") + } + var filterRegs []*regexp2.Regexp for _, filter := range strings.Split(filter, "`") { filterReg, err := regexp2.Compile(filter, 0) @@ -164,7 +169,7 @@ func NewProxySetProvider(name string, interval time.Duration, filter string, exc healthCheck: hc, } - fetcher := resource.NewFetcher[[]C.Proxy](name, interval, vehicle, proxiesParseAndFilter(filter, excludeFilter, filterRegs, excludeFilterReg), proxiesOnUpdate(pd)) + fetcher := resource.NewFetcher[[]C.Proxy](name, interval, vehicle, proxiesParseAndFilter(filter, excludeFilter, excludeTypeArray,filterRegs, excludeFilterReg), proxiesOnUpdate(pd)) pd.Fetcher = fetcher pd.getSubscriptionInfo() @@ -262,7 +267,7 @@ func proxiesOnUpdate(pd *proxySetProvider) func([]C.Proxy) { } } -func proxiesParseAndFilter(filter string, excludeFilter string, filterRegs []*regexp2.Regexp, excludeFilterReg *regexp2.Regexp) resource.Parser[[]C.Proxy] { +func proxiesParseAndFilter(filter string, excludeFilter string,excludeTypeArray []string, filterRegs []*regexp2.Regexp, excludeFilterReg *regexp2.Regexp) resource.Parser[[]C.Proxy] { return func(buf []byte) ([]C.Proxy, error) { schema := &ProxySchema{} @@ -282,6 +287,27 @@ func proxiesParseAndFilter(filter string, excludeFilter string, filterRegs []*re proxiesSet := map[string]struct{}{} for _, filterReg := range filterRegs { for idx, mapping := range schema.Proxies { + if nil !=excludeTypeArray && len(excludeTypeArray)>0{ + mType,ok:=mapping["type"] + if !ok { + continue + } + pType,ok:=mType.(string) + if !ok { + continue + } + flag:=false + for i := range excludeTypeArray { + if(strings.EqualFold(pType,excludeTypeArray[i])){ + flag=true + } + + } + if(flag){ + continue + } + + } mName, ok := mapping["name"] if !ok { continue diff --git a/common/convert/converter.go b/common/convert/converter.go index 24043a41..1b0e8cf3 100644 --- a/common/convert/converter.go +++ b/common/convert/converter.go @@ -162,8 +162,11 @@ func ConvertsV2Ray(buf []byte) ([]map[string]any, error) { if jsonDc.Decode(&values) != nil { continue } - - name := uniqueName(names, values["ps"].(string)) + tempName,ok:=values["ps"].(string) + if !ok{ + continue + } + name := uniqueName(names, tempName) vmess := make(map[string]any, 20) vmess["name"] = name