Skip to content

Commit c486a21

Browse files
committed
✨ 增加插件 漂流瓶 #2
1 parent 0cd0195 commit c486a21

File tree

5 files changed

+202
-1
lines changed

5 files changed

+202
-1
lines changed

data

Submodule data updated 1 file

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import (
6464
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_cpstory" // cp短打
6565
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_danbooru" // DeepDanbooru二次元图标签识别
6666
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_diana" // 嘉心糖发病
67+
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_drift_bottle" // 漂流瓶
6768
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_emojimix" // 合成emoji
6869
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_fortune" // 运势
6970
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_funny" // 笑话

plugin_drift_bottle/data.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package driftbottle
2+
3+
import (
4+
"fmt"
5+
"hash/crc64"
6+
"strconv"
7+
"sync"
8+
9+
sql "github.com/FloatTech/sqlite"
10+
"github.com/FloatTech/zbputils/binary"
11+
)
12+
13+
type bottle struct {
14+
ID int64 `db:"id"` // ID qq_grp_name_msg 的 crc64
15+
QQ int64 `db:"qq"` // QQ 发送者 qq
16+
Grp int64 `db:"grp"` // Grp 限制抽出的群 / 人(负数)
17+
Name string `db:"name"` // Name 发送者 昵称
18+
Msg string `db:"msg"` // Msg 消息,纯文本
19+
}
20+
21+
var seamu sync.RWMutex
22+
23+
func newBottle(qq, grp int64, name, msg string) *bottle {
24+
id := int64(crc64.Checksum(binary.StringToBytes(fmt.Sprintf("%d_%d_%s_%s", qq, grp, name, msg)), crc64.MakeTable(crc64.ISO)))
25+
return &bottle{ID: id, QQ: qq, Grp: grp, Name: name, Msg: msg}
26+
}
27+
28+
func (b *bottle) throw(db *sql.Sqlite, channel string) error {
29+
seamu.Lock()
30+
defer seamu.Unlock()
31+
return db.Insert(channel, b)
32+
}
33+
34+
func (b *bottle) destroy(db *sql.Sqlite, channel string) error {
35+
seamu.Lock()
36+
defer seamu.Unlock()
37+
return db.Del(channel, "WHERE id="+strconv.FormatInt(b.ID, 10))
38+
}
39+
40+
// fetchBottle grp != 0
41+
func fetchBottle(db *sql.Sqlite, channel string, grp int64) (*bottle, error) {
42+
seamu.RLock()
43+
defer seamu.RUnlock()
44+
b := new(bottle)
45+
return b, db.Find(channel, b, "WHERE grp=0 or grp="+strconv.FormatInt(grp, 10)+" ORDER BY RANDOM() limit 1")
46+
}
47+
48+
func createChannel(db *sql.Sqlite, channel string) error {
49+
seamu.Lock()
50+
defer seamu.Unlock()
51+
return db.Create(channel, &bottle{})
52+
}

plugin_drift_bottle/db.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package driftbottle
2+
3+
import (
4+
"os"
5+
6+
sql "github.com/FloatTech/sqlite"
7+
)
8+
9+
const (
10+
dbpath = "data/driftbottle/"
11+
dbfile = dbpath + "sea.db"
12+
)
13+
14+
var sea = &sql.Sqlite{DBPath: dbfile}
15+
16+
func init() {
17+
_ = os.MkdirAll(dbpath, 0755)
18+
err := sea.Open()
19+
if err != nil {
20+
panic(err)
21+
}
22+
_ = createChannel(sea, "global")
23+
}

plugin_drift_bottle/main.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package driftbottle
2+
3+
import (
4+
"strconv"
5+
"strings"
6+
"sync"
7+
8+
"github.com/FloatTech/zbputils/control"
9+
"github.com/FloatTech/zbputils/control/order"
10+
"github.com/FloatTech/zbputils/ctxext"
11+
"github.com/sirupsen/logrus"
12+
zero "github.com/wdvxdr1123/ZeroBot"
13+
"github.com/wdvxdr1123/ZeroBot/message"
14+
)
15+
16+
func init() {
17+
en := control.Register("driftbottle", order.AcquirePrio(), &control.Options{
18+
DisableOnDefault: false,
19+
Help: "漂流瓶\n- (在群xxx)丢漂流瓶(到频道xxx) [消息]\n- (从频道xxx)捡漂流瓶\n- 创建频道 xxx\n- 跳入(频道)海中\n- 注:不显式限制时,私聊发送可在所有群抽到,群聊发送仅可在本群抽到,默认频道为 global",
20+
})
21+
en.OnRegex(`^(在群\d+)?丢漂流瓶(到频道\w+)?\s+(.*)$`).SetBlock(true).
22+
Handle(func(ctx *zero.Ctx) {
23+
msgs := ctx.State["regex_matched"].([]string)
24+
grp := ctx.Event.GroupID
25+
channel := "global"
26+
msg := msgs[3]
27+
var err error
28+
if msgs[1] != "" {
29+
grp, err = strconv.ParseInt(msgs[1][6:], 10, 64)
30+
if err != nil {
31+
ctx.SendChain(message.Text("群号非法!"))
32+
return
33+
}
34+
}
35+
if msgs[2] != "" {
36+
channel = msgs[2][9:]
37+
}
38+
if msg == "" {
39+
ctx.SendChain(message.Text("消息为空!"))
40+
return
41+
}
42+
logrus.Debugln("[driftbottle]", grp, channel, msg)
43+
err = newBottle(
44+
ctx.Event.UserID,
45+
grp,
46+
ctxext.CardOrNickName(ctx, ctx.Event.UserID),
47+
msg,
48+
).throw(sea, channel)
49+
if err != nil {
50+
ctx.SendChain(message.Text("ERROR:", err))
51+
return
52+
}
53+
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("你将它扔进大海,希望有人捞到吧~")))
54+
})
55+
en.OnRegex(`^(从频道\w+)?捡漂流瓶$`).SetBlock(true).
56+
Handle(func(ctx *zero.Ctx) {
57+
msgs := ctx.State["regex_matched"].([]string)
58+
grp := ctx.Event.GroupID
59+
if grp == 0 {
60+
grp = -ctx.Event.UserID
61+
}
62+
if grp == 0 {
63+
ctx.SendChain(message.Text("找不到对象!"))
64+
return
65+
}
66+
channel := "global"
67+
if msgs[1] != "" {
68+
channel = msgs[1][9:]
69+
}
70+
logrus.Debugln("[driftbottle]", grp, channel)
71+
b, err := fetchBottle(sea, channel, grp)
72+
if err != nil {
73+
ctx.SendChain(message.Text("ERROR:", err))
74+
return
75+
}
76+
var wg sync.WaitGroup
77+
wg.Add(1)
78+
go func() {
79+
err = b.destroy(sea, channel)
80+
wg.Done()
81+
}()
82+
ctx.Send(
83+
message.ReplyWithMessage(
84+
ctx.Event.MessageID,
85+
message.Text("你在海边捡到了一个来自 ", b.Name, " 的漂流瓶,打开瓶子,里面有一张纸条,写着:"),
86+
message.Text(b.Msg),
87+
),
88+
)
89+
wg.Wait()
90+
if err != nil {
91+
ctx.SendChain(message.Text("ERROR:", err))
92+
return
93+
}
94+
})
95+
en.OnPrefix("创建频道", zero.SuperUserPermission, zero.OnlyToMe).SetBlock(true).
96+
Handle(func(ctx *zero.Ctx) {
97+
channel := strings.TrimRight(ctx.State["args"].(string), " ")
98+
if channel == "" {
99+
ctx.SendChain(message.Text("频道名为空!"))
100+
return
101+
}
102+
err := createChannel(sea, channel)
103+
if err != nil {
104+
ctx.SendChain(message.Text("ERROR:", err))
105+
return
106+
}
107+
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("成功~")))
108+
})
109+
en.OnRegex(`^跳入(\w+)?海中$`).SetBlock(true).
110+
Handle(func(ctx *zero.Ctx) {
111+
msgs := ctx.State["regex_matched"].([]string)
112+
channel := "global"
113+
if msgs[1] != "" {
114+
channel = msgs[1]
115+
}
116+
seamu.RLock()
117+
c, err := sea.Count(channel)
118+
seamu.RUnlock()
119+
if err != nil {
120+
ctx.SendChain(message.Text("ERROR:", err))
121+
return
122+
}
123+
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("你缓缓走入大海,感受着海浪轻柔地拍打着你的小腿,膝盖……\n波浪卷着你的腰腹,你感觉有些把握不住平衡了……\n……\n你沉入海中,", c, " 个物体与你一同沉浮。\n不知何处涌来一股暗流,你失去了意识。")))
124+
})
125+
}

0 commit comments

Comments
 (0)