package node import ( "strconv" "github.com/InazumaV/V2bX/api/panel" log "github.com/sirupsen/logrus" ) func (c *Controller) reportUserTrafficTask() (err error) { // Get User traffic userTraffic := make([]panel.UserTraffic, 0) for i := range c.userList { up, down := c.server.GetUserTraffic(c.tag, c.userList[i].Uuid, true) if up > 0 || down > 0 { if c.LimitConfig.EnableDynamicSpeedLimit { c.traffic[c.userList[i].Uuid] += up + down } userTraffic = append(userTraffic, panel.UserTraffic{ UID: (c.userList)[i].Id, Upload: up, Download: down}) } } if len(userTraffic) > 0 { err = c.apiClient.ReportUserTraffic(userTraffic) if err != nil { log.WithFields(log.Fields{ "tag": c.tag, "err": err, }).Info("Report user traffic failed") } else { log.WithField("tag", c.tag).Infof("Report %d users traffic", len(userTraffic)) } } if onlineDevice, err := c.limiter.GetOnlineDevice(); err != nil { log.Print(err) } else if len(*onlineDevice) > 0 { // Only report user has traffic > 100kb to allow ping test var result []panel.OnlineUser var nocountUID = make(map[int]struct{}) for _, traffic := range userTraffic { total := traffic.Upload + traffic.Download if total < int64(c.Options.DeviceOnlineMinTraffic*1000) { nocountUID[traffic.UID] = struct{}{} } } for _, online := range *onlineDevice { if _, ok := nocountUID[online.UID]; !ok { result = append(result, online) } } data := make(map[int][]string) for _, onlineuser := range result { // json structure: { UID1:["ip1","ip2"],UID2:["ip3","ip4"] } data[onlineuser.UID] = append(data[onlineuser.UID], onlineuser.IP) } if err = c.apiClient.ReportNodeOnlineUsers(&data); err != nil { log.WithFields(log.Fields{ "tag": c.tag, "err": err, }).Info("Report online users failed") } else { log.WithField("tag", c.tag).Infof("Total %d online users, %d Reported", len(*onlineDevice), len(result)) } } userTraffic = nil return nil } func compareUserList(old, new []panel.UserInfo) (deleted, added []panel.UserInfo) { oldMap := make(map[string]int) for i, user := range old { key := user.Uuid + strconv.Itoa(user.SpeedLimit) oldMap[key] = i } for _, user := range new { key := user.Uuid + strconv.Itoa(user.SpeedLimit) if _, exists := oldMap[key]; !exists { added = append(added, user) } else { delete(oldMap, key) } } for _, index := range oldMap { deleted = append(deleted, old[index]) } return deleted, added }