proxy-detector/pkg/proxy/structs/list.go

122 lines
2.2 KiB
Go

package structs
import (
"sync"
C "github.com/metacubex/mihomo/constant"
"github.com/samber/lo"
)
var ProxiesList = NewProxies(make([]Proxy, 0))
type Proxies struct {
proxies []Proxy
names *sync.Map
m sync.RWMutex
}
type Proxy struct {
p C.Proxy
mapping map[string]any
}
func NewProxy(p C.Proxy, mapping map[string]any) Proxy {
return Proxy{
p: p,
mapping: mapping,
}
}
// 返回ClashProxy
func (p *Proxy) ClashProxy() C.Proxy {
return p.p
}
// 返回mapping
func (p *Proxy) Mapping() map[string]any {
return p.mapping
}
func NewProxies(proxies []Proxy) *Proxies {
return &Proxies{
proxies: proxies,
names: &sync.Map{},
}
}
func (p *Proxies) Add(proxies []Proxy) {
for _, proxy := range proxies {
name := proxy.ClashProxy().Name()
_, loaded := p.names.LoadOrStore(name, struct{}{})
if !loaded {
p.m.Lock()
p.proxies = append(p.proxies, proxy)
p.m.Unlock()
}
}
}
// 删除
func (p *Proxies) Remove(proxies []Proxy) {
del := lo.SliceToMap(proxies, func(item Proxy) (string, struct{}) {
return item.ClashProxy().Name(), struct{}{}
})
var news = make([]Proxy, 0, len(p.proxies)-len(proxies))
for _, proxy := range p.proxies {
if _, ok := del[proxy.ClashProxy().Name()]; !ok {
news = append(news, proxy)
} else {
p.names.Delete(proxy.ClashProxy().Name())
}
}
p.m.Lock()
p.proxies = news
p.m.Unlock()
}
// 遍历
func (p *Proxies) ForEach(f func(proxy Proxy)) {
p.m.RLock()
defer p.m.RUnlock()
for _, proxy := range p.proxies {
f(proxy)
}
}
func (p *Proxies) Get() []Proxy {
p.m.RLock()
defer p.m.RUnlock()
return p.proxies
}
// 获取长度
func (p *Proxies) Len() int {
p.m.RLock()
defer p.m.RUnlock()
return len(p.proxies)
}
// 获取mapping列表
func (p *Proxies) Mapping() []map[string]any {
p.m.RLock()
defer p.m.RUnlock()
var mappings = make([]map[string]any, 0, len(p.proxies))
for _, proxy := range p.proxies {
mappings = append(mappings, proxy.Mapping())
}
return mappings
}
// 替换
func (p *Proxies) Replace(proxies []Proxy) {
names := &sync.Map{}
for _, proxy := range proxies {
name := proxy.ClashProxy().Name()
names.Store(name, struct{}{})
}
p.m.Lock()
defer p.m.Unlock()
p.names = names
p.proxies = proxies
}