Compare commits

...

15 Commits

Author SHA1 Message Date
ayflying
eb94e50f02 改为3天持久化 2025-11-24 11:20:18 +08:00
liaoyulong
26444905cf 新增DelByStopRank方法 调整SetScore 2025-11-21 10:29:46 +08:00
liaoyulong
d82b12ddaf Revert "解决后续data解析到空map为nil的问题"
This reverts commit f3e1ad74b5.
2025-11-19 14:56:12 +08:00
liaoyulong
b9a7970699 新增set分数的函数 2025-11-19 13:38:40 +08:00
ayflying
6f25e7baf3 更新核心库版本 2025-11-17 11:56:24 +08:00
513ed653e2 防止传入非法的属性key 2025-10-31 14:38:38 +08:00
31cd9896b6 Merge branch 'master' of new-gitlab.adesk.com:public_project/utility_go 2025-10-30 16:24:46 +08:00
9c99508bdd 发送时额外增加超时时间, 每5000条+1秒 2025-10-30 16:24:44 +08:00
liaoyulong
f3e1ad74b5 解决后续data解析到空map为nil的问题 2025-10-28 20:43:25 +08:00
liaoyulong
ba0f9bfd98 新增通用方法 2025-10-27 18:20:26 +08:00
ayflying
d07881bc29 上传失败后,尝试使用自己的代理地址 2025-10-27 16:12:11 +08:00
cdcdac3531 测试代码 更新 2025-10-20 15:10:43 +08:00
0a19bb5518 Merge branch 'master' of new-gitlab.adesk.com:public_project/utility_go 2025-10-20 14:50:27 +08:00
c7409fbf02 注释更新 2025-10-20 14:50:26 +08:00
ayflying
82d3824cae 更新服务器代码通过判断本地配置文件决定需要更新的目录 2025-10-20 10:14:19 +08:00
9 changed files with 136 additions and 19 deletions

View File

@@ -42,6 +42,9 @@ var (
getFileName, err := g.Cfg("hack").Get(ctx, "gfcli.build.name") getFileName, err := g.Cfg("hack").Get(ctx, "gfcli.build.name")
Filename := getFileName.String() Filename := getFileName.String()
getPath, err := g.Cfg("hack").Get(ctx, "gfcli.build.path")
Path := getPath.String()
//获取版本号 //获取版本号
getVersion, err := g.Cfg("hack").Get(ctx, "gfcli.build.version") getVersion, err := g.Cfg("hack").Get(ctx, "gfcli.build.version")
Version := getVersion.String() Version := getVersion.String()
@@ -89,7 +92,7 @@ var (
if v.Arch != "" && v.System != "" { if v.Arch != "" && v.System != "" {
systemName = v.System + "_" + v.Arch systemName = v.System + "_" + v.Arch
} }
var filename = path.Join(Version, systemName, Filename) var filename = path.Join(Path, Version, systemName, Filename)
g.Log().Debugf(ctx, "当前上传文件:"+filename) g.Log().Debugf(ctx, "当前上传文件:"+filename)
url[v.S3], err = UploadS3(v.S3, filename) url[v.S3], err = UploadS3(v.S3, filename)
@@ -109,9 +112,24 @@ var (
FileUrl: url[v.S3], FileUrl: url[v.S3],
}) })
if err != nil { if err != nil {
Proxy := g.Cfg().MustGet(ctx, "update_proxy", "http://192.168.50.170:10808").String() // 读取HTTP代理环境变量小写/大写通常都兼容,部分系统可能用大写)
g.Log().Debugf(ctx, "切换代理进行上传:err=%v", err) httpProxy := os.Getenv("http_proxy")
get, err = client.Proxy(Proxy).Post(ctx, address+"/callback/update", &UpdateReq{ if httpProxy == "" {
httpProxy = os.Getenv("HTTP_PROXY")
}
if httpProxy == "" {
// 读取HTTPS代理环境变量
httpProxy = os.Getenv("https_proxy")
if httpProxy == "" {
httpProxy = os.Getenv("HTTPS_PROXY")
}
}
// 如果没有读取到本地的代理,使用配置上传
if httpProxy == "" {
httpProxy = g.Cfg().MustGet(ctx, "update_proxy", "http://192.168.50.173:10808").String()
}
g.Log().Debugf(ctx, "切换代理进行上传:ip=%v,err=%v", httpProxy, err)
get, err = client.Proxy(httpProxy).Post(ctx, address+"/callback/update", &UpdateReq{
FileUrl: url[v.S3], FileUrl: url[v.S3],
}) })
} }

