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, } } 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) { p.m.Lock() defer p.m.Unlock() p.proxies = proxies }