mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 13:59:39 +08:00
feat(niuniu): 寫真으로 順位 表示 (#1024)
This commit is contained in:
parent
321c941ce5
commit
4b0a2a12a8
55
plugin/niuniu/draw.go
Normal file
55
plugin/niuniu/draw.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package niuniu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/FloatTech/floatbox/file"
|
||||||
|
"github.com/FloatTech/rendercard"
|
||||||
|
"github.com/FloatTech/zbputils/control"
|
||||||
|
"github.com/FloatTech/zbputils/img/text"
|
||||||
|
"image"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type drawUserRanking struct {
|
||||||
|
name string
|
||||||
|
user *userInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type drawer []drawUserRanking
|
||||||
|
|
||||||
|
func (allUsers drawer) draw(t bool) (img image.Image, err error) {
|
||||||
|
fontbyte, err := file.GetLazyData(text.GlowSansFontFile, control.Md5File, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
title string
|
||||||
|
s string
|
||||||
|
)
|
||||||
|
title = "牛牛深度排行"
|
||||||
|
s = "牛牛深度"
|
||||||
|
if t {
|
||||||
|
title = "牛牛长度排行"
|
||||||
|
s = "牛牛长度"
|
||||||
|
}
|
||||||
|
ri := make([]*rendercard.RankInfo, len(allUsers))
|
||||||
|
for i, user := range allUsers {
|
||||||
|
resp, err := http.Get(fmt.Sprintf("https://q1.qlogo.cn/g?b=qq&nk=%d&s=100", user.user.UID))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
decode, _, err := image.Decode(resp.Body)
|
||||||
|
_ = resp.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ri[i] = &rendercard.RankInfo{
|
||||||
|
Avatar: decode,
|
||||||
|
TopLeftText: user.name,
|
||||||
|
BottomLeftText: fmt.Sprintf("QQ:%d", user.user.UID),
|
||||||
|
RightText: fmt.Sprintf("%s:%.2fcm", s, user.user.Length),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img, err = rendercard.DrawRankingCard(fontbyte, title, ri)
|
||||||
|
return
|
||||||
|
}
|
||||||
@ -3,7 +3,6 @@ package niuniu
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -38,7 +37,7 @@ var (
|
|||||||
"- jj@xxx\n" +
|
"- jj@xxx\n" +
|
||||||
"- 使用[道具名称]jj@xxx\n" +
|
"- 使用[道具名称]jj@xxx\n" +
|
||||||
"- 注册牛牛\n" +
|
"- 注册牛牛\n" +
|
||||||
"- 赎牛牛(cd:45分钟)\n" +
|
"- 赎牛牛(cd:60分钟)\n" +
|
||||||
"- 牛牛商店\n" +
|
"- 牛牛商店\n" +
|
||||||
"- 牛牛背包\n" +
|
"- 牛牛背包\n" +
|
||||||
"- 注销牛牛\n" +
|
"- 注销牛牛\n" +
|
||||||
@ -158,14 +157,14 @@ func init() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Since(last.TimeLimit) > time.Minute*45 {
|
if time.Since(last.TimeLimit) > time.Minute*60 {
|
||||||
ctx.SendChain(message.Text("时间已经过期了,牛牛已被收回!"))
|
ctx.SendChain(message.Text("时间已经过期了,牛牛已被收回!"))
|
||||||
jjCount.Delete(fmt.Sprintf("%d_%d", gid, uid))
|
jjCount.Delete(fmt.Sprintf("%d_%d", gid, uid))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if last.Count < 6 {
|
if last.Count < 4 {
|
||||||
ctx.SendChain(message.Text("你还没有被厥够6次呢,不能赎牛牛"))
|
ctx.SendChain(message.Text("你还没有被厥够4次呢,不能赎牛牛"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,16 +207,14 @@ func init() {
|
|||||||
ctx.SendChain(message.Text("暂时没有男孩子哦"))
|
ctx.SendChain(message.Text("暂时没有男孩子哦"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var messages strings.Builder
|
m.sort(true)
|
||||||
messages.WriteString("牛子长度排行榜\n")
|
buf, err := m.setupDrawList(ctx, true)
|
||||||
for i, user := range m.sort(true) {
|
if err != nil {
|
||||||
messages.WriteString(fmt.Sprintf("第%d名 id:%s 长度:%.2fcm\n", i+1,
|
ctx.SendChain(message.Text("ERROR: ", err))
|
||||||
ctx.CardOrNickName(user.UID), user.Length))
|
return
|
||||||
}
|
|
||||||
msg := ctxext.FakeSenderForwardNode(ctx, message.Text(&messages))
|
|
||||||
if id := ctx.Send(message.Message{msg}).ID(); id == 0 {
|
|
||||||
ctx.Send(message.Text("发送排行失败"))
|
|
||||||
}
|
}
|
||||||
|
ctx.SendChain(message.ImageBytes(buf))
|
||||||
|
|
||||||
})
|
})
|
||||||
en.OnFullMatch("牛子深度排行", zero.OnlyGroup, getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
en.OnFullMatch("牛子深度排行", zero.OnlyGroup, getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||||
gid := ctx.Event.GroupID
|
gid := ctx.Event.GroupID
|
||||||
@ -231,16 +228,14 @@ func init() {
|
|||||||
ctx.SendChain(message.Text("暂时没有女孩子哦"))
|
ctx.SendChain(message.Text("暂时没有女孩子哦"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var messages strings.Builder
|
m.sort(false)
|
||||||
messages.WriteString("牛牛深度排行榜\n")
|
buf, err := m.setupDrawList(ctx, false)
|
||||||
for i, user := range m.sort(false) {
|
if err != nil {
|
||||||
messages.WriteString(fmt.Sprintf("第%d名 id:%s 长度:%.2fcm\n", i+1,
|
ctx.SendChain(message.Text("ERROR: ", err))
|
||||||
ctx.CardOrNickName(user.UID), user.Length))
|
return
|
||||||
}
|
|
||||||
msg := ctxext.FakeSenderForwardNode(ctx, message.Text(&messages))
|
|
||||||
if id := ctx.Send(message.Message{msg}).ID(); id == 0 {
|
|
||||||
ctx.Send(message.Text("发送排行失败"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.SendChain(message.ImageBytes(buf))
|
||||||
})
|
})
|
||||||
en.OnFullMatch("查看我的牛牛", getdb, zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
en.OnFullMatch("查看我的牛牛", getdb, zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||||
uid := ctx.Event.UserID
|
uid := ctx.Event.UserID
|
||||||
@ -411,7 +406,7 @@ func init() {
|
|||||||
Count: count.Count + 1,
|
Count: count.Count + 1,
|
||||||
Length: count.Length,
|
Length: count.Length,
|
||||||
}
|
}
|
||||||
if time.Since(c.TimeLimit) > time.Minute*45 {
|
if time.Since(c.TimeLimit) > time.Minute*60 {
|
||||||
c = lastLength{
|
c = lastLength{
|
||||||
TimeLimit: time.Now(),
|
TimeLimit: time.Now(),
|
||||||
Count: 1,
|
Count: 1,
|
||||||
@ -421,11 +416,11 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jjCount.Store(j, &c)
|
jjCount.Store(j, &c)
|
||||||
if c.Count > 5 {
|
if c.Count > 2 {
|
||||||
ctx.SendChain(message.Text(randomChoice([]string{fmt.Sprintf("你们太厉害了,对方已经被你们打了%d次了,你们可以继续找他🤺", c.Count),
|
ctx.SendChain(message.Text(randomChoice([]string{fmt.Sprintf("你们太厉害了,对方已经被你们打了%d次了,你们可以继续找他🤺", c.Count),
|
||||||
"你们不要再找ta🤺啦!"})))
|
"你们不要再找ta🤺啦!"})))
|
||||||
// 保证只发送一次
|
// 保证只发送一次
|
||||||
if c.Count < 7 {
|
if c.Count < 4 {
|
||||||
id := ctx.SendPrivateMessage(adduser,
|
id := ctx.SendPrivateMessage(adduser,
|
||||||
message.Text(fmt.Sprintf("你在%d群里已经被厥冒烟了,快去群里赎回你原本的牛牛!\n发送:`赎牛牛`即可!", gid)))
|
message.Text(fmt.Sprintf("你在%d群里已经被厥冒烟了,快去群里赎回你原本的牛牛!\n发送:`赎牛牛`即可!", gid)))
|
||||||
if id == 0 {
|
if id == 0 {
|
||||||
@ -450,35 +445,3 @@ func init() {
|
|||||||
ctx.SendChain(message.Text("注销成功,你已经没有牛牛了"))
|
ctx.SendChain(message.Text("注销成功,你已经没有牛牛了"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func randomChoice(options []string) string {
|
|
||||||
return options[rand.Intn(len(options))]
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateMap(t string, d bool) {
|
|
||||||
value, ok := prop.Load(t)
|
|
||||||
if value == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 检查一次是否已经过期
|
|
||||||
if !d {
|
|
||||||
if time.Since(value.TimeLimit) > time.Minute*8 {
|
|
||||||
prop.Delete(t)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ok {
|
|
||||||
prop.Store(t, &propsCount{
|
|
||||||
Count: value.Count + 1,
|
|
||||||
TimeLimit: value.TimeLimit,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
prop.Store(t, &propsCount{
|
|
||||||
Count: 1,
|
|
||||||
TimeLimit: time.Now(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if time.Since(value.TimeLimit) > time.Minute*8 {
|
|
||||||
prop.Delete(t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -2,8 +2,10 @@
|
|||||||
package niuniu
|
package niuniu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image/png"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sort"
|
"sort"
|
||||||
@ -275,6 +277,23 @@ func (u *userInfo) purchaseItem(n int) (int, error) {
|
|||||||
return money, err
|
return money, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m users) setupDrawList(ctx *zero.Ctx, t bool) ([]byte, error) {
|
||||||
|
allUsers := make(drawer, len(m))
|
||||||
|
for i, info := range m {
|
||||||
|
allUsers[i] = drawUserRanking{
|
||||||
|
name: ctx.CardOrNickName(info.UID),
|
||||||
|
user: info,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image, err := allUsers.draw(t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = png.Encode(&buf, image)
|
||||||
|
return buf.Bytes(), err
|
||||||
|
}
|
||||||
|
|
||||||
func (m users) positive() users {
|
func (m users) positive() users {
|
||||||
var m1 []*userInfo
|
var m1 []*userInfo
|
||||||
for _, i2 := range m {
|
for _, i2 := range m {
|
||||||
@ -295,7 +314,7 @@ func (m users) negative() users {
|
|||||||
return m1
|
return m1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m users) sort(isDesc bool) users {
|
func (m users) sort(isDesc bool) {
|
||||||
t := func(i, j int) bool {
|
t := func(i, j int) bool {
|
||||||
return m[i].Length < m[j].Length
|
return m[i].Length < m[j].Length
|
||||||
}
|
}
|
||||||
@ -305,12 +324,11 @@ func (m users) sort(isDesc bool) users {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Slice(m, t)
|
sort.Slice(m, t)
|
||||||
return m
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m users) ranking(niuniu float64, uid int64) int {
|
func (m users) ranking(niuniu float64, uid int64) int {
|
||||||
result := niuniu > 0
|
m.sort(niuniu > 0)
|
||||||
for i, user := range m.sort(result) {
|
for i, user := range m {
|
||||||
if user.UID == uid {
|
if user.UID == uid {
|
||||||
return i + 1
|
return i + 1
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -13,6 +14,48 @@ var (
|
|||||||
dajiaoProp = []string{"伟哥", "媚药"}
|
dajiaoProp = []string{"伟哥", "媚药"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 检查字符串是否在切片中
|
||||||
|
func contains(s string, array []string) bool {
|
||||||
|
for _, item := range array {
|
||||||
|
if strings.EqualFold(item, s) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func randomChoice(options []string) string {
|
||||||
|
return options[rand.Intn(len(options))]
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateMap(t string, d bool) {
|
||||||
|
value, ok := prop.Load(t)
|
||||||
|
if value == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 检查一次是否已经过期
|
||||||
|
if !d {
|
||||||
|
if time.Since(value.TimeLimit) > time.Minute*8 {
|
||||||
|
prop.Delete(t)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
prop.Store(t, &propsCount{
|
||||||
|
Count: value.Count + 1,
|
||||||
|
TimeLimit: value.TimeLimit,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
prop.Store(t, &propsCount{
|
||||||
|
Count: 1,
|
||||||
|
TimeLimit: time.Now(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if time.Since(value.TimeLimit) > time.Minute*8 {
|
||||||
|
prop.Delete(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func generateRandomStingTwo(niuniu float64) (string, float64) {
|
func generateRandomStingTwo(niuniu float64) (string, float64) {
|
||||||
probability := rand.Intn(100 + 1)
|
probability := rand.Intn(100 + 1)
|
||||||
reduce := math.Abs(hitGlue(niuniu))
|
reduce := math.Abs(hitGlue(niuniu))
|
||||||
@ -205,13 +248,3 @@ func hitGlue(l float64) float64 {
|
|||||||
return rand.Float64()
|
return rand.Float64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查字符串是否在切片中
|
|
||||||
func contains(s string, array []string) bool {
|
|
||||||
for _, item := range array {
|
|
||||||
if strings.EqualFold(item, s) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user