From c0eb9aac1c9851bd8765a8278764eb85e7d6c259 Mon Sep 17 00:00:00 2001 From: adlyq Date: Mon, 23 May 2022 00:40:27 +0800 Subject: [PATCH] feat: fallback can be select by user --- adapter/outboundgroup/fallback.go | 23 ++++++++++++++++++++--- adapter/outboundgroup/parser.go | 4 +++- adapter/outboundgroup/util.go | 4 ++++ hub/executor/executor.go | 2 +- hub/route/proxies.go | 2 +- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/adapter/outboundgroup/fallback.go b/adapter/outboundgroup/fallback.go index 33ff27eb..cd09b747 100644 --- a/adapter/outboundgroup/fallback.go +++ b/adapter/outboundgroup/fallback.go @@ -3,6 +3,7 @@ package outboundgroup import ( "context" "encoding/json" + "errors" "github.com/Dreamacro/clash/adapter/outbound" "github.com/Dreamacro/clash/component/dialer" C "github.com/Dreamacro/clash/constant" @@ -12,6 +13,7 @@ import ( type Fallback struct { *GroupBase disableUDP bool + selected string } func (f *Fallback) Now() string { @@ -75,13 +77,28 @@ func (f *Fallback) Unwrap(metadata *C.Metadata) C.Proxy { func (f *Fallback) findAliveProxy(touch bool) C.Proxy { proxies := f.GetProxies(touch) - for _, proxy := range proxies { - if proxy.Alive() { + al := proxies[0] + for i := len(proxies) - 1; i > -1; i-- { + proxy := proxies[i] + if proxy.Name() == f.selected && proxy.Alive() { return proxy } + if proxy.Alive() { + al = proxy + } + } + return al +} + +func (f *Fallback) Set(name string) error { + for _, proxy := range f.GetProxies(false) { + if proxy.Name() == name { + f.selected = name + return nil + } } - return proxies[0] + return errors.New("proxy not exist") } func NewFallback(option *GroupCommonOption, providers []provider.ProxyProvider) *Fallback { diff --git a/adapter/outboundgroup/parser.go b/adapter/outboundgroup/parser.go index 6fda4af7..76a1efea 100644 --- a/adapter/outboundgroup/parser.go +++ b/adapter/outboundgroup/parser.go @@ -76,7 +76,9 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide providersMap[groupName] = pd } else { if groupOption.URL == "" || groupOption.Interval == 0 { - return nil, errMissHealthCheck + //return nil, errMissHealthCheck + groupOption.URL = "http://www.gstatic.com/generate_204" + groupOption.Interval = 300 } hc := provider.NewHealthCheck(ps, groupOption.URL, uint(groupOption.Interval), groupOption.Lazy) diff --git a/adapter/outboundgroup/util.go b/adapter/outboundgroup/util.go index cbe9b489..e1700d94 100644 --- a/adapter/outboundgroup/util.go +++ b/adapter/outboundgroup/util.go @@ -51,3 +51,7 @@ func tcpKeepAlive(c net.Conn) { _ = tcp.SetKeepAlivePeriod(30 * time.Second) } } + +type SelectAble interface { + Set(string) error +} diff --git a/hub/executor/executor.go b/hub/executor/executor.go index c05479ed..6e53d567 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -351,7 +351,7 @@ func patchSelectGroup(proxies map[string]C.Proxy) { continue } - selector, ok := outbound.ProxyAdapter.(*outboundgroup.Selector) + selector, ok := outbound.ProxyAdapter.(outboundgroup.SelectAble) if !ok { continue } diff --git a/hub/route/proxies.go b/hub/route/proxies.go index 5cb084f9..baffb1f5 100644 --- a/hub/route/proxies.go +++ b/hub/route/proxies.go @@ -83,7 +83,7 @@ func updateProxy(w http.ResponseWriter, r *http.Request) { } proxy := r.Context().Value(CtxKeyProxy).(*adapter.Proxy) - selector, ok := proxy.ProxyAdapter.(*outboundgroup.Selector) + selector, ok := proxy.ProxyAdapter.(outboundgroup.SelectAble) if !ok { render.Status(r, http.StatusBadRequest) render.JSON(w, r, newError("Must be a Selector"))