6
go.mod
View File

@@ -12,8 +12,8 @@ require (
github.com/go-pay/gopay v1.5.114 github.com/go-pay/gopay v1.5.114
github.com/go-pay/util v0.0.4 github.com/go-pay/util v0.0.4
github.com/goccy/go-json v0.10.5 github.com/goccy/go-json v0.10.5
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.3 github.com/gogf/gf/contrib/config/apollo/v2 v2.9.4
github.com/gogf/gf/v2 v2.9.3 github.com/gogf/gf/v2 v2.9.4
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20250916043522-9a14e3273609 github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20250916043522-9a14e3273609
github.com/minio/minio-go/v7 v7.0.95 github.com/minio/minio-go/v7 v7.0.95
@@ -72,7 +72,7 @@ require (
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
github.com/olekukonko/errors v1.1.0 // indirect github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.1.1 // indirect github.com/olekukonko/ll v0.1.1 // indirect
github.com/olekukonko/tablewriter v1.0.9 // indirect github.com/olekukonko/tablewriter v1.1.0 // indirect
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/philhofer/fwd v1.2.0 // indirect github.com/philhofer/fwd v1.2.0 // indirect

12
go.sum
View File

@@ -151,10 +151,10 @@ github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlnd
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.3 h1:/IcE+DmlQDWeDjnkKWr1Rql7VCLUxEqz7gXoQKZHd8o= github.com/gogf/gf/contrib/config/apollo/v2 v2.9.4 h1:l2vkPpqteotzpq0h5Qg6S/GK84WpPUZlRwPVfZSDbYs=
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.3/go.mod h1:mek4CnNsvdum4jYhf0PzaIYzoSBuSvVXyuCZG4I9qvw= github.com/gogf/gf/contrib/config/apollo/v2 v2.9.4/go.mod h1:mTfSf2Zm8+C49+rM7pK6AC8cwDSDxxwO8sLMNOl0yCI=
github.com/gogf/gf/v2 v2.9.3 h1:qjN4s55FfUzxZ1AE8vUHNDX3V0eIOUGXhF2DjRTVZQ4= github.com/gogf/gf/v2 v2.9.4 h1:6vleEWypot9WBPncP2GjbpgAUeG6Mzb1YESb9nPMkjY=
github.com/gogf/gf/v2 v2.9.3/go.mod h1:w6rcfD13SmO7FKI80k9LSLiSMGqpMYp50Nfkrrc2sEE= github.com/gogf/gf/v2 v2.9.4/go.mod h1:Ukl+5HUH9S7puBmNLR4L1zUqeRwi0nrW4OigOknEztU=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
@@ -321,8 +321,8 @@ github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.1.1 h1:9Dfeed5/Mgaxb9lHRAftLK9pVfYETvHn+If6lywVhJc= github.com/olekukonko/ll v0.1.1 h1:9Dfeed5/Mgaxb9lHRAftLK9pVfYETvHn+If6lywVhJc=
github.com/olekukonko/ll v0.1.1/go.mod h1:2dJo+hYZcJMLMbKwHEWvxCUbAOLc/CXWS9noET22Mdo= github.com/olekukonko/ll v0.1.1/go.mod h1:2dJo+hYZcJMLMbKwHEWvxCUbAOLc/CXWS9noET22Mdo=
github.com/olekukonko/tablewriter v1.0.9 h1:XGwRsYLC2bY7bNd93Dk51bcPZksWZmLYuaTHR0FqfL8= github.com/olekukonko/tablewriter v1.1.0 h1:N0LHrshF4T39KvI96fn6GT8HEjXRXYNDrDjKFDB7RIY=
github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo= github.com/olekukonko/tablewriter v1.1.0/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=

View File

@@ -77,7 +77,7 @@ func (s *sGameAct) Info(uid int64, actId int) (data *g.Var, err error) {
_, err = g.Redis().Set(ctx, keyCache, data) _, err = g.Redis().Set(ctx, keyCache, data)
var CacheKey = fmt.Sprintf("act:update:%d", uid) var CacheKey = fmt.Sprintf("act:update:%d", uid)
pkg.Cache("redis").Set(ctx, CacheKey, uid, time.Hour*24*1) pkg.Cache("redis").Set(ctx, CacheKey, uid, time.Hour*24*3)
return return
} }

View File

@@ -2,6 +2,7 @@ package systemLog
import ( import (
"context" "context"
v1 "github.com/ayflying/utility_go/api/admin/v1" v1 "github.com/ayflying/utility_go/api/admin/v1"
"github.com/ayflying/utility_go/service" "github.com/ayflying/utility_go/service"
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"

View File

@@ -72,6 +72,13 @@ var safePropertyRE = regexp.MustCompile(`[/"'\\\/]`)
// 设置某些字段只允许包含字母、数字和下划线 // 设置某些字段只允许包含字母、数字和下划线
var onlyWordRE = regexp.MustCompile(`\W`) var onlyWordRE = regexp.MustCompile(`\W`)
var nonWordCharRes = regexp.MustCompile(`[^\w]`)
func hasNonWordChar(s string) bool {
// 匹配非 \w 字符的正则表达式
return nonWordCharRes.MatchString(s)
}
var onlyWordPropertyNames = map[string]struct{}{ var onlyWordPropertyNames = map[string]struct{}{
"nickname": {}, "nickname": {},
} }
@@ -83,7 +90,12 @@ func SetOnlyWordProperty(propertyNames ...string) {
} }
func safeProperty(property map[string]any) { func safeProperty(property map[string]any) {
delkeys := []string{}
for k, v := range property { for k, v := range property {
if hasNonWordChar(k) {
delkeys = append(delkeys, k)
continue
}
if _, ok := onlyWordPropertyNames[k]; ok { if _, ok := onlyWordPropertyNames[k]; ok {
if _, ok := v.(string); ok { if _, ok := v.(string); ok {
property[k] = onlyWordRE.ReplaceAllString(gconv.String(v), "*") property[k] = onlyWordRE.ReplaceAllString(gconv.String(v), "*")
@@ -93,6 +105,9 @@ func safeProperty(property map[string]any) {
} }
} }
for _, delkey := range delkeys {
delete(property, delkey)
}
} }
func getLocationMapValue(key string) *time.Location { func getLocationMapValue(key string) *time.Location {
@@ -390,7 +405,7 @@ func (sdk *SDK) flush() {
// 发送消息 // 发送消息
func (sdk *SDK) send(logs []GameLog) { func (sdk *SDK) send(logs []GameLog) {
waitSecond := time.Duration(sdk.sdkConfig.FlushInterval/4) * time.Second waitSecond := time.Duration(sdk.sdkConfig.FlushInterval/4)*time.Second + time.Second*time.Duration(gconv.Int(len(logs)/5000))
timeoutCtx, cancel := context.WithTimeout(context.Background(), waitSecond) timeoutCtx, cancel := context.WithTimeout(context.Background(), waitSecond)
defer cancel() defer cancel()
data := make([][]any, 0, len(logs)) data := make([][]any, 0, len(logs))

View File

@@ -14,8 +14,9 @@ import (
func TestGamelog(t *testing.T) { func TestGamelog(t *testing.T) {
glsdk, err := gamelog.INIT(&gamelog.SDKConfig{ glsdk, err := gamelog.INIT(&gamelog.SDKConfig{
// 必填 // 必填
Pid: "test5", // 项目ID Pid: "test5", // 项目ID
BaseUrl: "http://47.76.178.47:10101", // 香港测试服上报地址 // BaseUrl: "http://47.76.178.47:10101", // 香港测试服上报地址
BaseUrl: "http://101.37.28.111:10101", // 香港测试服上报地址
// BaseUrl: "http://127.0.0.1:10101", // 本次测试上报地址 // BaseUrl: "http://127.0.0.1:10101", // 本次测试上报地址
ReportSk: "sngame2025", // xor混淆key ReportSk: "sngame2025", // xor混淆key
FlushInterval: 5, // 上报间隔 FlushInterval: 5, // 上报间隔
@@ -23,7 +24,7 @@ func TestGamelog(t *testing.T) {
// 可填 // 可填
RetryN: 2, // 默认每10次, 上传检查一次磁盘的失败数据 RetryN: 2, // 默认每10次, 上传检查一次磁盘的失败数据
ChanSize: 500, // 默认1000, 信道size ChanSize: 500, // 默认1000, 信道size
SendSaveType: 1, // 发送存储类型, 默认不设置为0代表文件存储, 1代表走kafka可实同步日志 SendSaveType: 2, // 发送存储类型, 默认不设置为0代表文件存储, 2代表走kafka可实同步日志
}) })
// 随机测试事件和属性 // 随机测试事件和属性

View File

@@ -2,9 +2,10 @@ package rank
import ( import (
"fmt" "fmt"
v1 "github.com/ayflying/utility_go/api/pkg/v1"
"time" "time"
v1 "github.com/ayflying/utility_go/api/pkg/v1"
"github.com/gogf/gf/v2/database/gredis" "github.com/gogf/gf/v2/database/gredis"
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx" "github.com/gogf/gf/v2/os/gctx"
@@ -98,6 +99,53 @@ func (r *F64CountRank) IncrScore(id int64, score int64) (curScore float64, err e
return return
} }
// SetScore 对指定ID的分数进行赋值,这样同分情况下先完成的在前面。
// 该方法首先更新成员的更新时间戳,然后更新成员的分数。
//
// 参数:
//
// id - 要操作的成员ID。
// score - 要更新的分数。
//
// 返回值:
//
// err - 操作过程中可能发生的错误。
//
// @Description:
// @receiver r
// @param id
// @param score
// @return err
func (r *F64CountRank) SetScore(id int64, score int) (err error) {
//如果分数小于0则删除
if score <= 0 {
err = r.DelScore(id)
if err != nil {
return
}
return
}
// 记录当前时间戳,用于更新成员的最新活动时间。
now := time.Now().UnixMilli()
// 将成员的更新时间戳加入到Redis的有序集合中确保成员的排序依据是最新的活动时间。
_, err = g.Redis().ZAdd(ctx, r.updateTs, &gredis.ZAddOption{}, gredis.ZAddMember{
Score: float64(now),
Member: id,
})
if err != nil {
return
}
// 覆盖成员的分数
_, err = g.Redis().ZAdd(ctx, r.name, &gredis.ZAddOption{}, gredis.ZAddMember{
Score: float64(score) + (3*1e13-float64(now))/1e14,
Member: id,
})
return
}
// todo暂时未使用 // todo暂时未使用
func (r *F64CountRank) GetCount() { func (r *F64CountRank) GetCount() {
count, _ := g.Redis().ZCard(ctx, r.name) count, _ := g.Redis().ZCard(ctx, r.name)
@@ -141,6 +189,35 @@ func (r *F64CountRank) DelScore(id int64) (err error) {
return return
} }
// DelByStopRank 删除指定名次后的元素
func (r *F64CountRank) DelByStopRank(stop int64) (err error) {
// 初始化一个空的int64切片用于存储指定排名范围内的元素。
var members []int64
// 使用Redis的ZRange命令获取指定排名范围内的元素。
// 选项Rev设置为true表示按照分数从高到低的顺序返回元素。
get, err := g.Redis().ZRange(ctx, r.name, stop, 9999999,
gredis.ZRangeOption{
Rev: true,
})
// 使用Scan方法将获取到的元素扫描到members切片中。
err = get.Scan(&members)
// 如果扫描过程中出现错误,直接返回错误。
if err != nil {
return
}
// 遍历members切片对于每个元素使用ZRem命令从更新时间集合中删除对应的成员。
for _, member := range members {
_, err = g.Redis().ZRem(ctx, r.updateTs, member)
// 忽略ZRem操作的错误因为即使元素不存在ZRem也不会返回错误。
}
//删除超过9999的数据
g.Redis().ZRemRangeByRank(ctx, r.name, 0, -(stop + 1))
return
}
// DelByRank 根据排名范围删除元素。 // DelByRank 根据排名范围删除元素。
// 该方法使用了Redis的有序集合数据结构通过ZRange和ZRemRangeByRank命令来实现。 // 该方法使用了Redis的有序集合数据结构通过ZRange和ZRemRangeByRank命令来实现。
// 参数start和stop定义了要删除的排名范围从start到stop包括start和stop // 参数start和stop定义了要删除的排名范围从start到stop包括start和stop

View File

@@ -152,3 +152,8 @@ func (m *timeMod) CheckIsBeRwd(createdTime, lastRwdTime time.Time, _now ...time.
// 如果是,则说明还没领过,可以领取 // 如果是,则说明还没领过,可以领取
return lastRwdTime.Before(refreshToday) return lastRwdTime.Before(refreshToday)
} }
// 获取指定时间的本月最后一刻
func (m *timeMod) EndOfMonth(t time.Time) time.Time {
return time.Date(t.Year(), t.Month()+1, 1, 0, 0, 0, 0, t.Location()).Add(-time.Second)
}