feat: fallback can be select by user

This commit is contained in:
adlyq 2022-05-23 00:40:27 +08:00
parent 79469fc8d6
commit c0eb9aac1c
5 changed files with 29 additions and 6 deletions

View file

@ -3,6 +3,7 @@ package outboundgroup
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"github.com/Dreamacro/clash/adapter/outbound" "github.com/Dreamacro/clash/adapter/outbound"
"github.com/Dreamacro/clash/component/dialer" "github.com/Dreamacro/clash/component/dialer"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
@ -12,6 +13,7 @@ import (
type Fallback struct { type Fallback struct {
*GroupBase *GroupBase
disableUDP bool disableUDP bool
selected string
} }
func (f *Fallback) Now() 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 { func (f *Fallback) findAliveProxy(touch bool) C.Proxy {
proxies := f.GetProxies(touch) proxies := f.GetProxies(touch)
for _, proxy := range proxies { al := proxies[0]
if proxy.Alive() { for i := len(proxies) - 1; i > -1; i-- {
proxy := proxies[i]
if proxy.Name() == f.selected && proxy.Alive() {
return proxy 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 { func NewFallback(option *GroupCommonOption, providers []provider.ProxyProvider) *Fallback {

View file

@ -76,7 +76,9 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide
providersMap[groupName] = pd providersMap[groupName] = pd
} else { } else {
if groupOption.URL == "" || groupOption.Interval == 0 { 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) hc := provider.NewHealthCheck(ps, groupOption.URL, uint(groupOption.Interval), groupOption.Lazy)

View file

@ -51,3 +51,7 @@ func tcpKeepAlive(c net.Conn) {
_ = tcp.SetKeepAlivePeriod(30 * time.Second) _ = tcp.SetKeepAlivePeriod(30 * time.Second)
} }
} }
type SelectAble interface {
Set(string) error
}

View file

@ -351,7 +351,7 @@ func patchSelectGroup(proxies map[string]C.Proxy) {
continue continue
} }
selector, ok := outbound.ProxyAdapter.(*outboundgroup.Selector) selector, ok := outbound.ProxyAdapter.(outboundgroup.SelectAble)
if !ok { if !ok {
continue continue
} }

View file

@ -83,7 +83,7 @@ func updateProxy(w http.ResponseWriter, r *http.Request) {
} }
proxy := r.Context().Value(CtxKeyProxy).(*adapter.Proxy) proxy := r.Context().Value(CtxKeyProxy).(*adapter.Proxy)
selector, ok := proxy.ProxyAdapter.(*outboundgroup.Selector) selector, ok := proxy.ProxyAdapter.(outboundgroup.SelectAble)
if !ok { if !ok {
render.Status(r, http.StatusBadRequest) render.Status(r, http.StatusBadRequest)
render.JSON(w, r, newError("Must be a Selector")) render.JSON(w, r, newError("Must be a Selector"))