Compare commits

...

2 Commits

Author SHA1 Message Date
wyx2685
8d225f811b fix: 用户限速信息不能同步更新BUG 2025-07-13 09:23:06 +09:00
wyx2685
f6b587b275 prefer msgpack for userlist 2025-07-04 11:37:23 +09:00
4 changed files with 34 additions and 12 deletions

View File

@@ -2,8 +2,11 @@ package panel
import (
"fmt"
"io"
"strings"
"github.com/goccy/go-json"
"github.com/vmihailenco/msgpack"
)
type OnlineUser struct {
@@ -12,15 +15,14 @@ type OnlineUser struct {
}
type UserInfo struct {
Id int `json:"id"`
Uuid string `json:"uuid"`
SpeedLimit int `json:"speed_limit"`
DeviceLimit int `json:"device_limit"`
Id int `json:"id" msgpack:"id"`
Uuid string `json:"uuid" msgpack:"uuid"`
SpeedLimit int `json:"speed_limit" msgpack:"speed_limit"`
DeviceLimit int `json:"device_limit" msgpack:"device_limit"`
}
type UserListBody struct {
//Msg string `json:"msg"`
Users []UserInfo `json:"users"`
Users []UserInfo `json:"users" msgpack:"users"`
}
type AliveMap struct {
@@ -32,7 +34,8 @@ func (c *Client) GetUserList() ([]UserInfo, error) {
const path = "/api/v1/server/UniProxy/user"
r, err := c.client.R().
SetHeader("If-None-Match", c.userEtag).
ForceContentType("application/json").
SetHeader("X-Response-Format", "msgpack").
SetDoNotParseResponse(true).
Get(path)
if r == nil || r.RawResponse == nil {
return nil, fmt.Errorf("received nil response or raw response")
@@ -47,8 +50,19 @@ func (c *Client) GetUserList() ([]UserInfo, error) {
return nil, err
}
userlist := &UserListBody{}
if err := json.Unmarshal(r.Body(), userlist); err != nil {
return nil, fmt.Errorf("unmarshal user list error: %w", err)
if strings.Contains(r.Header().Get("Content-Type"), "application/x-msgpack") {
decoder := msgpack.NewDecoder(r.RawResponse.Body)
if err := decoder.Decode(userlist); err != nil {
return nil, fmt.Errorf("decode user list error: %w", err)
}
} else {
bodyBytes, err := io.ReadAll(r.RawResponse.Body)
if err != nil {
return nil, fmt.Errorf("read response body error: %w", err)
}
if err := json.Unmarshal(bodyBytes, userlist); err != nil {
return nil, fmt.Errorf("unmarshal user list error: %w", err)
}
}
c.userEtag = r.Header().Get("ETag")
return userlist.Users, nil

3
go.mod
View File

@@ -20,6 +20,7 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.9.1
github.com/spf13/viper v1.19.0
github.com/vmihailenco/msgpack v4.0.4+incompatible
github.com/xtls/xray-core v1.250516.1-0.20250608135303-fbae89d017ae
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.39.0
@@ -124,6 +125,7 @@ require (
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
@@ -314,6 +316,7 @@ require (
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/api v0.214.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect

4
go.sum
View File

@@ -1086,6 +1086,8 @@ github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5J
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/volcengine/volc-sdk-golang v1.0.189 h1:VMDTHWYXakXJtZqPYn0As/h4eB0c4imvyru6mIp+o60=
github.com/volcengine/volc-sdk-golang v1.0.189/go.mod h1:u0VtPvlXWpXDTmc9IHkaW1q+5Jjwus4oAqRhNMDRInE=
github.com/vultr/govultr/v3 v3.9.1 h1:uxSIb8Miel7tqTs3ee+z3t+JelZikwqBBsZzCOPBy/8=
@@ -1548,6 +1550,8 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=

View File

@@ -24,11 +24,11 @@ type Limiter struct {
DomainRules []*regexp.Regexp
ProtocolRules []string
SpeedLimit int
UserOnlineIP *sync.Map // Key: Name, value: {Key: Ip, value: Uid}
UserOnlineIP *sync.Map // Key: TagUUID, value: {Key: Ip, value: Uid}
OldUserOnline *sync.Map // Key: Ip, value: Uid
UUIDtoUID map[string]int // Key: UUID, value: Uid
UserLimitInfo *sync.Map // Key: Uid value: UserLimitInfo
SpeedLimiter *sync.Map // key: Uid, value: *ratelimit.Bucket
UserLimitInfo *sync.Map // Key: TagUUID value: UserLimitInfo
SpeedLimiter *sync.Map // key: TagUUID, value: *ratelimit.Bucket
AliveList map[int]int // Key: Uid, value: alive_ip
}
@@ -91,6 +91,7 @@ func (l *Limiter) UpdateUser(tag string, added []panel.UserInfo, deleted []panel
for i := range deleted {
l.UserLimitInfo.Delete(format.UserTag(tag, deleted[i].Uuid))
l.UserOnlineIP.Delete(format.UserTag(tag, deleted[i].Uuid))
l.SpeedLimiter.Delete(format.UserTag(tag, deleted[i].Uuid))
delete(l.UUIDtoUID, deleted[i].Uuid)
delete(l.AliveList, deleted[i].Id)
}