From 3ef0e76ed5268d59840f8be7de1c48f2609a542d Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Wed, 1 Feb 2023 17:10:50 +0000 Subject: [PATCH 1/8] =?UTF-8?q?=E5=8A=A0=E4=B8=80=E7=82=B9=E7=BB=86?= =?UTF-8?q?=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 10 +- go.sum | 7 +- plugin/ai_false/ai_false.go | 479 ++++++++++++++++++++++++++++++++++-- 3 files changed, 461 insertions(+), 35 deletions(-) diff --git a/go.mod b/go.mod index 42d9b4cd56..5c894ca2d3 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/Coloured-glaze/gg v1.3.4 github.com/FloatTech/AnimeAPI v1.6.1-0.20230130095520-be357484e5a7 github.com/FloatTech/floatbox v0.0.0-20230130095057-3d1da721425e + github.com/FloatTech/rendercard v0.0.8 github.com/FloatTech/sqlite v1.5.7 github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b github.com/FloatTech/zbpctrl v1.5.3-0.20230130095145-714ad318cd52 @@ -16,6 +17,7 @@ require ( github.com/antchfx/htmlquery v1.2.5 github.com/corona10/goimagehash v1.1.0 github.com/davidscholberg/go-durationfmt v0.0.0-20170122144659-64843a2083d3 + github.com/disintegration/imaging v1.6.2 github.com/fumiama/ahsai v0.1.0 github.com/fumiama/cron v1.3.0 github.com/fumiama/go-base16384 v1.6.4 @@ -30,20 +32,19 @@ require ( github.com/lucas-clemente/quic-go v0.31.1 github.com/mroth/weightedrand v1.0.0 github.com/pkg/errors v0.9.1 - github.com/shirou/gopsutil/v3 v3.22.11 + github.com/shirou/gopsutil/v3 v3.23.1 github.com/sirupsen/logrus v1.9.0 github.com/tidwall/gjson v1.14.4 github.com/wcharczuk/go-chart/v2 v2.1.0 github.com/wdvxdr1123/ZeroBot v1.6.8 gitlab.com/gomidi/midi/v2 v2.0.25 golang.org/x/image v0.3.0 + golang.org/x/text v0.6.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/FloatTech/rendercard v0.0.8 // indirect github.com/antchfx/xpath v1.2.1 // indirect - github.com/disintegration/imaging v1.6.2 // indirect github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 // indirect github.com/faiface/beep v1.1.0 // indirect github.com/fumiama/go-simple-protobuf v0.1.0 // indirect @@ -81,8 +82,7 @@ require ( golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect - golang.org/x/sys v0.2.0 // indirect - golang.org/x/text v0.6.0 // indirect + golang.org/x/sys v0.4.0 // indirect golang.org/x/tools v0.1.12 // indirect modernc.org/libc v1.21.5 // indirect modernc.org/mathutil v1.5.0 // indirect diff --git a/go.sum b/go.sum index baf20eef3b..57475c142a 100644 --- a/go.sum +++ b/go.sum @@ -167,8 +167,8 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/shirou/gopsutil/v3 v3.22.11 h1:kxsPKS+Eeo+VnEQ2XCaGJepeP6KY53QoRTETx3+1ndM= -github.com/shirou/gopsutil/v3 v3.22.11/go.mod h1:xl0EeL4vXJ+hQMAGN8B9VFpxukEMA0XdevQOe5MZ1oY= +github.com/shirou/gopsutil/v3 v3.23.1 h1:a9KKO+kGLKEvcPIs4W62v0nu3sciVDOOOPUD0Hz7z/4= +github.com/shirou/gopsutil/v3 v3.23.1/go.mod h1:NN6mnm5/0k8jw4cBfCnJtr5L7ErOTg18tMNpgFkn0hA= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -263,8 +263,9 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/plugin/ai_false/ai_false.go b/plugin/ai_false/ai_false.go index e301380bd9..abce6f3554 100644 --- a/plugin/ai_false/ai_false.go +++ b/plugin/ai_false/ai_false.go @@ -2,24 +2,47 @@ package aifalse import ( - "fmt" + "bytes" + "image" "math" + "runtime" "strconv" + "strings" + "sync" "time" + "github.com/Coloured-glaze/gg" + "github.com/FloatTech/AnimeAPI/bilibili" + "github.com/FloatTech/floatbox/img/writer" + "github.com/FloatTech/floatbox/web" + "github.com/FloatTech/rendercard" ctrl "github.com/FloatTech/zbpctrl" "github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/ctxext" + "github.com/FloatTech/zbputils/img" + "github.com/FloatTech/zbputils/img/text" + "github.com/disintegration/imaging" "github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/disk" + "github.com/shirou/gopsutil/v3/host" "github.com/shirou/gopsutil/v3/mem" "github.com/sirupsen/logrus" + "golang.org/x/text/cases" + "golang.org/x/text/language" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" ) +const ( + backgroundURL = "https://iw233.cn/api.php?sort=mp" + referer = "https://weibo.com/" +) + +var boottime time.Time + func init() { // 插件主体 + boottime = time.Now() engine := control.Register("aifalse", &ctrl.Options[*zero.Ctx]{ DisableOnDefault: false, Brief: "自检, 全局限速", @@ -39,12 +62,14 @@ func init() { // 插件主体 } engine.OnFullMatchGroup([]string{"检查身体", "自检", "启动自检", "系统状态"}, zero.AdminPermission).SetBlock(true). Handle(func(ctx *zero.Ctx) { - ctx.SendChain(message.Text( - "* CPU占用: ", cpuPercent(), "%\n", - "* RAM占用: ", memPercent(), "%\n", - "* 硬盘使用: ", diskPercent(), - ), - ) + img, err := drawstatus(ctx.Event.SelfID, zero.BotConfig.NickName[0]) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return + } + if id := ctx.SendChain(message.ImageBytes(img)); id.ID() == 0 { + ctx.SendChain(message.Text("ERROR:可能被风控了")) + } }) engine.OnRegex(`^设置默认限速为每\s*(\d+)\s*(分钟|秒)\s*(\d+)\s*次触发$`, zero.SuperUserPermission).SetBlock(true). Handle(func(ctx *zero.Ctx) { @@ -84,38 +109,438 @@ func init() { // 插件主体 }) } -func cpuPercent() float64 { - percent, err := cpu.Percent(time.Second, false) +func drawstatus(uid int64, botname string) (sendimg []byte, err error) { + diskstate, err := diskstate() + if err != nil { + return + } + diskcardh := 40 + (20+50)*len(diskstate) + 40 - 20 + + moreinfo, err := moreinfo() + if err != nil { + return + } + moreinfocardh := 30 + (20+32*72/96)*len(moreinfo) + 30 - 20 + + url, err := bilibili.GetRealURL(backgroundURL) + if err != nil { + return + } + data, err := web.RequestDataWith(web.NewDefaultClient(), url, "", referer, "", nil) + if err != nil { + return + } + back, _, err := image.Decode(bytes.NewReader(data)) + if err != nil { + return + } + data, err = web.GetData("http://q4.qlogo.cn/g?b=qq&nk=" + strconv.FormatInt(uid, 10) + "&s=640") + if err != nil { + return + } + + avatar, _, err := image.Decode(bytes.NewReader(data)) + if err != nil { + return + } + avatarf := img.Size(avatar, 200, 200) + + canvas := gg.NewContext(1280, 70+250+40+380+diskcardh+40+moreinfocardh+40+70) + + bh, bw, ch, cw := float64(back.Bounds().Dy()), float64(back.Bounds().Dx()), float64(canvas.H()), float64(canvas.W()) + + if bh/bw < ch/cw { + back = img.Size(back, int(bw*ch/bh), int(bh*ch/bh)).Im + canvas.DrawImageAnchored(back, canvas.W()/2, canvas.H()/2, 0.5, 0.5) + } else { + back = img.Size(back, int(bw*cw/bw), int(bh*cw/bw)).Im + canvas.DrawImage(back, 0, 0) + } + + wg := &sync.WaitGroup{} + wg.Add(5) + + titlecard := gg.NewContext(canvas.W()-70-70, 250) + basiccard := gg.NewContext(canvas.W()-70-70, 380) + diskcard := gg.NewContext(canvas.W()-70-70, diskcardh) + moreinfocard := gg.NewContext(canvas.W()-70-70, moreinfocardh) + shadow := gg.NewContext(canvas.W(), canvas.H()) + + var titleimg, basicimg, diskimg, moreinfoimg, shadowimg image.Image + go func() { + defer wg.Done() + + titlecard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70) + + titlecard.DrawRoundedRectangle(1, 1, float64(titlecard.W()-1*2), float64(titlecard.H()-1*2), 16) + titlecard.SetLineWidth(3) + titlecard.SetRGBA255(255, 255, 255, 100) + titlecard.StrokePreserve() + titlecard.SetRGBA255(255, 255, 255, 100) + titlecard.Fill() + + titlecard.DrawImage(avatarf.Circle(0).Im, (titlecard.H()-avatarf.H)/2, (titlecard.H()-avatarf.H)/2) + + err = titlecard.LoadFontFace(text.GlowSansFontFile, 72) + if err != nil { + return + } + titlecard.SetRGBA255(30, 30, 30, 255) + fw, _ := titlecard.MeasureString(botname) + + titlecard.DrawStringAnchored(botname, float64(titlecard.H())+fw/2, float64(titlecard.H())*0.5/2, 0.5, 0.5) + + err = titlecard.LoadFontFace(text.GlowSansFontFile, 24) + if err != nil { + return + } + titlecard.SetRGBA255(30, 30, 30, 180) + + titlecard.NewSubPath() + titlecard.MoveTo(float64(titlecard.H()), float64(titlecard.H())/2) + titlecard.LineTo(float64(titlecard.W()-titlecard.H()), float64(titlecard.H())/2) + titlecard.Stroke() + + brt, err := botruntime() + if err != nil { + return + } + + fw, _ = titlecard.MeasureString(brt) + + titlecard.DrawStringAnchored(brt, float64(titlecard.H())+fw/2, float64(titlecard.H())*(0.5+0.25/2), 0.5, 0.5) + + bs, err := botstatus() + if err != nil { + return + } + fw, _ = titlecard.MeasureString(bs) + + titlecard.DrawStringAnchored(bs, float64(titlecard.H())+fw/2, float64(titlecard.H())*(0.5+0.5/2), 0.5, 0.5) + titleimg = rendercard.Fillet(titlecard.Image(), 16) + }() + go func() { + defer wg.Done() + + basiccard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecard.H()-40) + + basiccard.DrawRoundedRectangle(1, 1, float64(basiccard.W()-1*2), float64(basiccard.H()-1*2), 16) + basiccard.SetLineWidth(3) + basiccard.SetRGBA255(255, 255, 255, 100) + basiccard.StrokePreserve() + basiccard.SetRGBA255(255, 255, 255, 140) + basiccard.Fill() + + basicstate, err := basicstate() + if err != nil { + return + } + bslen := len(basicstate) + for i, v := range basicstate { + offset := float64(i) * ((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1) + 200) + + basiccard.SetRGBA255(235, 235, 235, 255) + basiccard.DrawCircle((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2, 100) + basiccard.Fill() + + switch { + case v.precent > 90: + basiccard.SetRGBA255(255, 70, 0, 255) + case v.precent > 70: + basiccard.SetRGBA255(255, 165, 0, 255) + default: + basiccard.SetRGBA255(145, 240, 145, 255) + } + + basiccard.NewSubPath() + basiccard.MoveTo((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2) + basiccard.DrawEllipticalArc((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2, 100, 100, -0.5*math.Pi, -0.5*math.Pi+2*v.precent*0.01*math.Pi) + basiccard.Fill() + + basiccard.SetRGBA255(255, 255, 255, 255) + basiccard.DrawCircle((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2, 80) + basiccard.Fill() + + err = basiccard.LoadFontFace(text.GlowSansFontFile, 42) + if err != nil { + return + } + + basiccard.SetRGBA255(213, 213, 213, 255) + basiccard.DrawStringAnchored(strconv.FormatFloat(v.precent, 'f', 0, 64)+"%", (float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2, 0.5, 0.5) + + basiccard.SetRGBA255(30, 30, 30, 255) + _, fw := basiccard.MeasureString(v.name) + basiccard.DrawStringAnchored(v.name, (float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200+15+basiccard.FontHeight()/2, 0.5, 0.5) + + err = basiccard.LoadFontFace(text.GlowSansFontFile, 20) + if err != nil { + return + } + basiccard.SetRGBA255(30, 30, 30, 180) + + textoffsety := basiccard.FontHeight() + 10 + for k, s := range v.text { + basiccard.DrawStringAnchored(s, (float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200+15+fw+15+basiccard.FontHeight()/2+float64(k)*textoffsety, 0.5, 0.5) + } + } + basicimg = rendercard.Fillet(basiccard.Image(), 16) + }() + + go func() { + defer wg.Done() + + diskcard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecard.H()-40-basiccard.H()-40) + + diskcard.DrawRoundedRectangle(1, 1, float64(diskcard.W()-1*2), float64(diskcard.H()-1*2), 16) + diskcard.SetLineWidth(3) + diskcard.SetRGBA255(255, 255, 255, 100) + diskcard.StrokePreserve() + diskcard.SetRGBA255(255, 255, 255, 140) + diskcard.Fill() + + dslen := len(diskstate) + for i, v := range diskstate { + offset := float64(i)*(50+20) - 20 + + diskcard.SetRGBA255(192, 192, 192, 255) + diskcard.DrawRoundedRectangle(60, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, float64(diskcard.W())-60-100, 50, 12) + diskcard.Fill() + + switch { + case v.precent > 90: + diskcard.SetRGBA255(255, 70, 0, 255) + case v.precent > 70: + diskcard.SetRGBA255(255, 165, 0, 255) + default: + diskcard.SetRGBA255(145, 240, 145, 255) + } + + diskcard.DrawRoundedRectangle(60, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, (float64(diskcard.W())-60-100)*v.precent*0.01, 50, 12) + diskcard.Fill() + + err = diskcard.LoadFontFace(text.GlowSansFontFile, 32) + if err != nil { + return + } + diskcard.SetRGBA255(30, 30, 30, 255) + diskcard.DrawStringAnchored(v.name, 60/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) + diskcard.DrawStringAnchored(v.text[0], (float64(diskcard.W())-60)/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) + diskcard.DrawStringAnchored(strconv.FormatFloat(v.precent, 'f', 0, 64)+"%", float64(diskcard.W())-100/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) + } + diskimg = rendercard.Fillet(diskcard.Image(), 16) + }() + + go func() { + defer wg.Done() + + moreinfocard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecard.H()-40-basiccard.H()-40-diskcard.H()-40) + + moreinfocard.DrawRoundedRectangle(1, 1, float64(moreinfocard.W()-1*2), float64(moreinfocard.H()-1*2), 16) + moreinfocard.SetLineWidth(3) + moreinfocard.SetRGBA255(255, 255, 255, 120) + moreinfocard.StrokePreserve() + moreinfocard.SetRGBA255(255, 255, 255, 160) + moreinfocard.Fill() + + milen := len(moreinfo) + for i, v := range moreinfo { + + err = moreinfocard.LoadFontFace(text.GlowSansFontFile, 32) + if err != nil { + return + } + offset := float64(i)*(20+moreinfocard.FontHeight()) - 20 + + moreinfocard.SetRGBA255(30, 30, 30, 255) + + fw, _ := moreinfocard.MeasureString(v.name) + fw1, _ := moreinfocard.MeasureString(v.text[0]) + + moreinfocard.DrawStringAnchored(v.name, 20+fw/2, 30+(float64(moreinfocardh-30*2)-moreinfocard.FontHeight()*float64(milen))/float64(milen-1)+moreinfocard.FontHeight()/2+offset, 0.5, 0.5) + moreinfocard.DrawStringAnchored(v.text[0], float64(moreinfocard.W())-20-fw1/2, 30+(float64(moreinfocardh-30*2)-moreinfocard.FontHeight()*float64(milen))/float64(milen-1)+moreinfocard.FontHeight()/2+offset, 0.5, 0.5) + } + moreinfoimg = rendercard.Fillet(moreinfocard.Image(), 16) + }() + + go func() { + defer wg.Done() + shadow.SetRGBA255(0, 0, 0, 100) + shadow.SetLineWidth(12) + shadow.DrawRoundedRectangle(70, 70, float64(titlecard.W()), float64(titlecard.H()), 16) + shadow.Stroke() + shadow.DrawRoundedRectangle(70, float64(70+titlecard.H()+40), float64(basiccard.W()), float64(basiccard.H()), 16) + shadow.Stroke() + shadow.DrawRoundedRectangle(70, float64(70+titlecard.H()+40+basiccard.H()+40), float64(diskcard.W()), float64(diskcard.H()), 16) + shadow.Stroke() + shadow.DrawRoundedRectangle(70, float64(70+titlecard.H()+40+basiccard.H()+40+diskcard.H()+40), float64(moreinfocard.W()), float64(moreinfocard.H()), 16) + shadow.Stroke() + shadowimg = imaging.Blur(shadow.Image(), 24) + }() + + wg.Wait() + canvas.DrawImage(shadowimg, 0, 0) + canvas.DrawImage(titleimg, 70, 70) + canvas.DrawImage(basicimg, 70, 70+titlecard.H()+40) + canvas.DrawImage(diskimg, 70, 70+titlecard.H()+40+basiccard.H()+40) + canvas.DrawImage(moreinfoimg, 70, 70+titlecard.H()+40+basiccard.H()+40+diskcard.H()+40) + + sendimg, cl := writer.ToBytes(canvas.Image()) + defer cl() + return sendimg, nil +} + +func botruntime() (string, error) { + hostinfo, err := host.Info() if err != nil { - return -1 + return "", err } - return math.Round(percent[0]) + t := &strings.Builder{} + t.WriteString("ZeroBot-Plugin 已运行 ") + t.WriteString(strconv.FormatInt((time.Now().Unix()-boottime.Unix())/86400, 10)) + t.WriteString(" 天 ") + t.WriteString(time.Unix(time.Now().Unix()-boottime.Unix(), 0).UTC().Format("15:04:05")) + t.WriteString(" | 系统运行 ") + t.WriteString(strconv.FormatInt(int64(hostinfo.Uptime)/86400, 10)) + t.WriteString(" 天 ") + t.WriteString(time.Unix(int64(hostinfo.Uptime), 0).UTC().Format("15:04:05")) + return t.String(), nil } -func memPercent() float64 { - memInfo, err := mem.VirtualMemory() +func botstatus() (string, error) { + hostinfo, err := host.Info() if err != nil { - return -1 + return "", err } - return math.Round(memInfo.UsedPercent) + t := &strings.Builder{} + t.WriteString(time.Now().Format("2006-01-02 15:04:05")) + t.WriteString(" | ") + t.WriteString(runtime.Version()) + t.WriteString(" | ") + t.WriteString(cases.Title(language.English).String(hostinfo.OS)) + return t.String(), nil +} + +type status struct { + precent float64 + name string + text []string } -func diskPercent() string { - parts, err := disk.Partitions(true) +func basicstate() (stateinfo []*status, err error) { + stateinfo = make([]*status, 3) + percent, err := cpu.Percent(time.Second, false) + if err != nil { + return + } + cpuinfo, err := cpu.Info() + if err != nil { + return + } + cores := strconv.Itoa(int(cpuinfo[0].Cores)) + " Core" + times := "最大 " + strconv.FormatFloat(cpuinfo[0].Mhz/1000, 'f', 1, 64) + "Ghz" + + stateinfo[0] = &status{ + precent: math.Round(percent[0]), + name: "CPU", + text: []string{cores, times}, + } + + raminfo, err := mem.VirtualMemory() + if err != nil { + return + } + total := "总共 " + storagefmt(float64(raminfo.Total)) + used := "已用 " + storagefmt(float64(raminfo.Used)) + free := "剩余 " + storagefmt(float64(raminfo.Free)) + + stateinfo[1] = &status{ + precent: math.Round(raminfo.UsedPercent), + name: "RAM", + text: []string{total, used, free}, + } + + swapinfo, err := mem.SwapMemory() if err != nil { - return err.Error() + return + } + total = "总共 " + storagefmt(float64(swapinfo.Total)) + used = "已用 " + storagefmt(float64(swapinfo.Used)) + free = "剩余 " + storagefmt(float64(swapinfo.Free)) + + stateinfo[2] = &status{ + precent: math.Round(swapinfo.UsedPercent), + name: "SWAP", + text: []string{total, used, free}, + } + return +} + +func storagefmt(num float64) string { + if num /= 1024; num < 1 { + return strconv.FormatFloat(num*1024, 'f', 2, 64) + "B" } - msg := "" - for _, p := range parts { - diskInfo, err := disk.Usage(p.Mountpoint) + if num /= 1024; num < 1 { + return strconv.FormatFloat(num*1024, 'f', 2, 64) + "KB" + } + if num /= 1024; num < 1 { + return strconv.FormatFloat(num*1024, 'f', 2, 64) + "MB" + } + if num /= 1024; num < 1 { + return strconv.FormatFloat(num*1024, 'f', 2, 64) + "GB" + } + return strconv.FormatFloat(num, 'f', 2, 64) + "TB" +} + +func diskstate() (stateinfo []*status, err error) { + parts, err := disk.Partitions(false) + if err != nil { + return + } + stateinfo = make([]*status, len(parts)) + for i, v := range parts { + mp := v.Mountpoint + diskusage, err := disk.Usage(mp) + usage := "" + precent := 0.0 if err != nil { - msg += "\n - " + err.Error() - continue + usage = err.Error() + } else { + usage = storagefmt(float64(diskusage.Used)) + " / " + storagefmt(float64(diskusage.Total)) + precent = math.Round(diskusage.UsedPercent) } - pc := uint(math.Round(diskInfo.UsedPercent)) - if pc > 0 { - msg += fmt.Sprintf("\n - %s(%dM) %d%%", p.Mountpoint, diskInfo.Total/1024/1024, pc) + stateinfo[i] = &status{ + precent: precent, + name: mp, + text: []string{usage}, } } - return msg + + return +} + +func moreinfo() (stateinfo []*status, err error) { + hostinfo, err := host.Info() + if err != nil { + return + } + cpuinfo, err := cpu.Info() + if err != nil { + return + } + count := 0 + m, ok := control.Lookup("aifalse") + if ok { + m.Manager.ForEach(func(key string, manager *ctrl.Control[*zero.Ctx]) bool { + count++ + return true + }) + } + stateinfo = []*status{ + {name: "OS", text: []string{hostinfo.Platform}}, + {name: "CPU", text: []string{cpuinfo[0].ModelName}}, + {name: "Version", text: []string{hostinfo.PlatformVersion}}, + {name: "Plugin", text: []string{"共 " + strconv.Itoa(count) + " 个"}}, + } + return } From 303300de8dece2c93d7b768bd6a23b1993901bc2 Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Thu, 2 Feb 2023 15:39:43 +0000 Subject: [PATCH 2/8] update --- plugin/ai_false/ai_false.go | 126 +++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 58 deletions(-) diff --git a/plugin/ai_false/ai_false.go b/plugin/ai_false/ai_false.go index abce6f3554..0878bb3315 100644 --- a/plugin/ai_false/ai_false.go +++ b/plugin/ai_false/ai_false.go @@ -3,6 +3,7 @@ package aifalse import ( "bytes" + "errors" "image" "math" "runtime" @@ -13,6 +14,7 @@ import ( "github.com/Coloured-glaze/gg" "github.com/FloatTech/AnimeAPI/bilibili" + "github.com/FloatTech/ZeroBot-Plugin/kanban" "github.com/FloatTech/floatbox/img/writer" "github.com/FloatTech/floatbox/web" "github.com/FloatTech/rendercard" @@ -39,10 +41,9 @@ const ( referer = "https://weibo.com/" ) -var boottime time.Time +var boottime = time.Now() func init() { // 插件主体 - boottime = time.Now() engine := control.Register("aifalse", &ctrl.Options[*zero.Ctx]{ DisableOnDefault: false, Brief: "自检, 全局限速", @@ -62,14 +63,21 @@ func init() { // 插件主体 } engine.OnFullMatchGroup([]string{"检查身体", "自检", "启动自检", "系统状态"}, zero.AdminPermission).SetBlock(true). Handle(func(ctx *zero.Ctx) { - img, err := drawstatus(ctx.Event.SelfID, zero.BotConfig.NickName[0]) + m, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) + if !ok { + ctx.SendChain(message.Text("ERROR: no such plugin")) + return + } + img, err := drawstatus(m, ctx.Event.SelfID, zero.BotConfig.NickName[0]) if err != nil { - ctx.SendChain(message.Text("ERROR:", err)) + ctx.SendChain(message.Text("ERROR: ", err)) return } - if id := ctx.SendChain(message.ImageBytes(img)); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR:可能被风控了")) + sendimg, cl := writer.ToBytes(img) + if id := ctx.SendChain(message.ImageBytes(sendimg)); id.ID() == 0 { + ctx.SendChain(message.Text("ERROR: 可能被风控了")) } + cl() }) engine.OnRegex(`^设置默认限速为每\s*(\d+)\s*(分钟|秒)\s*(\d+)\s*次触发$`, zero.SuperUserPermission).SetBlock(true). Handle(func(ctx *zero.Ctx) { @@ -109,14 +117,14 @@ func init() { // 插件主体 }) } -func drawstatus(uid int64, botname string) (sendimg []byte, err error) { +func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg image.Image, err error) { diskstate, err := diskstate() if err != nil { return } diskcardh := 40 + (20+50)*len(diskstate) + 40 - 20 - moreinfo, err := moreinfo() + moreinfo, err := moreinfo(m) if err != nil { return } @@ -134,11 +142,11 @@ func drawstatus(uid int64, botname string) (sendimg []byte, err error) { if err != nil { return } + data, err = web.GetData("http://q4.qlogo.cn/g?b=qq&nk=" + strconv.FormatInt(uid, 10) + "&s=640") if err != nil { return } - avatar, _, err := image.Decode(bytes.NewReader(data)) if err != nil { return @@ -160,35 +168,36 @@ func drawstatus(uid int64, botname string) (sendimg []byte, err error) { wg := &sync.WaitGroup{} wg.Add(5) - titlecard := gg.NewContext(canvas.W()-70-70, 250) - basiccard := gg.NewContext(canvas.W()-70-70, 380) - diskcard := gg.NewContext(canvas.W()-70-70, diskcardh) - moreinfocard := gg.NewContext(canvas.W()-70-70, moreinfocardh) - shadow := gg.NewContext(canvas.W(), canvas.H()) + cardw := canvas.W() - 70 - 70 + + titlecardh := 250 + basiccardh := 380 var titleimg, basicimg, diskimg, moreinfoimg, shadowimg image.Image go func() { defer wg.Done() + titlecard := gg.NewContext(cardw, titlecardh) titlecard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70) - titlecard.DrawRoundedRectangle(1, 1, float64(titlecard.W()-1*2), float64(titlecard.H()-1*2), 16) + titlecard.DrawRoundedRectangle(1, 1, float64(titlecard.W()-1*2), float64(titlecardh-1*2), 16) titlecard.SetLineWidth(3) titlecard.SetRGBA255(255, 255, 255, 100) titlecard.StrokePreserve() - titlecard.SetRGBA255(255, 255, 255, 100) + titlecard.SetRGBA255(255, 255, 255, 140) titlecard.Fill() - titlecard.DrawImage(avatarf.Circle(0).Im, (titlecard.H()-avatarf.H)/2, (titlecard.H()-avatarf.H)/2) + titlecard.DrawImage(avatarf.Circle(0).Im, (titlecardh-avatarf.H)/2, (titlecardh-avatarf.H)/2) err = titlecard.LoadFontFace(text.GlowSansFontFile, 72) if err != nil { return } - titlecard.SetRGBA255(30, 30, 30, 255) fw, _ := titlecard.MeasureString(botname) - titlecard.DrawStringAnchored(botname, float64(titlecard.H())+fw/2, float64(titlecard.H())*0.5/2, 0.5, 0.5) + titlecard.SetRGBA255(30, 30, 30, 255) + + titlecard.DrawStringAnchored(botname, float64(titlecardh)+fw/2, float64(titlecardh)*0.5/2, 0.5, 0.5) err = titlecard.LoadFontFace(text.GlowSansFontFile, 24) if err != nil { @@ -197,18 +206,17 @@ func drawstatus(uid int64, botname string) (sendimg []byte, err error) { titlecard.SetRGBA255(30, 30, 30, 180) titlecard.NewSubPath() - titlecard.MoveTo(float64(titlecard.H()), float64(titlecard.H())/2) - titlecard.LineTo(float64(titlecard.W()-titlecard.H()), float64(titlecard.H())/2) + titlecard.MoveTo(float64(titlecardh), float64(titlecardh)/2) + titlecard.LineTo(float64(titlecard.W()-titlecardh), float64(titlecardh)/2) titlecard.Stroke() brt, err := botruntime() if err != nil { return } - fw, _ = titlecard.MeasureString(brt) - titlecard.DrawStringAnchored(brt, float64(titlecard.H())+fw/2, float64(titlecard.H())*(0.5+0.25/2), 0.5, 0.5) + titlecard.DrawStringAnchored(brt, float64(titlecardh)+fw/2, float64(titlecardh)*(0.5+0.25/2), 0.5, 0.5) bs, err := botstatus() if err != nil { @@ -216,15 +224,16 @@ func drawstatus(uid int64, botname string) (sendimg []byte, err error) { } fw, _ = titlecard.MeasureString(bs) - titlecard.DrawStringAnchored(bs, float64(titlecard.H())+fw/2, float64(titlecard.H())*(0.5+0.5/2), 0.5, 0.5) + titlecard.DrawStringAnchored(bs, float64(titlecardh)+fw/2, float64(titlecardh)*(0.5+0.5/2), 0.5, 0.5) titleimg = rendercard.Fillet(titlecard.Image(), 16) }() go func() { defer wg.Done() + basiccard := gg.NewContext(cardw, basiccardh) - basiccard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecard.H()-40) + basiccard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecardh-40) - basiccard.DrawRoundedRectangle(1, 1, float64(basiccard.W()-1*2), float64(basiccard.H()-1*2), 16) + basiccard.DrawRoundedRectangle(1, 1, float64(basiccard.W()-1*2), float64(basiccardh-1*2), 16) basiccard.SetLineWidth(3) basiccard.SetRGBA255(255, 255, 255, 100) basiccard.StrokePreserve() @@ -286,13 +295,12 @@ func drawstatus(uid int64, botname string) (sendimg []byte, err error) { } basicimg = rendercard.Fillet(basiccard.Image(), 16) }() - go func() { defer wg.Done() + diskcard := gg.NewContext(cardw, diskcardh) + diskcard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecardh-40-basiccardh-40) - diskcard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecard.H()-40-basiccard.H()-40) - - diskcard.DrawRoundedRectangle(1, 1, float64(diskcard.W()-1*2), float64(diskcard.H()-1*2), 16) + diskcard.DrawRoundedRectangle(1, 1, float64(diskcard.W()-1*2), float64(basiccardh-1*2), 16) diskcard.SetLineWidth(3) diskcard.SetRGBA255(255, 255, 255, 100) diskcard.StrokePreserve() @@ -324,32 +332,33 @@ func drawstatus(uid int64, botname string) (sendimg []byte, err error) { return } diskcard.SetRGBA255(30, 30, 30, 255) + diskcard.DrawStringAnchored(v.name, 60/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) diskcard.DrawStringAnchored(v.text[0], (float64(diskcard.W())-60)/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) diskcard.DrawStringAnchored(strconv.FormatFloat(v.precent, 'f', 0, 64)+"%", float64(diskcard.W())-100/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) } diskimg = rendercard.Fillet(diskcard.Image(), 16) }() - go func() { defer wg.Done() + moreinfocard := gg.NewContext(cardw, moreinfocardh) - moreinfocard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecard.H()-40-basiccard.H()-40-diskcard.H()-40) + moreinfocard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecardh-40-basiccardh-40-diskcardh-40) moreinfocard.DrawRoundedRectangle(1, 1, float64(moreinfocard.W()-1*2), float64(moreinfocard.H()-1*2), 16) moreinfocard.SetLineWidth(3) - moreinfocard.SetRGBA255(255, 255, 255, 120) + moreinfocard.SetRGBA255(255, 255, 255, 100) moreinfocard.StrokePreserve() - moreinfocard.SetRGBA255(255, 255, 255, 160) + moreinfocard.SetRGBA255(255, 255, 255, 140) moreinfocard.Fill() milen := len(moreinfo) for i, v := range moreinfo { - err = moreinfocard.LoadFontFace(text.GlowSansFontFile, 32) if err != nil { return } + offset := float64(i)*(20+moreinfocard.FontHeight()) - 20 moreinfocard.SetRGBA255(30, 30, 30, 255) @@ -362,32 +371,41 @@ func drawstatus(uid int64, botname string) (sendimg []byte, err error) { } moreinfoimg = rendercard.Fillet(moreinfocard.Image(), 16) }() - go func() { defer wg.Done() + shadow := gg.NewContext(canvas.W(), canvas.H()) shadow.SetRGBA255(0, 0, 0, 100) shadow.SetLineWidth(12) - shadow.DrawRoundedRectangle(70, 70, float64(titlecard.W()), float64(titlecard.H()), 16) + shadow.DrawRoundedRectangle(70, 70, float64(cardw), float64(titlecardh), 16) shadow.Stroke() - shadow.DrawRoundedRectangle(70, float64(70+titlecard.H()+40), float64(basiccard.W()), float64(basiccard.H()), 16) + shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40), float64(cardw), float64(basiccardh), 16) shadow.Stroke() - shadow.DrawRoundedRectangle(70, float64(70+titlecard.H()+40+basiccard.H()+40), float64(diskcard.W()), float64(diskcard.H()), 16) + shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40+basiccardh+40), float64(cardw), float64(basiccardh), 16) shadow.Stroke() - shadow.DrawRoundedRectangle(70, float64(70+titlecard.H()+40+basiccard.H()+40+diskcard.H()+40), float64(moreinfocard.W()), float64(moreinfocard.H()), 16) + shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40+basiccardh+40+diskcardh+40), float64(cardw), float64(moreinfocardh), 16) shadow.Stroke() shadowimg = imaging.Blur(shadow.Image(), 24) }() wg.Wait() + if shadowimg == nil || titleimg == nil || basicimg == nil || diskimg == nil || moreinfoimg == nil { + err = errors.New("图片渲染失败") + return + } canvas.DrawImage(shadowimg, 0, 0) canvas.DrawImage(titleimg, 70, 70) - canvas.DrawImage(basicimg, 70, 70+titlecard.H()+40) - canvas.DrawImage(diskimg, 70, 70+titlecard.H()+40+basiccard.H()+40) - canvas.DrawImage(moreinfoimg, 70, 70+titlecard.H()+40+basiccard.H()+40+diskcard.H()+40) + canvas.DrawImage(basicimg, 70, 70+titlecardh+40) + canvas.DrawImage(diskimg, 70, 70+titlecardh+40+basiccardh+40) + canvas.DrawImage(moreinfoimg, 70, 70+titlecardh+40+basiccardh+40+diskcardh+40) + + canvas.LoadFontFace(text.GlowSansFontFile, 28) + canvas.SetRGBA255(0, 0, 0, 255) + canvas.DrawStringAnchored("Created By ZeroBot-Plugin "+kanban.Version, float64(canvas.W())/2+3, float64(canvas.H())-70/2+3, 0.5, 0.5) + canvas.SetRGBA255(255, 255, 255, 255) + canvas.DrawStringAnchored("Created By ZeroBot-Plugin "+kanban.Version, float64(canvas.W())/2, float64(canvas.H())-70/2, 0.5, 0.5) - sendimg, cl := writer.ToBytes(canvas.Image()) - defer cl() - return sendimg, nil + sendimg = canvas.Image() + return } func botruntime() (string, error) { @@ -414,7 +432,7 @@ func botstatus() (string, error) { } t := &strings.Builder{} t.WriteString(time.Now().Format("2006-01-02 15:04:05")) - t.WriteString(" | ") + t.WriteString(" | Compiled by ") t.WriteString(runtime.Version()) t.WriteString(" | ") t.WriteString(cases.Title(language.English).String(hostinfo.OS)) @@ -427,8 +445,7 @@ type status struct { text []string } -func basicstate() (stateinfo []*status, err error) { - stateinfo = make([]*status, 3) +func basicstate() (stateinfo [3]*status, err error) { percent, err := cpu.Percent(time.Second, false) if err != nil { return @@ -519,7 +536,7 @@ func diskstate() (stateinfo []*status, err error) { return } -func moreinfo() (stateinfo []*status, err error) { +func moreinfo(m *ctrl.Control[*zero.Ctx]) (stateinfo []*status, err error) { hostinfo, err := host.Info() if err != nil { return @@ -528,14 +545,7 @@ func moreinfo() (stateinfo []*status, err error) { if err != nil { return } - count := 0 - m, ok := control.Lookup("aifalse") - if ok { - m.Manager.ForEach(func(key string, manager *ctrl.Control[*zero.Ctx]) bool { - count++ - return true - }) - } + count := len(m.Manager.M) stateinfo = []*status{ {name: "OS", text: []string{hostinfo.Platform}}, {name: "CPU", text: []string{cpuinfo[0].ModelName}}, From d63fb947148f2ef4ee2f79d07b40cac1a46d8a39 Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Thu, 2 Feb 2023 15:41:31 +0000 Subject: [PATCH 3/8] =?UTF-8?q?=E5=88=A0=E6=8E=89=E7=A9=BA=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/ai_false/ai_false.go | 1 - 1 file changed, 1 deletion(-) diff --git a/plugin/ai_false/ai_false.go b/plugin/ai_false/ai_false.go index 0878bb3315..98af902d88 100644 --- a/plugin/ai_false/ai_false.go +++ b/plugin/ai_false/ai_false.go @@ -532,7 +532,6 @@ func diskstate() (stateinfo []*status, err error) { text: []string{usage}, } } - return } From 93a753031d7580c4cf55ddc1f789ed956af97fa6 Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Thu, 2 Feb 2023 15:45:32 +0000 Subject: [PATCH 4/8] make lint happy --- plugin/ai_false/ai_false.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugin/ai_false/ai_false.go b/plugin/ai_false/ai_false.go index 98af902d88..966ac0b74c 100644 --- a/plugin/ai_false/ai_false.go +++ b/plugin/ai_false/ai_false.go @@ -398,7 +398,10 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg canvas.DrawImage(diskimg, 70, 70+titlecardh+40+basiccardh+40) canvas.DrawImage(moreinfoimg, 70, 70+titlecardh+40+basiccardh+40+diskcardh+40) - canvas.LoadFontFace(text.GlowSansFontFile, 28) + err = canvas.LoadFontFace(text.GlowSansFontFile, 28) + if err != nil { + return + } canvas.SetRGBA255(0, 0, 0, 255) canvas.DrawStringAnchored("Created By ZeroBot-Plugin "+kanban.Version, float64(canvas.W())/2+3, float64(canvas.H())-70/2+3, 0.5, 0.5) canvas.SetRGBA255(255, 255, 255, 255) From c46d4606b423235d9007aed60abf3047b9130d0c Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Fri, 3 Feb 2023 16:26:11 +0000 Subject: [PATCH 5/8] =?UTF-8?q?=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/ai_false/ai_false.go | 47 +++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/plugin/ai_false/ai_false.go b/plugin/ai_false/ai_false.go index 966ac0b74c..0f7b34d938 100644 --- a/plugin/ai_false/ai_false.go +++ b/plugin/ai_false/ai_false.go @@ -15,6 +15,7 @@ import ( "github.com/Coloured-glaze/gg" "github.com/FloatTech/AnimeAPI/bilibili" "github.com/FloatTech/ZeroBot-Plugin/kanban" + "github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/img/writer" "github.com/FloatTech/floatbox/web" "github.com/FloatTech/rendercard" @@ -68,6 +69,11 @@ func init() { // 插件主体 ctx.SendChain(message.Text("ERROR: no such plugin")) return } + _, err := file.GetLazyData(text.GlowSansFontFile, control.Md5File, true) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } img, err := drawstatus(m, ctx.Event.SelfID, zero.BotConfig.NickName[0]) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) @@ -130,6 +136,11 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg } moreinfocardh := 30 + (20+32*72/96)*len(moreinfo) + 30 - 20 + basicstate, err := basicstate() + if err != nil { + return + } + url, err := bilibili.GetRealURL(backgroundURL) if err != nil { return @@ -240,10 +251,6 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg basiccard.SetRGBA255(255, 255, 255, 140) basiccard.Fill() - basicstate, err := basicstate() - if err != nil { - return - } bslen := len(basicstate) for i, v := range basicstate { offset := float64(i) * ((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1) + 200) @@ -307,12 +314,17 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg diskcard.SetRGBA255(255, 255, 255, 140) diskcard.Fill() + err = diskcard.LoadFontFace(text.GlowSansFontFile, 32) + if err != nil { + return + } + dslen := len(diskstate) for i, v := range diskstate { offset := float64(i)*(50+20) - 20 diskcard.SetRGBA255(192, 192, 192, 255) - diskcard.DrawRoundedRectangle(60, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, float64(diskcard.W())-60-100, 50, 12) + diskcard.DrawRoundedRectangle(40, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, float64(diskcard.W())-40-100, 50, 12) diskcard.Fill() switch { @@ -324,17 +336,16 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg diskcard.SetRGBA255(145, 240, 145, 255) } - diskcard.DrawRoundedRectangle(60, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, (float64(diskcard.W())-60-100)*v.precent*0.01, 50, 12) + diskcard.DrawRoundedRectangle(40, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, (float64(diskcard.W())-40-100)*v.precent*0.01, 50, 12) diskcard.Fill() - err = diskcard.LoadFontFace(text.GlowSansFontFile, 32) - if err != nil { - return - } diskcard.SetRGBA255(30, 30, 30, 255) - diskcard.DrawStringAnchored(v.name, 60/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) - diskcard.DrawStringAnchored(v.text[0], (float64(diskcard.W())-60)/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) + fw, _ := diskcard.MeasureString(v.name) + fw1, _ := diskcard.MeasureString(v.text[0]) + + diskcard.DrawStringAnchored(v.name, 40+10+fw/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) + diskcard.DrawStringAnchored(v.text[0], (float64(diskcard.W())-100-10)-fw1/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) diskcard.DrawStringAnchored(strconv.FormatFloat(v.precent, 'f', 0, 64)+"%", float64(diskcard.W())-100/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) } diskimg = rendercard.Fillet(diskcard.Image(), 16) @@ -352,13 +363,13 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg moreinfocard.SetRGBA255(255, 255, 255, 140) moreinfocard.Fill() + err = moreinfocard.LoadFontFace(text.GlowSansFontFile, 32) + if err != nil { + return + } + milen := len(moreinfo) for i, v := range moreinfo { - err = moreinfocard.LoadFontFace(text.GlowSansFontFile, 32) - if err != nil { - return - } - offset := float64(i)*(20+moreinfocard.FontHeight()) - 20 moreinfocard.SetRGBA255(30, 30, 30, 255) @@ -535,7 +546,7 @@ func diskstate() (stateinfo []*status, err error) { text: []string{usage}, } } - return + return stateinfo, nil } func moreinfo(m *ctrl.Control[*zero.Ctx]) (stateinfo []*status, err error) { From f625a711848be7479242e4d749c85840397e6b97 Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Fri, 3 Feb 2023 20:21:48 +0000 Subject: [PATCH 6/8] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=AA=E6=9C=89?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=88=86=E5=8C=BA=E7=9A=84=E6=83=85=E5=86=B5?= =?UTF-8?q?=E4=B8=8B=E7=94=BB=E4=B8=8D=E5=87=BA=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/ai_false/ai_false.go | 51 ++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/plugin/ai_false/ai_false.go b/plugin/ai_false/ai_false.go index 0f7b34d938..51dc8062dc 100644 --- a/plugin/ai_false/ai_false.go +++ b/plugin/ai_false/ai_false.go @@ -320,33 +320,60 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg } dslen := len(diskstate) - for i, v := range diskstate { - offset := float64(i)*(50+20) - 20 - + if dslen == 1 { diskcard.SetRGBA255(192, 192, 192, 255) - diskcard.DrawRoundedRectangle(40, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, float64(diskcard.W())-40-100, 50, 12) + diskcard.DrawRoundedRectangle(40, 40, float64(diskcard.W())-40-100, 50, 12) diskcard.Fill() switch { - case v.precent > 90: + case diskstate[0].precent > 90: diskcard.SetRGBA255(255, 70, 0, 255) - case v.precent > 70: + case diskstate[0].precent > 70: diskcard.SetRGBA255(255, 165, 0, 255) default: diskcard.SetRGBA255(145, 240, 145, 255) } - diskcard.DrawRoundedRectangle(40, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, (float64(diskcard.W())-40-100)*v.precent*0.01, 50, 12) + diskcard.DrawRoundedRectangle(40, 40, (float64(diskcard.W())-40-100)*diskstate[0].precent*0.01, 50, 12) diskcard.Fill() diskcard.SetRGBA255(30, 30, 30, 255) - fw, _ := diskcard.MeasureString(v.name) - fw1, _ := diskcard.MeasureString(v.text[0]) + fw, _ := diskcard.MeasureString(diskstate[0].name) + fw1, _ := diskcard.MeasureString(diskstate[0].text[0]) + + diskcard.DrawStringAnchored(diskstate[0].name, 40+10+fw/2, 40+50/2, 0.5, 0.5) + diskcard.DrawStringAnchored(diskstate[0].text[0], (float64(diskcard.W())-100-10)-fw1/2, 40+50/2, 0.5, 0.5) + diskcard.DrawStringAnchored(strconv.FormatFloat(diskstate[0].precent, 'f', 0, 64)+"%", float64(diskcard.W())-100/2, 40+50/2, 0.5, 0.5) + } else { + for i, v := range diskstate { + offset := float64(i)*(50+20) - 20 + + diskcard.SetRGBA255(192, 192, 192, 255) + diskcard.DrawRoundedRectangle(40, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, float64(diskcard.W())-40-100, 50, 12) + diskcard.Fill() - diskcard.DrawStringAnchored(v.name, 40+10+fw/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) - diskcard.DrawStringAnchored(v.text[0], (float64(diskcard.W())-100-10)-fw1/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) - diskcard.DrawStringAnchored(strconv.FormatFloat(v.precent, 'f', 0, 64)+"%", float64(diskcard.W())-100/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) + switch { + case v.precent > 90: + diskcard.SetRGBA255(255, 70, 0, 255) + case v.precent > 70: + diskcard.SetRGBA255(255, 165, 0, 255) + default: + diskcard.SetRGBA255(145, 240, 145, 255) + } + + diskcard.DrawRoundedRectangle(40, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, (float64(diskcard.W())-40-100)*v.precent*0.01, 50, 12) + diskcard.Fill() + + diskcard.SetRGBA255(30, 30, 30, 255) + + fw, _ := diskcard.MeasureString(v.name) + fw1, _ := diskcard.MeasureString(v.text[0]) + + diskcard.DrawStringAnchored(v.name, 40+10+fw/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) + diskcard.DrawStringAnchored(v.text[0], (float64(diskcard.W())-100-10)-fw1/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) + diskcard.DrawStringAnchored(strconv.FormatFloat(v.precent, 'f', 0, 64)+"%", float64(diskcard.W())-100/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5) + } } diskimg = rendercard.Fillet(diskcard.Image(), 16) }() From 99763735e2736e4972425f5c47f7f48a05fe9499 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 4 Feb 2023 04:23:13 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=F0=9F=8E=A8=20=E6=94=B9=E8=BF=9B=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A0=B7=E5=BC=8F=20(#20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- plugin/ai_false/ai_false.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugin/ai_false/ai_false.go b/plugin/ai_false/ai_false.go index 51dc8062dc..1c19636a82 100644 --- a/plugin/ai_false/ai_false.go +++ b/plugin/ai_false/ai_false.go @@ -14,7 +14,6 @@ import ( "github.com/Coloured-glaze/gg" "github.com/FloatTech/AnimeAPI/bilibili" - "github.com/FloatTech/ZeroBot-Plugin/kanban" "github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/img/writer" "github.com/FloatTech/floatbox/web" @@ -33,6 +32,8 @@ import ( "golang.org/x/text/cases" "golang.org/x/text/language" + "github.com/FloatTech/ZeroBot-Plugin/kanban" + zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" ) From c74c66a12dcc4709a5942e8af767fbfcaf001af9 Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Sat, 4 Feb 2023 17:03:39 +0000 Subject: [PATCH 8/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 1 + go.sum | 2 ++ plugin/ai_false/ai_false.go | 33 ++++++++++++++------------------- plugin/gif/gif.go | 2 +- plugin/gif/png.go | 2 +- plugin/qqwife/command.go | 3 +-- plugin/qzone/qzone.go | 2 +- plugin/score/sign_in.go | 2 +- plugin/wordle/wordle.go | 2 +- 9 files changed, 23 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 5c894ca2d3..fb27d9c190 100644 --- a/go.mod +++ b/go.mod @@ -44,6 +44,7 @@ require ( ) require ( + github.com/FloatTech/gg v1.0.0 github.com/antchfx/xpath v1.2.1 // indirect github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 // indirect github.com/faiface/beep v1.1.0 // indirect diff --git a/go.sum b/go.sum index 57475c142a..d0e996738e 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/FloatTech/AnimeAPI v1.6.1-0.20230130095520-be357484e5a7 h1:4FCjcjcsjU github.com/FloatTech/AnimeAPI v1.6.1-0.20230130095520-be357484e5a7/go.mod h1:LmHu358Oovtxhc/7xz+IfffUAMCX2bijpEvWatacEYQ= github.com/FloatTech/floatbox v0.0.0-20230130095057-3d1da721425e h1:RhKDmRNaBXK+lGY9FX+PAm75z03EHXp7y3/F2cZIv58= github.com/FloatTech/floatbox v0.0.0-20230130095057-3d1da721425e/go.mod h1:OoZE4Ra7olpFaJSrlD6mcyT4chPLg9QBRE1pzTC8R84= +github.com/FloatTech/gg v1.0.0 h1:Ydn2zHMah6WXD6Q/+OVvH8wuQEYmOj8ghloszgdRY5M= +github.com/FloatTech/gg v1.0.0/go.mod h1:tp7XIzGMl+SPiQyq9q5Gv/o0R09HM8KmbXExbvRIwjQ= github.com/FloatTech/rendercard v0.0.8 h1:IOZ757RKJGj4EAQj7XoW8iSNl6yVS98z0DK9LDup+Yo= github.com/FloatTech/rendercard v0.0.8/go.mod h1:hDqmlGgXBPI3QAvkE2kKjdPFAIB5cFQ55QnmXapAr3I= github.com/FloatTech/sqlite v1.5.7 h1:Bvo4LSojcZ6dVtbHrkqvt6z4v8e+sj0G5PSUIvdawsk= diff --git a/plugin/ai_false/ai_false.go b/plugin/ai_false/ai_false.go index 51dc8062dc..3736ea09c4 100644 --- a/plugin/ai_false/ai_false.go +++ b/plugin/ai_false/ai_false.go @@ -12,12 +12,12 @@ import ( "sync" "time" - "github.com/Coloured-glaze/gg" "github.com/FloatTech/AnimeAPI/bilibili" "github.com/FloatTech/ZeroBot-Plugin/kanban" "github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/img/writer" "github.com/FloatTech/floatbox/web" + "github.com/FloatTech/gg" "github.com/FloatTech/rendercard" ctrl "github.com/FloatTech/zbpctrl" "github.com/FloatTech/zbputils/control" @@ -64,17 +64,7 @@ func init() { // 插件主体 } engine.OnFullMatchGroup([]string{"检查身体", "自检", "启动自检", "系统状态"}, zero.AdminPermission).SetBlock(true). Handle(func(ctx *zero.Ctx) { - m, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) - if !ok { - ctx.SendChain(message.Text("ERROR: no such plugin")) - return - } - _, err := file.GetLazyData(text.GlowSansFontFile, control.Md5File, true) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - img, err := drawstatus(m, ctx.Event.SelfID, zero.BotConfig.NickName[0]) + img, err := drawstatus(ctx.State["manager"].(*ctrl.Control[*zero.Ctx]), ctx.Event.SelfID, zero.BotConfig.NickName[0]) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return @@ -164,6 +154,11 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg } avatarf := img.Size(avatar, 200, 200) + fontbyte, err := file.GetLazyData(text.GlowSansFontFile, control.Md5File, true) + if err != nil { + return + } + canvas := gg.NewContext(1280, 70+250+40+380+diskcardh+40+moreinfocardh+40+70) bh, bw, ch, cw := float64(back.Bounds().Dy()), float64(back.Bounds().Dx()), float64(canvas.H()), float64(canvas.W()) @@ -200,7 +195,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg titlecard.DrawImage(avatarf.Circle(0).Im, (titlecardh-avatarf.H)/2, (titlecardh-avatarf.H)/2) - err = titlecard.LoadFontFace(text.GlowSansFontFile, 72) + err = titlecard.LoadFontFace(fontbyte, 72) if err != nil { return } @@ -210,7 +205,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg titlecard.DrawStringAnchored(botname, float64(titlecardh)+fw/2, float64(titlecardh)*0.5/2, 0.5, 0.5) - err = titlecard.LoadFontFace(text.GlowSansFontFile, 24) + err = titlecard.LoadFontFace(fontbyte, 24) if err != nil { return } @@ -277,7 +272,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg basiccard.DrawCircle((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2, 80) basiccard.Fill() - err = basiccard.LoadFontFace(text.GlowSansFontFile, 42) + err = basiccard.LoadFontFace(fontbyte, 42) if err != nil { return } @@ -289,7 +284,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg _, fw := basiccard.MeasureString(v.name) basiccard.DrawStringAnchored(v.name, (float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200+15+basiccard.FontHeight()/2, 0.5, 0.5) - err = basiccard.LoadFontFace(text.GlowSansFontFile, 20) + err = basiccard.LoadFontFace(fontbyte, 20) if err != nil { return } @@ -314,7 +309,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg diskcard.SetRGBA255(255, 255, 255, 140) diskcard.Fill() - err = diskcard.LoadFontFace(text.GlowSansFontFile, 32) + err = diskcard.LoadFontFace(fontbyte, 32) if err != nil { return } @@ -390,7 +385,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg moreinfocard.SetRGBA255(255, 255, 255, 140) moreinfocard.Fill() - err = moreinfocard.LoadFontFace(text.GlowSansFontFile, 32) + err = moreinfocard.LoadFontFace(fontbyte, 32) if err != nil { return } @@ -436,7 +431,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg canvas.DrawImage(diskimg, 70, 70+titlecardh+40+basiccardh+40) canvas.DrawImage(moreinfoimg, 70, 70+titlecardh+40+basiccardh+40+diskcardh+40) - err = canvas.LoadFontFace(text.GlowSansFontFile, 28) + err = canvas.LoadFontFace(fontbyte, 28) if err != nil { return } diff --git a/plugin/gif/gif.go b/plugin/gif/gif.go index f147eff6dc..e3b3b44d50 100644 --- a/plugin/gif/gif.go +++ b/plugin/gif/gif.go @@ -6,9 +6,9 @@ import ( "image/color" "sync" - "github.com/Coloured-glaze/gg" "github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/img/writer" + "github.com/FloatTech/gg" "github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/img" "github.com/FloatTech/zbputils/img/text" diff --git a/plugin/gif/png.go b/plugin/gif/png.go index 9ecdd7fade..91f700cb61 100644 --- a/plugin/gif/png.go +++ b/plugin/gif/png.go @@ -8,9 +8,9 @@ import ( "strconv" "sync" - "github.com/Coloured-glaze/gg" "github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/img/writer" + "github.com/FloatTech/gg" "github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/img" "github.com/FloatTech/zbputils/img/text" diff --git a/plugin/qqwife/command.go b/plugin/qqwife/command.go index 1274261a59..f17b7c5bdd 100644 --- a/plugin/qqwife/command.go +++ b/plugin/qqwife/command.go @@ -21,12 +21,11 @@ import ( // 数据库 sql "github.com/FloatTech/sqlite" // 画图 - "github.com/Coloured-glaze/gg" fcext "github.com/FloatTech/floatbox/ctxext" "github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/img/writer" + "github.com/FloatTech/gg" "github.com/FloatTech/zbputils/img/text" - // 货币系统 ) type 婚姻登记 struct { diff --git a/plugin/qzone/qzone.go b/plugin/qzone/qzone.go index 975b2d5ddf..f1c2a314db 100644 --- a/plugin/qzone/qzone.go +++ b/plugin/qzone/qzone.go @@ -12,11 +12,11 @@ import ( "strings" "time" - "github.com/Coloured-glaze/gg" "github.com/FloatTech/AnimeAPI/qzone" "github.com/FloatTech/floatbox/binary" "github.com/FloatTech/floatbox/img/writer" "github.com/FloatTech/floatbox/web" + "github.com/FloatTech/gg" ctrl "github.com/FloatTech/zbpctrl" "github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/ctxext" diff --git a/plugin/score/sign_in.go b/plugin/score/sign_in.go index bf633dd38c..16f965bc7b 100644 --- a/plugin/score/sign_in.go +++ b/plugin/score/sign_in.go @@ -9,13 +9,13 @@ import ( "strconv" "time" - "github.com/Coloured-glaze/gg" "github.com/FloatTech/AnimeAPI/bilibili" "github.com/FloatTech/AnimeAPI/wallet" "github.com/FloatTech/floatbox/file" "github.com/FloatTech/floatbox/img/writer" "github.com/FloatTech/floatbox/process" "github.com/FloatTech/floatbox/web" + "github.com/FloatTech/gg" ctrl "github.com/FloatTech/zbpctrl" "github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/ctxext" diff --git a/plugin/wordle/wordle.go b/plugin/wordle/wordle.go index 1818d8939b..8f4684961c 100644 --- a/plugin/wordle/wordle.go +++ b/plugin/wordle/wordle.go @@ -14,10 +14,10 @@ import ( "github.com/FloatTech/AnimeAPI/tl" - "github.com/Coloured-glaze/gg" "github.com/FloatTech/floatbox/binary" fcext "github.com/FloatTech/floatbox/ctxext" "github.com/FloatTech/floatbox/img/writer" + "github.com/FloatTech/gg" ctrl "github.com/FloatTech/zbpctrl" "github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/ctxext"