package hy2 import ( "net" "sync" "github.com/InazumaV/V2bX/api/panel" "github.com/InazumaV/V2bX/common/counter" vCore "github.com/InazumaV/V2bX/core" "github.com/apernet/hysteria/core/v2/server" ) var _ server.Authenticator = &V2bX{} type V2bX struct { usersMap map[string]int mutex sync.RWMutex } func (v *V2bX) Authenticate(addr net.Addr, auth string, tx uint64) (ok bool, id string) { v.mutex.RLock() defer v.mutex.RUnlock() if _, exists := v.usersMap[auth]; exists { return true, auth } return false, "" } func (h *Hysteria2) AddUsers(p *vCore.AddUsersParams) (added int, err error) { var wg sync.WaitGroup for _, user := range p.Users { wg.Add(1) go func(u panel.UserInfo) { defer wg.Done() h.Auth.mutex.Lock() h.Auth.usersMap[u.Uuid] = u.Id h.Auth.mutex.Unlock() }(user) } wg.Wait() return len(p.Users), nil } func (h *Hysteria2) DelUsers(users []panel.UserInfo, tag string, _ *panel.NodeInfo) error { var wg sync.WaitGroup for _, user := range users { wg.Add(1) go func(u panel.UserInfo) { defer wg.Done() h.Auth.mutex.Lock() delete(h.Auth.usersMap, u.Uuid) h.Auth.mutex.Unlock() }(user) } wg.Wait() return nil } func (h *Hysteria2) GetUserTrafficSlice(tag string, reset bool) ([]panel.UserTraffic, error) { trafficSlice := make([]panel.UserTraffic, 0) h.Auth.mutex.RLock() defer h.Auth.mutex.RUnlock() if _, ok := h.Hy2nodes[tag]; !ok { return nil, nil } hook := h.Hy2nodes[tag].TrafficLogger.(*HookServer) if v, ok := hook.Counter.Load(tag); ok { c := v.(*counter.TrafficCounter) c.Counters.Range(func(key, value interface{}) bool { uuid := key.(string) traffic := value.(*counter.TrafficStorage) up := traffic.UpCounter.Load() down := traffic.DownCounter.Load() if up+down > hook.ReportMinTrafficBytes { if reset { traffic.UpCounter.Store(0) traffic.DownCounter.Store(0) } trafficSlice = append(trafficSlice, panel.UserTraffic{ UID: h.Auth.usersMap[uuid], Upload: up, Download: down, }) } return true }) if len(trafficSlice) == 0 { return nil, nil } return trafficSlice, nil } return nil, nil }