mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 13:59:39 +08:00
✨ 增加插件 漂流瓶 #2
This commit is contained in:
parent
0cd01959a0
commit
c486a210e4
2
data
2
data
@ -1 +1 @@
|
||||
Subproject commit 3a7d07ec9955fa7162d4600f1d4fb1ebefa0dc23
|
||||
Subproject commit 431911b8755799e61f096c7853a05731743f3761
|
||||
1
main.go
1
main.go
@ -64,6 +64,7 @@ import (
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_cpstory" // cp短打
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_danbooru" // DeepDanbooru二次元图标签识别
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_diana" // 嘉心糖发病
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_drift_bottle" // 漂流瓶
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_emojimix" // 合成emoji
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_fortune" // 运势
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_funny" // 笑话
|
||||
|
||||
52
plugin_drift_bottle/data.go
Normal file
52
plugin_drift_bottle/data.go
Normal file
@ -0,0 +1,52 @@
|
||||
package driftbottle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash/crc64"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
sql "github.com/FloatTech/sqlite"
|
||||
"github.com/FloatTech/zbputils/binary"
|
||||
)
|
||||
|
||||
type bottle struct {
|
||||
ID int64 `db:"id"` // ID qq_grp_name_msg 的 crc64
|
||||
QQ int64 `db:"qq"` // QQ 发送者 qq
|
||||
Grp int64 `db:"grp"` // Grp 限制抽出的群 / 人(负数)
|
||||
Name string `db:"name"` // Name 发送者 昵称
|
||||
Msg string `db:"msg"` // Msg 消息,纯文本
|
||||
}
|
||||
|
||||
var seamu sync.RWMutex
|
||||
|
||||
func newBottle(qq, grp int64, name, msg string) *bottle {
|
||||
id := int64(crc64.Checksum(binary.StringToBytes(fmt.Sprintf("%d_%d_%s_%s", qq, grp, name, msg)), crc64.MakeTable(crc64.ISO)))
|
||||
return &bottle{ID: id, QQ: qq, Grp: grp, Name: name, Msg: msg}
|
||||
}
|
||||
|
||||
func (b *bottle) throw(db *sql.Sqlite, channel string) error {
|
||||
seamu.Lock()
|
||||
defer seamu.Unlock()
|
||||
return db.Insert(channel, b)
|
||||
}
|
||||
|
||||
func (b *bottle) destroy(db *sql.Sqlite, channel string) error {
|
||||
seamu.Lock()
|
||||
defer seamu.Unlock()
|
||||
return db.Del(channel, "WHERE id="+strconv.FormatInt(b.ID, 10))
|
||||
}
|
||||
|
||||
// fetchBottle grp != 0
|
||||
func fetchBottle(db *sql.Sqlite, channel string, grp int64) (*bottle, error) {
|
||||
seamu.RLock()
|
||||
defer seamu.RUnlock()
|
||||
b := new(bottle)
|
||||
return b, db.Find(channel, b, "WHERE grp=0 or grp="+strconv.FormatInt(grp, 10)+" ORDER BY RANDOM() limit 1")
|
||||
}
|
||||
|
||||
func createChannel(db *sql.Sqlite, channel string) error {
|
||||
seamu.Lock()
|
||||
defer seamu.Unlock()
|
||||
return db.Create(channel, &bottle{})
|
||||
}
|
||||
23
plugin_drift_bottle/db.go
Normal file
23
plugin_drift_bottle/db.go
Normal file
@ -0,0 +1,23 @@
|
||||
package driftbottle
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
sql "github.com/FloatTech/sqlite"
|
||||
)
|
||||
|
||||
const (
|
||||
dbpath = "data/driftbottle/"
|
||||
dbfile = dbpath + "sea.db"
|
||||
)
|
||||
|
||||
var sea = &sql.Sqlite{DBPath: dbfile}
|
||||
|
||||
func init() {
|
||||
_ = os.MkdirAll(dbpath, 0755)
|
||||
err := sea.Open()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_ = createChannel(sea, "global")
|
||||
}
|
||||
125
plugin_drift_bottle/main.go
Normal file
125
plugin_drift_bottle/main.go
Normal file
@ -0,0 +1,125 @@
|
||||
package driftbottle
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/control/order"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
"github.com/sirupsen/logrus"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
func init() {
|
||||
en := control.Register("driftbottle", order.AcquirePrio(), &control.Options{
|
||||
DisableOnDefault: false,
|
||||
Help: "漂流瓶\n- (在群xxx)丢漂流瓶(到频道xxx) [消息]\n- (从频道xxx)捡漂流瓶\n- 创建频道 xxx\n- 跳入(频道)海中\n- 注:不显式限制时,私聊发送可在所有群抽到,群聊发送仅可在本群抽到,默认频道为 global",
|
||||
})
|
||||
en.OnRegex(`^(在群\d+)?丢漂流瓶(到频道\w+)?\s+(.*)$`).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
msgs := ctx.State["regex_matched"].([]string)
|
||||
grp := ctx.Event.GroupID
|
||||
channel := "global"
|
||||
msg := msgs[3]
|
||||
var err error
|
||||
if msgs[1] != "" {
|
||||
grp, err = strconv.ParseInt(msgs[1][6:], 10, 64)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("群号非法!"))
|
||||
return
|
||||
}
|
||||
}
|
||||
if msgs[2] != "" {
|
||||
channel = msgs[2][9:]
|
||||
}
|
||||
if msg == "" {
|
||||
ctx.SendChain(message.Text("消息为空!"))
|
||||
return
|
||||
}
|
||||
logrus.Debugln("[driftbottle]", grp, channel, msg)
|
||||
err = newBottle(
|
||||
ctx.Event.UserID,
|
||||
grp,
|
||||
ctxext.CardOrNickName(ctx, ctx.Event.UserID),
|
||||
msg,
|
||||
).throw(sea, channel)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("你将它扔进大海,希望有人捞到吧~")))
|
||||
})
|
||||
en.OnRegex(`^(从频道\w+)?捡漂流瓶$`).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
msgs := ctx.State["regex_matched"].([]string)
|
||||
grp := ctx.Event.GroupID
|
||||
if grp == 0 {
|
||||
grp = -ctx.Event.UserID
|
||||
}
|
||||
if grp == 0 {
|
||||
ctx.SendChain(message.Text("找不到对象!"))
|
||||
return
|
||||
}
|
||||
channel := "global"
|
||||
if msgs[1] != "" {
|
||||
channel = msgs[1][9:]
|
||||
}
|
||||
logrus.Debugln("[driftbottle]", grp, channel)
|
||||
b, err := fetchBottle(sea, channel, grp)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
err = b.destroy(sea, channel)
|
||||
wg.Done()
|
||||
}()
|
||||
ctx.Send(
|
||||
message.ReplyWithMessage(
|
||||
ctx.Event.MessageID,
|
||||
message.Text("你在海边捡到了一个来自 ", b.Name, " 的漂流瓶,打开瓶子,里面有一张纸条,写着:"),
|
||||
message.Text(b.Msg),
|
||||
),
|
||||
)
|
||||
wg.Wait()
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
})
|
||||
en.OnPrefix("创建频道", zero.SuperUserPermission, zero.OnlyToMe).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
channel := strings.TrimRight(ctx.State["args"].(string), " ")
|
||||
if channel == "" {
|
||||
ctx.SendChain(message.Text("频道名为空!"))
|
||||
return
|
||||
}
|
||||
err := createChannel(sea, channel)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("成功~")))
|
||||
})
|
||||
en.OnRegex(`^跳入(\w+)?海中$`).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
msgs := ctx.State["regex_matched"].([]string)
|
||||
channel := "global"
|
||||
if msgs[1] != "" {
|
||||
channel = msgs[1]
|
||||
}
|
||||
seamu.RLock()
|
||||
c, err := sea.Count(channel)
|
||||
seamu.RUnlock()
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("你缓缓走入大海,感受着海浪轻柔地拍打着你的小腿,膝盖……\n波浪卷着你的腰腹,你感觉有些把握不住平衡了……\n……\n你沉入海中,", c, " 个物体与你一同沉浮。\n不知何处涌来一股暗流,你失去了意识。")))
|
||||
})
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user