Skip to content

Commit fdf90a7

Browse files
author
MoeMagicMango
authored
feat: 全局漂流瓶 (#474)
* feat: remove driftbottle and push bottle global plugin. * Reverse name * change by requests
1 parent ba0c05a commit fdf90a7

File tree

2 files changed

+85
-163
lines changed

2 files changed

+85
-163
lines changed

plugin/drift_bottle/data.go

Lines changed: 0 additions & 53 deletions
This file was deleted.

plugin/drift_bottle/main.go

Lines changed: 85 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -2,132 +2,107 @@
22
package driftbottle
33

44
import (
5+
"fmt"
6+
"hash/crc64"
57
"strconv"
6-
"strings"
78
"sync"
89
"time"
10+
"unicode/utf8"
911

12+
"github.com/FloatTech/floatbox/binary"
13+
sql "github.com/FloatTech/sqlite"
1014
ctrl "github.com/FloatTech/zbpctrl"
1115
"github.com/FloatTech/zbputils/control"
12-
"github.com/sirupsen/logrus"
16+
"github.com/FloatTech/zbputils/ctxext"
1317
zero "github.com/wdvxdr1123/ZeroBot"
1418
"github.com/wdvxdr1123/ZeroBot/message"
1519
)
1620

21+
type sea struct {
22+
ID int64 `db:"id"` // ID qq_grp_name_msg 的 crc64 hashCheck.
23+
QQ int64 `db:"qq"` // Get current user(Who sends this)
24+
Name string `db:"Name"` // his or her name at that time:P
25+
Msg string `db:"msg"` // What he or she sent to bot?
26+
Grp int64 `db:"grp"` // which group sends this msg?
27+
Time string `db:"time"` // we need to know the current time,master>
28+
}
29+
30+
var seaSide = &sql.Sqlite{}
31+
var seaLocker sync.RWMutex
32+
33+
// We need a container to inject what we need :(
34+
1735
func init() {
1836
en := control.Register("driftbottle", &ctrl.Options[*zero.Ctx]{
1937
DisableOnDefault: false,
20-
Help: "漂流瓶\n- (在群xxx)丢漂流瓶(到频道xxx) [消息]\n- (从频道xxx)捡漂流瓶\n- @BOT 创建频道 xxx\n- 跳入(频道)海中\n- 注:不显式限制时,私聊发送可在所有群抽到,群聊发送仅可在本群抽到,默认频道为 global",
38+
Help: "简单的漂流瓶\n" + "- @bot pick" + "- @bot throw xxx (xxx为投递内容)",
2139
PrivateDataFolder: "driftbottle",
2240
})
23-
sea.DBPath = en.DataFolder() + "sea.db"
24-
err := sea.Open(time.Hour * 24)
41+
seaSide.DBPath = en.DataFolder() + "sea.db"
42+
err := seaSide.Open(time.Hour * 24)
2543
if err != nil {
2644
panic(err)
2745
}
28-
_ = createChannel(sea, "global")
29-
en.OnRegex(`^(在群\d+)?丢漂流瓶(到频道\w+)?\s+(.*)$`).SetBlock(true).
30-
Handle(func(ctx *zero.Ctx) {
31-
msgs := ctx.State["regex_matched"].([]string)
32-
grp := ctx.Event.GroupID
33-
channel := "global"
34-
msg := msgs[3]
35-
var err error
36-
if msgs[1] != "" {
37-
grp, err = strconv.ParseInt(msgs[1][6:], 10, 64)
38-
if err != nil {
39-
ctx.SendChain(message.Text("群号非法!"))
40-
return
41-
}
42-
}
43-
if msgs[2] != "" {
44-
channel = msgs[2][9:]
45-
}
46-
if msg == "" {
47-
ctx.SendChain(message.Text("消息为空!"))
48-
return
49-
}
50-
logrus.Debugln("[driftbottle]", grp, channel, msg)
51-
err = newBottle(
52-
ctx.Event.UserID,
53-
grp,
54-
ctx.CardOrNickName(ctx.Event.UserID),
55-
msg,
56-
).throw(sea, channel)
57-
if err != nil {
58-
ctx.SendChain(message.Text("ERROR: ", err))
59-
return
60-
}
61-
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("你将它扔进大海,希望有人捞到吧~")))
62-
})
63-
en.OnRegex(`^(从频道\w+)?捡漂流瓶$`).SetBlock(true).
64-
Handle(func(ctx *zero.Ctx) {
65-
msgs := ctx.State["regex_matched"].([]string)
66-
grp := ctx.Event.GroupID
67-
if grp == 0 {
68-
grp = -ctx.Event.UserID
69-
}
70-
if grp == 0 {
71-
ctx.SendChain(message.Text("找不到对象!"))
72-
return
73-
}
74-
channel := "global"
75-
if msgs[1] != "" {
76-
channel = msgs[1][9:]
77-
}
78-
logrus.Debugln("[driftbottle]", grp, channel)
79-
b, err := fetchBottle(sea, channel, grp)
80-
if err != nil {
81-
ctx.SendChain(message.Text("ERROR: ", err))
82-
return
83-
}
84-
var wg sync.WaitGroup
85-
wg.Add(1)
86-
go func() {
87-
err = b.destroy(sea, channel)
88-
wg.Done()
89-
}()
90-
ctx.Send(
91-
message.ReplyWithMessage(
92-
ctx.Event.MessageID,
93-
message.Text("你在海边捡到了一个来自 ", b.Name, " 的漂流瓶,打开瓶子,里面有一张纸条,写着:"),
94-
message.Text(b.Msg),
95-
),
96-
)
97-
wg.Wait()
98-
if err != nil {
99-
ctx.SendChain(message.Text("ERROR: ", err))
100-
return
101-
}
102-
})
103-
en.OnPrefix("创建频道", zero.SuperUserPermission, zero.OnlyToMe).SetBlock(true).
104-
Handle(func(ctx *zero.Ctx) {
105-
channel := strings.TrimRight(ctx.State["args"].(string), " ")
106-
if channel == "" {
107-
ctx.SendChain(message.Text("频道名为空!"))
108-
return
109-
}
110-
err := createChannel(sea, channel)
111-
if err != nil {
112-
ctx.SendChain(message.Text("ERROR: ", err))
113-
return
114-
}
115-
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("成功~")))
116-
})
117-
en.OnRegex(`^跳入(\w+)?海中$`).SetBlock(true).
118-
Handle(func(ctx *zero.Ctx) {
119-
msgs := ctx.State["regex_matched"].([]string)
120-
channel := "global"
121-
if msgs[1] != "" {
122-
channel = msgs[1]
123-
}
124-
seamu.RLock()
125-
c, err := sea.Count(channel)
126-
seamu.RUnlock()
127-
if err != nil {
128-
ctx.SendChain(message.Text("ERROR: ", err))
129-
return
130-
}
131-
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("你缓缓走入大海,感受着海浪轻柔地拍打着你的小腿,膝盖……\n波浪卷着你的腰腹,你感觉有些把握不住平衡了……\n……\n你沉入海中,", c, " 个物体与你一同沉浮。\n不知何处涌来一股暗流,你失去了意识。")))
132-
})
46+
47+
_ = createChannel(seaSide)
48+
en.OnFullMatch("pick", zero.OnlyToMe, zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
49+
be, err := fetchBottle(seaSide)
50+
if err != nil {
51+
ctx.SendChain(message.Text("ERR:", err))
52+
}
53+
idstr := strconv.Itoa(int(be.ID))
54+
qqstr := strconv.Itoa(int(be.QQ))
55+
grpstr := strconv.Itoa(int(be.Grp))
56+
botname := zero.BotConfig.NickName[0]
57+
msg := message.Message{message.CustomNode(botname, ctx.Event.SelfID, botname+"试着帮你捞出来了这个~\nID:"+idstr+"\n投递人: "+be.Name+"("+qqstr+")"+"\n群号: "+grpstr+"\n时间: "+be.Time+"\n内容: \n"+be.Msg)}
58+
ctx.Send(msg)
59+
})
60+
61+
en.OnRegex(`throw.*?(.*)`, zero.OnlyToMe, zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
62+
senderFormatTime := time.Unix(ctx.Event.Time, 0).Format("2006-01-02 15:04:05")
63+
rawSenderMessage := ctx.State["regex_matched"].([]string)[1]
64+
rawMessageCallBack := message.UnescapeCQCodeText(rawSenderMessage)
65+
keyWordsNum := utf8.RuneCountInString(rawMessageCallBack)
66+
if keyWordsNum < 10 {
67+
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("需要投递的内容过少( "))
68+
return
69+
}
70+
// check current needs and prepare to throw drift_bottle.
71+
err = globalbottle(
72+
ctx.Event.UserID,
73+
ctx.Event.GroupID,
74+
senderFormatTime,
75+
ctx.CardOrNickName(ctx.Event.UserID),
76+
rawMessageCallBack,
77+
).throw(seaSide)
78+
if err != nil {
79+
ctx.SendChain(message.Text("ERROR: ", err))
80+
return
81+
}
82+
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("已经帮你丢出去了哦~")))
83+
})
84+
}
85+
86+
func globalbottle(qq, grp int64, time, name, msg string) *sea { // Check as if the User is available and collect information to store.
87+
id := int64(crc64.Checksum(binary.StringToBytes(fmt.Sprintf("%d_%d_%s_%s_%s", grp, qq, time, name, msg)), crc64.MakeTable(crc64.ISO)))
88+
return &sea{ID: id, Grp: grp, Time: time, QQ: qq, Name: name, Msg: msg}
89+
}
90+
91+
func (be *sea) throw(db *sql.Sqlite) error {
92+
seaLocker.Lock()
93+
defer seaLocker.Unlock()
94+
return db.Insert("global", be)
95+
}
96+
97+
func fetchBottle(db *sql.Sqlite) (*sea, error) {
98+
seaLocker.Lock()
99+
defer seaLocker.Unlock()
100+
be := new(sea)
101+
return be, db.Pick("global", be)
102+
}
103+
104+
func createChannel(db *sql.Sqlite) error {
105+
seaLocker.Lock()
106+
defer seaLocker.Unlock()
107+
return db.Create("global", &sea{})
133108
}

0 commit comments

Comments
 (0)