From 57404b2dcdc7b08ac39926442e9b2f2ab75ade07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?= <101934327+fangliuyu@users.noreply.github.com> Date: Thu, 3 Nov 2022 16:38:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=AD=BE=E5=88=B0=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=EF=BC=8Cqqwife=E6=8F=92=E4=BB=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=A4=BC=E7=89=A9=E7=B3=BB=E7=BB=9F=20(#480)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 ++- go.mod | 2 +- go.sum | 4 +- plugin/aipaint/aipaint.go | 2 +- plugin/qqwife/command.go | 72 ++++++++++++ plugin/qqwife/function.go | 69 ++++++------ plugin/score/model.go | 2 +- plugin/score/sign_in.go | 224 +++++++++++++++++++++++++++++--------- 8 files changed, 295 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 12764ba4..fdbb9703 100644 --- a/README.md +++ b/README.md @@ -641,17 +641,19 @@ print("run[CQ:image,file="+j["img"]+"]") - [x] 设置CD为xx小时 - - [x] 允许/禁止自由恋爱 + - [x] [允许|禁止]自由恋爱 - - [x] 允许/禁止牛头人 + - [x] [允许|禁止]牛头人 - [x] 娶群友 - - [x] (娶|嫁)[@对方QQ] + - [x] [娶|嫁][@对方QQ] - [x] 当[对方Q号|@对方QQ]的小三 - [x] 做媒 @攻方QQ @受方QQ + + - [x] 买礼物给[对方Q号|@对方QQ] - [x] 群老婆列表 @@ -1092,6 +1094,11 @@ print("run[CQ:image,file="+j["img"]+"]") - [x] 签到 - [x] 获得签到背景[@xxx] | 获得签到背景 + - [x] 查看等级排名 + - 注:跨群排行 + - [x] 查看我的钱包 + - [x] 查看钱包排名 + - 注:本群排行,若群人数太多不建议使用该功能!!!
diff --git a/go.mod b/go.mod index 3da0f8b8..852de31e 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/Baidu-AIP/golang-sdk v1.1.1 github.com/Coloured-glaze/gg v1.3.4 - github.com/FloatTech/AnimeAPI v1.5.2-0.20221029160612-a8d3d8e63d8f + github.com/FloatTech/AnimeAPI v1.5.2-0.20221101144606-ec2f4e59d0ef github.com/FloatTech/floatbox v0.0.0-20221029160423-446812ec82d9 github.com/FloatTech/sqlite v0.5.0 github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b diff --git a/go.sum b/go.sum index 0baf05e1..c91b427b 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/Coloured-glaze/gg v1.3.4 h1:l31zIF/HaVwkzjrj+A56RGQoSKyKuR1IWtIrqXGFStI= github.com/Coloured-glaze/gg v1.3.4/go.mod h1:Ih5NLNNDHOy3RJbB0EPqGTreIzq/H02TGThIagh8HJg= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/FloatTech/AnimeAPI v1.5.2-0.20221029160612-a8d3d8e63d8f h1:fIh53+XMesj7rv6OauvsXGiWQoYEmk2v6XbuwgwAL8Q= -github.com/FloatTech/AnimeAPI v1.5.2-0.20221029160612-a8d3d8e63d8f/go.mod h1:7ZXHFEgAOFvfbgIwgyFl8G/ISnUl1KvWBzngoCpQVLg= +github.com/FloatTech/AnimeAPI v1.5.2-0.20221101144606-ec2f4e59d0ef h1:IO4ZSaTrRTidAXqUH86dHgzk8vRlw2+YX0Oz+4n/oeg= +github.com/FloatTech/AnimeAPI v1.5.2-0.20221101144606-ec2f4e59d0ef/go.mod h1:7ZXHFEgAOFvfbgIwgyFl8G/ISnUl1KvWBzngoCpQVLg= github.com/FloatTech/floatbox v0.0.0-20221029160423-446812ec82d9 h1:HYJ7lwaqaOKmbYooPUMWxMhXRTp+JItoyeqa320ARD4= github.com/FloatTech/floatbox v0.0.0-20221029160423-446812ec82d9/go.mod h1:w+ND28mRaJvxUJ6pRXS6i4cLzutpXsWyroutCzBdL78= github.com/FloatTech/sqlite v0.5.0 h1:U7J5Omc534PqmH6csfu+ypCo3DS8L91l5lTsxUu3b/U= diff --git a/plugin/aipaint/aipaint.go b/plugin/aipaint/aipaint.go index ca62398a..0beb7cf1 100644 --- a/plugin/aipaint/aipaint.go +++ b/plugin/aipaint/aipaint.go @@ -61,7 +61,7 @@ func init() { // 插件主体 "通过 http://91.217.139.190:5010/token 获取token\n" + "[prompt]参数如下\n" + "tags:tag词条\nntags:ntag词条\nshape:[Portrait|Landscape|Square]\nscale:[6:20]\nseed:种子\n" + - "参数与参数内容用:连接,每个参数之间用回车或者&分割", + "参数与参数内容用:连接,每个参数之间用回车分割", PrivateDataFolder: "aipaint", }) datapath = file.BOTPATH + "/" + engine.DataFolder() diff --git a/plugin/qqwife/command.go b/plugin/qqwife/command.go index 10ff6e51..fdff59a0 100644 --- a/plugin/qqwife/command.go +++ b/plugin/qqwife/command.go @@ -24,6 +24,9 @@ import ( "github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/img/writer" "github.com/FloatTech/zbputils/img/text" + + // 货币系统 + "github.com/FloatTech/AnimeAPI/wallet" ) // nolint: asciicheck @@ -66,6 +69,7 @@ func init() { "- (娶|嫁)@对方QQ\n自由选择对象,自由恋爱(好感度越高成功率越高,保底30%概率)\n" + "- 当[对方Q号|@对方QQ]的小三\n我和你才是真爱,为了你我愿意付出一切(好感度越高成功率越高,保底10%概率)\n" + "- 闹离婚\n你谁啊,给我滚(好感度越高成功率越低)\n" + + "- 买礼物给[对方Q号|@对方QQ]\n使用小熊饼干获取好感度\n" + "- 做媒 @攻方QQ @受方QQ\n身为管理,群友的xing福是要搭把手的(攻受双方好感度越高成功率越高,保底30%概率)\n" + "--------------------------------\n好感度规则\n--------------------------------\n" + "‘娶群友’指令好感度随机增加1~5。\n‘A牛B的C’会导致C恨A,好感度-5;\nB为了报复A,好感度+5(什么柜子play)\nA为BC做媒,成功B、C对A好感度+1反之-1\n做媒成功BC好感度+1", @@ -458,6 +462,74 @@ func init() { ), ) }) + // 礼物系统 + engine.OnRegex(`^买礼物给\s?(\[CQ:at,qq=(\d+)\]|(\d+))`, getdb).SetBlock(true).Limit(ctxext.LimitByUser). + Handle(func(ctx *zero.Ctx) { + gid := ctx.Event.GroupID + uid := ctx.Event.UserID + fiancee := ctx.State["regex_matched"].([]string) + gay, _ := strconv.ParseInt(fiancee[2]+fiancee[3], 10, 64) + // 获取CD + cdTime, err := 民政局.getCDtime(gid) + if err != nil { + ctx.SendChain(message.Text("[qqwife]获取该群技能CD错误(将以CD12H计算)\n", err)) + } + ok, err := 民政局.compareCDtime(gid, uid, 5, cdTime) + if err != nil { + ctx.SendChain(message.Text("[qqwife]查询用户CD状态失败,请重试\n", err)) + return + } + if !ok { + ctx.SendChain(message.Text("舔狗,今天你已经送过礼物了。")) + return + } + // 写入CD + err = 民政局.writeCDtime(gid, uid, 5) + if err != nil { + ctx.SendChain(message.At(uid), message.Text("[qqwife]你的技能CD记录失败\n", err)) + } + // 获取好感度 + favor, err := 民政局.getFavorability(uid, gay) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + return + } + // 对接小熊饼干 + walletinfo := wallet.GetWalletOf(uid) + if walletinfo < 1 { + ctx.SendChain(message.Text("你钱包没钱啦!")) + return + } + moneyToFavor := rand.Intn(math.Min(walletinfo, 100)) + 1 + // 计算钱对应的好感值 + newFavor := 1 + if favor > 50 { + newFavor += moneyToFavor % 10 // 礼物厌倦 + } else { + newFavor += rand.Intn(moneyToFavor) + } + // 随机对方心情 + mood := rand.Intn(5) + if mood == 0 { + newFavor = -newFavor + } + // 记录结果 + err = wallet.InsertWalletOf(uid, -moneyToFavor) + if err != nil { + ctx.SendChain(message.Text("[qqwife]钱包坏掉力:\n", err)) + return + } + lastfavor, err := 民政局.setFavorability(uid, gay, newFavor) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度数据库发生问题力\n", err)) + return + } + if mood == 0 { + ctx.SendChain(message.Text("你花了", moneyToFavor, "ATRI币买了一件女装送给了ta,ta很不喜欢,你们的好感度降低至", lastfavor)) + } else { + ctx.SendChain(message.Text("你花了", moneyToFavor, "ATRI币买了一件女装送给了ta,ta很喜欢,你们的好感度升至", lastfavor)) + } + }) engine.OnFullMatchGroup([]string{"闹离婚", "办离婚"}, zero.OnlyGroup, getdb, checkdivorce).Limit(ctxext.LimitByUser).SetBlock(true). Handle(func(ctx *zero.Ctx) { gid := ctx.Event.GroupID diff --git a/plugin/qqwife/function.go b/plugin/qqwife/function.go index 6f540588..1adce885 100644 --- a/plugin/qqwife/function.go +++ b/plugin/qqwife/function.go @@ -17,8 +17,8 @@ import ( // nolint: asciicheck // nolint: asciicheck type 婚姻登记 struct { - db *sql.Sqlite - dbmu sync.RWMutex + db *sql.Sqlite + sync.RWMutex } // 结婚证信息 @@ -55,8 +55,8 @@ type cdsheet struct { } func (sql *婚姻登记) 开门时间(gid int64) (ok bool, err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() ok = false err = sql.db.Create("updateinfo", &updateinfo{}) if err != nil { @@ -99,8 +99,8 @@ func (sql *婚姻登记) 开门时间(gid int64) (ok bool, err error) { } func (sql *婚姻登记) 营业模式(gid int64) (canMatch, canNtr int, err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() err = sql.db.Create("updateinfo", &updateinfo{}) if err != nil { if err = sql.db.Drop("updateinfo"); err == nil { @@ -130,8 +130,8 @@ func (sql *婚姻登记) 营业模式(gid int64) (canMatch, canNtr int, err erro } func (sql *婚姻登记) 修改模式(gid int64, mode string, stauts int) (err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() err = sql.db.Create("updateinfo", &updateinfo{}) if err != nil { if err = sql.db.Drop("updateinfo"); err == nil { @@ -169,8 +169,8 @@ func (sql *婚姻登记) 修改模式(gid int64, mode string, stauts int) (err e } func (sql *婚姻登记) 清理花名册(gid string) error { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() grouplist, err := sql.db.ListTables() if err != nil { return err @@ -209,8 +209,8 @@ func (sql *婚姻登记) 清理花名册(gid string) error { } func (sql *婚姻登记) 查户口(gid, uid int64) (info userinfo, status string, err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() gidstr := "group" + strconv.FormatInt(gid, 10) uidstr := strconv.FormatInt(uid, 10) status = "单" @@ -232,8 +232,8 @@ func (sql *婚姻登记) 查户口(gid, uid int64) (info userinfo, status string } func (sql *婚姻登记) 登记(gid, uid, target int64, username, targetname string) error { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() gidstr := "group" + strconv.FormatInt(gid, 10) err := sql.db.Create(gidstr, &userinfo{}) if err != nil { @@ -254,24 +254,24 @@ func (sql *婚姻登记) 登记(gid, uid, target int64, username, targetname str } func (sql *婚姻登记) 离婚休妻(gid, wife int64) error { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() gidstr := "group" + strconv.FormatInt(gid, 10) wifestr := strconv.FormatInt(wife, 10) return sql.db.Del(gidstr, "where target = "+wifestr) } func (sql *婚姻登记) 离婚休夫(gid, husband int64) error { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() gidstr := "group" + strconv.FormatInt(gid, 10) husbandstr := strconv.FormatInt(husband, 10) return sql.db.Del(gidstr, "where user = "+husbandstr) } func (sql *婚姻登记) 花名册(gid int64) (list [][4]string, number int, err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() gidstr := "group" + strconv.FormatInt(gid, 10) err = sql.db.Create(gidstr, &userinfo{}) if err != nil { @@ -322,8 +322,8 @@ func slicename(name string, canvas *gg.Context) (resultname string) { // 获取好感度 func (sql *婚姻登记) getFavorability(uid, target int64) (favor int, err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() err = sql.db.Create("favorability", &favorability{}) if err != nil { return @@ -345,8 +345,8 @@ func (sql *婚姻登记) getFavorability(uid, target int64) (favor int, err erro // 设置好感度 正增负减 func (sql *婚姻登记) setFavorability(uid, target int64, score int) (favor int, err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() err = sql.db.Create("favorability", &favorability{}) if err != nil { return @@ -360,7 +360,10 @@ func (sql *婚姻登记) setFavorability(uid, target int64, score int) (favor in Userinfo: uidstr + "+" + targstr + "+" + uidstr, Favor: score, }) - return score, err + if err == nil { + err = sql.db.Find("favorability", &info, "where Userinfo glob '*"+uidstr+"+"+targstr+"*'") + } + return info.Favor, err } info.Favor += score if info.Favor > 100 { @@ -374,8 +377,8 @@ func (sql *婚姻登记) setFavorability(uid, target int64, score int) (favor in // 获取技能时长 func (sql *婚姻登记) getCDtime(gid int64) (skillCD float64, err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() skillCD = 12 err = sql.db.Create("updateinfo", &updateinfo{}) if err != nil { @@ -404,8 +407,8 @@ func (sql *婚姻登记) getCDtime(gid int64) (skillCD float64, err error) { // 设置技能时长 func (sql *婚姻登记) setCDtime(gid int64, cdTime float64) (err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() err = sql.db.Create("updateinfo", &updateinfo{}) if err != nil { if err = sql.db.Drop("updateinfo"); err == nil { @@ -435,8 +438,8 @@ func (sql *婚姻登记) setCDtime(gid int64, cdTime float64) (err error) { // 记录CD func (sql *婚姻登记) writeCDtime(gid, uid, mun int64) error { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() err := sql.db.Create("cdsheet", &cdsheet{}) if err != nil { if err = sql.db.Drop("cdsheet"); err == nil { @@ -457,8 +460,8 @@ func (sql *婚姻登记) writeCDtime(gid, uid, mun int64) error { // 判断CD是否过时 func (sql *婚姻登记) compareCDtime(gid, uid, mun int64, cdtime float64) (ok bool, err error) { - sql.dbmu.Lock() - defer sql.dbmu.Unlock() + sql.Lock() + defer sql.Unlock() ok = false err = sql.db.Create("cdsheet", &cdsheet{}) if err != nil { diff --git a/plugin/score/model.go b/plugin/score/model.go index 90280907..fab21fe2 100644 --- a/plugin/score/model.go +++ b/plugin/score/model.go @@ -107,7 +107,7 @@ func (sdb *scoredb) InsertOrUpdateSignInCountByUID(uid int64, count int) (err er if err = db.Model(&signintable{}).First(&si, "uid = ? ", uid).Error; err != nil { // error handling... if gorm.IsRecordNotFoundError(err) { - db.Model(&signintable{}).Create(&si) // newUser not user + err = db.Model(&signintable{}).Create(&si).Error // newUser not user } } else { err = db.Model(&signintable{}).Where("uid = ? ", uid).Update( diff --git a/plugin/score/sign_in.go b/plugin/score/sign_in.go index 27598a41..412782ad 100644 --- a/plugin/score/sign_in.go +++ b/plugin/score/sign_in.go @@ -3,17 +3,13 @@ package score import ( "fmt" + "math" + "math/rand" "os" "strconv" "time" "github.com/Coloured-glaze/gg" - "github.com/golang/freetype" - log "github.com/sirupsen/logrus" - "github.com/wcharczuk/go-chart/v2" - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/message" - "github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/img/writer" ctrl "github.com/FloatTech/zbpctrl" @@ -21,20 +17,28 @@ import ( "github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/zbputils/img" "github.com/FloatTech/zbputils/img/text" + "github.com/golang/freetype" + log "github.com/sirupsen/logrus" + "github.com/wcharczuk/go-chart/v2" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" + + // 货币系统 + "github.com/FloatTech/AnimeAPI/wallet" ) const ( backgroundURL = "https://img.moehu.org/pic.php?id=pc" signinMax = 1 - // SCOREMAX 分数上限定为120 - SCOREMAX = 120 + // SCOREMAX 分数上限定为1200 + SCOREMAX = 1200 ) var ( - levelArray = [...]int{0, 1, 2, 5, 10, 20, 35, 55, 75, 100, 120} - engine = control.Register("score", &ctrl.Options[*zero.Ctx]{ + rankArray = [...]int{0, 10, 20, 50, 100, 200, 350, 550, 750, 1000, 1200} + engine = control.Register("score", &ctrl.Options[*zero.Ctx]{ DisableOnDefault: false, - Help: "签到得分\n- 签到\n- 获得签到背景[@xxx] | 获得签到背景\n- 查看分数排名", + Help: "签到得分\n- 签到\n- 获得签到背景[@xxx] | 获得签到背景\n- 查看等级排名\n注:为跨群排名\n- 查看我的钱包\n- 查看钱包排名\n注:为本群排行,若群人数太多不建议使用该功能!!!", PrivateDataFolder: "score", }) ) @@ -49,25 +53,66 @@ func init() { } sdb = initialize(engine.DataFolder() + "score.db") }() - engine.OnFullMatch("签到").Limit(ctxext.LimitByUser).SetBlock(true). + zero.OnFullMatch("查看我的钱包").SetBlock(true).Handle(func(ctx *zero.Ctx) { + uid := ctx.Event.UserID + money := wallet.GetWalletOf(uid) + ctx.SendChain(message.At(uid), message.Text("你的钱包当前有", money, "ATRI币")) + }) + engine.OnFullMatch("2签到").Limit(ctxext.LimitByUser).SetBlock(true). Handle(func(ctx *zero.Ctx) { uid := ctx.Event.UserID now := time.Now() today := now.Format("20060102") + // 签到图片 + drawedFile := cachePath + strconv.FormatInt(uid, 10) + today + "signin.png" + picFile := cachePath + strconv.FormatInt(uid, 10) + today + ".png" + // 获取签到时间 si := sdb.GetSignInByUID(uid) siUpdateTimeStr := si.UpdatedAt.Format("20060102") - drawedFile := cachePath + strconv.FormatInt(uid, 10) + today + "signin.png" - - picFile := cachePath + strconv.FormatInt(uid, 10) + today + ".png" - - if si.Count >= signinMax && siUpdateTimeStr == today { + switch { + case si.Count >= signinMax && siUpdateTimeStr == today: + // 如果签到时间是今天 ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("今天你已经签到过了!")) if file.IsExist(drawedFile) { ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile)) } return + case siUpdateTimeStr != today: + // 如果是夸天签到就请数据 + err := sdb.InsertOrUpdateSignInCountByUID(uid, 0) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } } - err := initPic(picFile) + // 更新签到次数 + err := sdb.InsertOrUpdateSignInCountByUID(uid, si.Count+1) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + // 更新经验 + level := sdb.GetScoreByUID(uid).Score + 1 + if level > SCOREMAX { + level = SCOREMAX + ctx.SendChain(message.At(uid), message.Text("你的登记已经达到上限")) + } + err = sdb.InsertOrUpdateScoreByUID(uid, level) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + // 更新钱包 + rank := getrank(level) + add := 1 + rand.Intn(10) + rank*5 // 等级越高获得的钱越高 + err = wallet.InsertWalletOf(uid, add) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + score := wallet.GetWalletOf(uid) + // 绘图 + err = initPic(picFile) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return @@ -77,20 +122,12 @@ func init() { ctx.SendChain(message.Text("ERROR: ", err)) return } - if siUpdateTimeStr != today { - _ = sdb.InsertOrUpdateSignInCountByUID(uid, 0) - } - - _ = sdb.InsertOrUpdateSignInCountByUID(uid, si.Count+1) - // 避免图片过大,最大 1280*720 back = img.Limit(back, 1280, 720) - canvas := gg.NewContext(back.Bounds().Size().X, int(float64(back.Bounds().Size().Y)*1.7)) canvas.SetRGB(1, 1, 1) canvas.Clear() canvas.DrawImage(back, 0, 0) - monthWord := now.Format("01/02") hourWord := getHourWord(now) _, err = file.GetLazyData(text.BoldFontFile, true) @@ -115,32 +152,23 @@ func init() { ctx.SendChain(message.Text("ERROR: ", err)) return } - add := 1 - canvas.DrawString(nickName+fmt.Sprintf(" 小熊饼干+%d", add), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.3) - score := sdb.GetScoreByUID(uid).Score - score += add - if score > SCOREMAX { - score = SCOREMAX - ctx.SendChain(message.At(uid), message.Text("你获得的小熊饼干已经达到上限")) - } - _ = sdb.InsertOrUpdateScoreByUID(uid, score) - level := getLevel(score) - canvas.DrawString("当前小熊饼干:"+strconv.FormatInt(int64(score), 10), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.4) - canvas.DrawString("LEVEL:"+strconv.FormatInt(int64(level), 10), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.5) + canvas.DrawString(nickName+fmt.Sprintf(" ATRI币+%d", add), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.3) + canvas.DrawString("当前ATRI币:"+strconv.FormatInt(int64(score), 10), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.4) + canvas.DrawString("LEVEL:"+strconv.FormatInt(int64(rank), 10), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.5) canvas.DrawRectangle(float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.55, float64(back.Bounds().Size().X)*0.6, float64(back.Bounds().Size().Y)*0.1) canvas.SetRGB255(150, 150, 150) canvas.Fill() - var nextLevelScore int - if level < 10 { - nextLevelScore = levelArray[level+1] + var nextrankScore int + if rank < 10 { + nextrankScore = rankArray[rank+1] } else { - nextLevelScore = SCOREMAX + nextrankScore = SCOREMAX } canvas.SetRGB255(0, 0, 0) - canvas.DrawRectangle(float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.55, float64(back.Bounds().Size().X)*0.6*float64(score)/float64(nextLevelScore), float64(back.Bounds().Size().Y)*0.1) + canvas.DrawRectangle(float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.55, float64(back.Bounds().Size().X)*0.6*float64(level)/float64(nextrankScore), float64(back.Bounds().Size().Y)*0.1) canvas.SetRGB255(102, 102, 102) canvas.Fill() - canvas.DrawString(fmt.Sprintf("%d/%d", score, nextLevelScore), float64(back.Bounds().Size().X)*0.75, float64(back.Bounds().Size().Y)*1.62) + canvas.DrawString(fmt.Sprintf("%d/%d", level, nextrankScore), float64(back.Bounds().Size().X)*0.75, float64(back.Bounds().Size().Y)*1.62) f, err := os.Create(drawedFile) if err != nil { @@ -174,7 +202,7 @@ func init() { } ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + picFile)) }) - engine.OnFullMatch("查看分数排名", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true). + engine.OnFullMatch("查看等级排名", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true). Handle(func(ctx *zero.Ctx) { today := time.Now().Format("20060102") drawedFile := cachePath + today + "scoreRank.png" @@ -211,19 +239,111 @@ func init() { ctx.SendChain(message.Text("ERROR: ", err)) return } - bars := make([]chart.Value, len(st)) - for i, v := range st { - bars[i].Value = float64(v.Score) - bars[i].Label = ctx.CardOrNickName(v.UID) + var bars []chart.Value + for _, v := range st { + if v.Score != 0 { + bars = append(bars, chart.Value{ + Label: ctx.CardOrNickName(v.UID), + Value: float64(v.Score), + }) + } } err = chart.BarChart{ Font: font, - Title: "饼干排名", + Title: "等级排名(1天只刷新1次)", Background: chart.Style{ Padding: chart.Box{ Top: 40, }, }, + YAxis: chart.YAxis{ + Range: &chart.ContinuousRange{ + Min: 0, + Max: math.Ceil(bars[0].Value/10) * 10, + }, + }, + Height: 500, + BarWidth: 50, + Bars: bars, + }.Render(chart.PNG, f) + _ = f.Close() + if err != nil { + _ = os.Remove(drawedFile) + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile)) + }) + engine.OnFullMatch("查看钱包排名", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + gid := strconv.FormatInt(ctx.Event.GroupID, 10) + today := time.Now().Format("20060102") + drawedFile := cachePath + gid + today + "walletRank.png" + if file.IsExist(drawedFile) { + ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile)) + return + } + // 无缓存获取群员列表 + temp := ctx.GetThisGroupMemberListNoCache().Array() + var usergroup []int64 + for _, info := range temp { + usergroup = append(usergroup, info.Get("user_id").Int()) + } + // 获取钱包信息 + st, err := wallet.GetGroupWalletOf(usergroup, true) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + if len(st) == 0 { + ctx.SendChain(message.Text("ERROR: 当前没人获取过ATRI币")) + return + } else if len(st) > 10 { + st = st[:10] + } + _, err = file.GetLazyData(text.FontFile, true) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + b, err := os.ReadFile(text.FontFile) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + font, err := freetype.ParseFont(b) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + f, err := os.Create(drawedFile) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + var bars []chart.Value + for _, v := range st { + if v.Money != 0 { + bars = append(bars, chart.Value{ + Label: ctx.CardOrNickName(v.UID), + Value: float64(v.Money), + }) + } + } + err = chart.BarChart{ + Font: font, + Title: "ATRI币排名(1天只刷新1次)", + Background: chart.Style{ + Padding: chart.Box{ + Top: 40, + }, + }, + YAxis: chart.YAxis{ + Range: &chart.ContinuousRange{ + Min: 0, + Max: math.Ceil(bars[0].Value/10) * 10, + }, + }, Height: 500, BarWidth: 50, Bars: bars, @@ -256,8 +376,8 @@ func getHourWord(t time.Time) string { } } -func getLevel(count int) int { - for k, v := range levelArray { +func getrank(count int) int { + for k, v := range rankArray { if count == v { return k } else if count < v {