Compare commits

..

28 Commits

Author SHA1 Message Date
fumiama
bb63b98f39 ✏️ 更改版本为 v1.2.1 2021-11-29 20:27:42 +08:00
fumiama
f3f7e2d3c1 ✏️ 修正 sql 2021-11-29 20:25:14 +08:00
fumiama
89121cfc57 新增 本地 setu 插件 2021-11-29 15:33:15 +08:00
fumiama
d8a41a5ee1 ✏️ 修复 control 找不到服务时 panic (#81) 2021-11-27 01:10:51 +08:00
fumiama
f8ca9355d2 ✏️ 修复 control 全局禁用 2021-11-27 00:56:22 +08:00
fumiama
d4bceb1922 ✏️ 修复 control 全局禁用 2021-11-27 00:49:50 +08:00
fumiama
876d85ac4e ✏️ 修复 control 全局禁用 2021-11-27 00:48:32 +08:00
fumiama
ab34930beb ✏️ 修复 control 全局禁用 2021-11-27 00:40:48 +08:00
fumiama
35f7450ab2 ✏️ 修复 control 全局禁用 2021-11-27 00:36:29 +08:00
fumiama
2917ff6701 ✏️ 持久化 fansdaily 2021-11-26 19:45:48 +08:00
fumiama
d1656b25c9 ✏️ 默认禁用 wtf 2021-11-26 19:22:02 +08:00
fumiama
e6a20866b6 ✏️ 优化 getea 2021-11-26 18:48:05 +08:00
fumiama
9de065d31a ✏️ 修正 moyu 提醒 2021-11-26 11:39:43 +08:00
fumiama
37d27e07e9 ✏️ 小修正 2021-11-25 22:39:25 +08:00
fumiama
01853768db ✏️ 小修正 2021-11-23 23:25:04 +08:00
fumiama
9d3787dfc2 ✏️ 小修正 2021-11-23 23:05:59 +08:00
fumiama
e9f145056d ✏️ 小修正 2021-11-23 22:51:18 +08:00
fumiama
ea17943bff ✏️ 新增 wtf 2021-11-23 22:40:49 +08:00
fumiama
180c32ef50 ✏️ 优化 moyu 格式 2021-11-23 21:35:42 +08:00
fumiama
17bb844360 ✏️ vtb drop unsafe 2021-11-23 13:05:16 +08:00
fumiama
3d0a161176 ✏️ 修正 badge 2021-11-23 12:46:05 +08:00
fumiama
1148867d3c Merge branch 'master' of https://github.com/FloatTech/ZeroBot-Plugin 2021-11-23 12:33:33 +08:00
fumiama
c83d01e977 ✏️ 修复摸鱼 cron 2021-11-23 12:33:24 +08:00
ByronLeeeee
7c42d6f857 修复代理域名,解决PC端无法看图问题 (#80)
1.代理域名从.cat替换成.re;
2.Large尺寸图无法在PC QQ看见,已更改成Medium尺寸
2021-11-23 12:30:40 +08:00
fumiama
ac1c6bc74b ✏️ 在 main 添加摸鱼 2021-11-22 22:40:01 +08:00
fumiama
12f96bb95c ✏️ 修复 vtb panic 判断失误 2021-11-22 22:33:29 +08:00
fumiama
fa063a05f7 ✏️ 修复 vtb 自动下载数据库失败 2021-11-22 22:29:07 +08:00
fumiama
51d10d3234 升级加密算法 2021-11-22 22:22:13 +08:00
23 changed files with 734 additions and 175 deletions

View File

@@ -12,8 +12,8 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/FloatTech/ZeroBot-Plugin?style=flat-square&logo=go)](https://goreportcard.com/report/github.com/github.com/FloatTech/ZeroBot-Plugin)
[![Badge](https://img.shields.io/badge/onebot-v11-black?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAABwCAMAAADxPgR5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAxQTFRF////29vbr6+vAAAAk1hCcwAAAAR0Uk5T////AEAqqfQAAAKcSURBVHja7NrbctswDATQXfD//zlpO7FlmwAWIOnOtNaTM5JwDMa8E+PNFz7g3waJ24fviyDPgfhz8fHP39cBcBL9KoJbQUxjA2iYqHL3FAnvzhL4GtVNUcoSZe6eSHizBcK5LL7dBr2AUZlev1ARRHCljzRALIEog6H3U6bCIyqIZdAT0eBuJYaGiJaHSjmkYIZd+qSGWAQnIaz2OArVnX6vrItQvbhZJtVGB5qX9wKqCMkb9W7aexfCO/rwQRBzsDIsYx4AOz0nhAtWu7bqkEQBO0Pr+Ftjt5fFCUEbm0Sbgdu8WSgJ5NgH2iu46R/o1UcBXJsFusWF/QUaz3RwJMEgngfaGGdSxJkE/Yg4lOBryBiMwvAhZrVMUUvwqU7F05b5WLaUIN4M4hRocQQRnEedgsn7TZB3UCpRrIJwQfqvGwsg18EnI2uSVNC8t+0QmMXogvbPg/xk+Mnw/6kW/rraUlvqgmFreAA09xW5t0AFlHrQZ3CsgvZm0FbHNKyBmheBKIF2cCA8A600aHPmFtRB1XvMsJAiza7LpPog0UJwccKdzw8rdf8MyN2ePYF896LC5hTzdZqxb6VNXInaupARLDNBWgI8spq4T0Qb5H4vWfPmHo8OyB1ito+AysNNz0oglj1U955sjUN9d41LnrX2D/u7eRwxyOaOpfyevCWbTgDEoilsOnu7zsKhjRCsnD/QzhdkYLBLXjiK4f3UWmcx2M7PO21CKVTH84638NTplt6JIQH0ZwCNuiWAfvuLhdrcOYPVO9eW3A67l7hZtgaY9GZo9AFc6cryjoeFBIWeU+npnk/nLE0OxCHL1eQsc1IciehjpJv5mqCsjeopaH6r15/MrxNnVhu7tmcslay2gO2Z1QfcfX0JMACG41/u0RrI9QAAAABJRU5ErkJggg==)](https://github.com/howmanybots/onebot)
[![Badge](https://img.shields.io/badge/zerobot-v1.3.2-black?style=flat-square&logo=go)](https://github.com/wdvxdr1123/ZeroBot)
[![License](https://img.shields.io/github/license/Yiwen-Chan/OneBot-YaYa.svg?style=flat-square&logo=gnu)](https://raw.githubusercontent.com/FloatTech/ZeroBot-Plugin/master/LICENSE)
[![Badge](https://img.shields.io/badge/zerobot-v1.4.1-black?style=flat-square&logo=go)](https://github.com/wdvxdr1123/ZeroBot)
[![License](https://img.shields.io/github/license/FloatTech/ZeroBot-Plugin.svg?style=flat-square&logo=gnu)](https://raw.githubusercontent.com/FloatTech/ZeroBot-Plugin/master/LICENSE)
[![qq group](https://img.shields.io/badge/group-1048452984-red?style=flat-square&logo=tencent-qq)](https://jq.qq.com/?_wv=1027&k=QMb7x1mM)
</div>
@@ -122,6 +122,12 @@ zerobot -h -t token -u url [-d|w] [-g 监听地址:端口] qq1 qq2 qq3 ...
- [x] 添加[涩图/二次元/风景/车万][P站图片ID]
- [x] 删除[涩图/二次元/风景/车万][P站图片ID]
- [x] > setu status
- **本地涩图** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_nativesetu"`
- [x] 本地[xxx]
- [x] 刷新本地[xxx]
- [x] 设置本地setu绝对路径[xxx]
- [x] 刷新所有本地setu
- [x] 所有本地setu分类
- **lolicon** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_lolicon"`
- [x] 来份萝莉
- **搜图** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_saucenao"`
@@ -149,6 +155,10 @@ zerobot -h -t token -u url [-d|w] [-g 监听地址:端口] qq1 qq2 qq3 ...
- [x] 发大病
- [x] 教你一篇小作文[作文]
- [x] [回复]查重
- **鬼东西** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_wtf"`
- [x] 鬼东西列表
- [x] 查询鬼东西[序号][@xxx]
- 注:由于需要科学,默认注释。
- **AIfalse** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_ai_false"`
- [x] 查询计算机当前活跃度 [身体检查]
- [x] 清理缓存

View File

@@ -94,7 +94,6 @@ func (m *Control) IsEnabledIn(gid int64) bool {
m.RLock()
err = db.Find(m.service, &c, "WHERE gid = "+strconv.FormatInt(gid, 10))
m.RUnlock()
logrus.Debugln("[control] db find gid =", c.GroupID)
if err == nil && gid == c.GroupID {
logrus.Debugf("[control] plugin %s of grp %d : %d", m.service, c.GroupID, c.Disable)
return c.Disable == 0
@@ -103,7 +102,7 @@ func (m *Control) IsEnabledIn(gid int64) bool {
m.RLock()
err = db.Find(m.service, &c, "WHERE gid = 0")
m.RUnlock()
if err == nil {
if err == nil && c.GroupID == 0 {
logrus.Debugf("[control] plugin %s of all : %d", m.service, c.Disable)
return c.Disable == 0
}
@@ -178,6 +177,7 @@ func init() {
service, ok := Lookup(model.Args)
if !ok {
ctx.SendChain(message.Text("没有找到指定服务!"))
return
}
grp := ctx.Event.GroupID
if grp == 0 {
@@ -202,6 +202,7 @@ func init() {
service, ok := Lookup(model.Args)
if !ok {
ctx.SendChain(message.Text("没有找到指定服务!"))
return
}
grp := ctx.Event.GroupID
if grp == 0 {
@@ -219,6 +220,7 @@ func init() {
service, ok := Lookup(model.Args)
if !ok {
ctx.SendChain(message.Text("没有找到指定服务!"))
return
}
if service.options.Help != "" {
ctx.SendChain(message.Text(service.options.Help))

4
go.mod
View File

@@ -6,10 +6,11 @@ require (
github.com/FloatTech/AnimeAPI v1.1.10
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.4
github.com/FloatTech/bot-manager v1.0.1-0.20211112011524-85b9895271ed
github.com/corona10/goimagehash v1.0.3
github.com/fogleman/gg v1.3.0
github.com/fumiama/cron v1.3.0
github.com/fumiama/go-base16384 v1.2.1
github.com/fumiama/gofastTEA v0.0.3
github.com/fumiama/gofastTEA v0.0.5
github.com/fumiama/gotracemoe v0.0.3
github.com/gin-gonic/gin v1.7.5
github.com/golang/protobuf v1.5.2
@@ -22,4 +23,5 @@ require (
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816
github.com/tidwall/gjson v1.11.0
github.com/wdvxdr1123/ZeroBot v1.4.1
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
)

8
go.sum
View File

@@ -19,6 +19,8 @@ github.com/antchfx/htmlquery v1.2.3 h1:sP3NFDneHx2stfNXCKbhHFo8XgNjCACnU/4AO5gWz
github.com/antchfx/htmlquery v1.2.3/go.mod h1:B0ABL+F5irhhMWg54ymEZinzMSi0Kt3I2if0BLYa3V0=
github.com/antchfx/xpath v1.1.6 h1:6sVh6hB5T6phw1pFpHRQ+C4bd8sNI+O58flqtg7h0R0=
github.com/antchfx/xpath v1.1.6/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/corona10/goimagehash v1.0.3 h1:NZM518aKLmoNluluhfHGxT3LGOnrojrxhGn63DR/CZA=
github.com/corona10/goimagehash v1.0.3/go.mod h1:VkvE0mLn84L4aF8vCb6mafVajEb6QYMHl2ZJLn0mOGI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -39,8 +41,8 @@ github.com/fumiama/cron v1.3.0 h1:ZWlwuexF+HQHl3cYytEE5HNwD99q+3vNZF1GrEiXCFo=
github.com/fumiama/cron v1.3.0/go.mod h1:bz5Izvgi/xEUI8tlBN8BI2jr9Moo8N4or0KV8xXuPDY=
github.com/fumiama/go-base16384 v1.2.1 h1:6OGprW8g/95m2ocmryHi8mipZ7bx9StFMZDKEqLvMiA=
github.com/fumiama/go-base16384 v1.2.1/go.mod h1:1HTC0QFL7BjS0DuO5Qm+fBYKQkHqmAapLbRpCxrhPXQ=
github.com/fumiama/gofastTEA v0.0.3 h1:JKcNktWArLkJe88Y+zGmsQGhqlh8IzYqUnWy2ipylh0=
github.com/fumiama/gofastTEA v0.0.3/go.mod h1:+sBZ05nCA2skZkursHNvyr8kULlEetrYTM2y5kA4rQc=
github.com/fumiama/gofastTEA v0.0.5 h1:Pd/2eSfLl2V0CqZL8pnu1CIU8Fy4HYpLutpliXU70Ds=
github.com/fumiama/gofastTEA v0.0.5/go.mod h1:+sBZ05nCA2skZkursHNvyr8kULlEetrYTM2y5kA4rQc=
github.com/fumiama/gotracemoe v0.0.3 h1:iI5EbE9A3UUbfukG6+/soYPjp1S31eCNYf4tw7s6/Jc=
github.com/fumiama/gotracemoe v0.0.3/go.mod h1:tyqahdUzHf0bQIAVY/GYmDWvYYe5ik1ZbhnGYh+zl40=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
@@ -110,6 +112,8 @@ github.com/modern-go/reflect2 v1.0.2-0.20210109003243-333559e1834b h1:6Xjqolv/0D
github.com/modern-go/reflect2 v1.0.2-0.20210109003243-333559e1834b/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mroth/weightedrand v0.4.1 h1:rHcbUBopmi/3x4nnrvwGJBhX9d0vk+KgoLUZeDP6YyI=
github.com/mroth/weightedrand v0.4.1/go.mod h1:3p2SIcC8al1YMzGhAIoXD+r9olo/g/cdJgAD905gyNE=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=

View File

@@ -26,12 +26,14 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_translation" // 翻译
// 娱乐类
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin_wtf" // 鬼东西
_ "github.com/FloatTech/ZeroBot-Plugin-Gif" // 制图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_ai_false" // 服务器监控
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_choose" // 选择困难症帮手
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_fortune" // 运势
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_hs" // 炉石
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_minecraft" // MCSManager
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_moyu" // 摸鱼
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_music" // 点歌
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_omikuji" // 浅草寺求签
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_reborn" // 投胎
@@ -46,6 +48,7 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_aiwife" // 随机老婆
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_image_finder" // 关键字搜图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_lolicon" // lolicon 随机图片
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_nativesetu" // 本地涩图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_saucenao" // 以图搜图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_setutime" // 来份涩图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_tracemoe" // 搜番
@@ -61,7 +64,7 @@ import (
var (
contents = []string{
"* OneBot + ZeroBot + Golang",
"* Version 1.2.0 - 2021-10-29 13:08:45 +0800 CST",
"* Version 1.2.1 - 2021-11-29 20:27:37 +0800 CST",
"* Copyright © 2020 - 2021 FloatTech. All Rights Reserved.",
"* Project: https://github.com/FloatTech/ZeroBot-Plugin",
}

View File

@@ -62,18 +62,6 @@ func init() {
})
}
// Slice is the runtime representation of a slice.
// It cannot be used safely or portably and its representation may
// change in a later release.
//
// Unlike reflect.SliceHeader, its Data field is sufficient to guarantee the
// data it references will not be garbage collected.
type slice struct {
Data unsafe.Pointer
Len int
Cap int
}
func getea(key string) tea.TEA {
kr := []rune(key)
if len(kr) > 4 {
@@ -83,8 +71,5 @@ func getea(key string) tea.TEA {
kr = append(kr, rune(4-len(kr)))
}
}
skr := *(*slice)(unsafe.Pointer(&kr))
skr.Len *= 4
skr.Cap *= 4
return tea.NewTeaCipher(*(*[]byte)(unsafe.Pointer(&skr)))
return *(*tea.TEA)(*(*unsafe.Pointer)(unsafe.Pointer(&kr)))
}

View File

@@ -5,6 +5,7 @@ import (
"net/http"
"time"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/fumiama/cron"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
@@ -23,88 +24,128 @@ type follower struct {
// 开启日报推送
func init() {
engine.OnFullMatch("/开启粉丝日报", zero.AdminPermission).SetBlock(true).
fansDaily()
en := control.Register("fansdaily", &control.Options{
DisableOnDefault: true,
Help: "fansdaily\n- /开启粉丝日报\n- /关闭粉丝日报",
})
zero.OnCommand("开启粉丝日报", zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
fansDaily(ctx.Event.GroupID) // 群号传进去给下面发信息的函数
m, ok := control.Lookup("fansdaily")
if ok {
if m.IsEnabledIn(ctx.Event.GroupID) {
ctx.Send(message.Text("已启用!"))
} else {
m.Enable(ctx.Event.GroupID)
ctx.Send(message.Text("添加成功!"))
}
} else {
ctx.Send(message.Text("找不到该服务!"))
}
})
en.OnCommand("关闭粉丝日报", zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
m, ok := control.Lookup("fansdaily")
if ok {
if m.IsEnabledIn(ctx.Event.GroupID) {
m.Disable(ctx.Event.GroupID)
ctx.Send(message.Text("关闭成功!"))
} else {
ctx.Send(message.Text("未启用!"))
}
} else {
ctx.Send(message.Text("找不到该服务!"))
}
})
}
// 定时任务每天晚上最后2分钟执行一次
func fansDaily(groupID int64) {
func fansDaily() {
c := cron.New()
_, err := c.AddFunc("58 23 * * *", func() { fansData(groupID) })
_, err := c.AddFunc("58 23 * * *", func() { sendNotice() })
if err == nil {
c.Start()
}
}
// 获取数据拼接消息链并发送
func fansData(groupID int64) {
// TODO: 更改为 GetBot
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
var (
diana = fansapi("672328094")
ava = fansapi("672346917")
eileen = fansapi("672342685")
bella = fansapi("672353429")
carol = fansapi("351609538")
)
ctx.SendGroupMessage(
groupID,
message.Text(
time.Now().Format("2006-01-02"), " Asoul全团粉丝日报如下", "\n\n",
"uid: ", diana.Mid, "\n",
"名字: ", diana.Uname, "\n",
"当前粉丝数: ", diana.Follower, "\n",
"今日涨粉数: ", diana.Rise, "\n",
"视频投稿数: ", diana.Video, "\n",
"直播间id: ", diana.Roomid, "\n",
"舰队: ", diana.GuardNum, "\n",
"直播总排名: ", diana.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672328094", "\n\n",
func getMsg() message.MessageSegment {
var (
diana = fansapi("672328094")
ava = fansapi("672346917")
eileen = fansapi("672342685")
bella = fansapi("672353429")
carol = fansapi("351609538")
)
return message.Text(
time.Now().Format("2006-01-02"), " Asoul全团粉丝日报如下", "\n\n",
"uid: ", diana.Mid, "\n",
"名字: ", diana.Uname, "\n",
"当前粉丝数: ", diana.Follower, "\n",
"今日涨粉数: ", diana.Rise, "\n",
"视频投稿数: ", diana.Video, "\n",
"直播间id: ", diana.Roomid, "\n",
"舰队: ", diana.GuardNum, "\n",
"直播总排名: ", diana.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672328094", "\n\n",
"uid: ", ava.Mid, "\n",
"名字: ", ava.Uname, "\n",
"当前粉丝数: ", ava.Follower, "\n",
"今日涨粉数: ", ava.Rise, "\n",
"视频投稿数: ", ava.Video, "\n",
"直播间id: ", ava.Roomid, "\n",
"舰队: ", ava.GuardNum, "\n",
"直播总排名: ", ava.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672346917", "\n\n",
"uid: ", ava.Mid, "\n",
"名字: ", ava.Uname, "\n",
"当前粉丝数: ", ava.Follower, "\n",
"今日涨粉数: ", ava.Rise, "\n",
"视频投稿数: ", ava.Video, "\n",
"直播间id: ", ava.Roomid, "\n",
"舰队: ", ava.GuardNum, "\n",
"直播总排名: ", ava.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672346917", "\n\n",
"uid: ", eileen.Mid, "\n",
"名字: ", eileen.Uname, "\n",
"当前粉丝数: ", eileen.Follower, "\n",
"今日涨粉数: ", eileen.Rise, "\n",
"视频投稿数: ", eileen.Video, "\n",
"直播间id: ", eileen.Roomid, "\n",
"舰队: ", eileen.GuardNum, "\n",
"直播总排名: ", eileen.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672342685", "\n\n",
"uid: ", eileen.Mid, "\n",
"名字: ", eileen.Uname, "\n",
"当前粉丝数: ", eileen.Follower, "\n",
"今日涨粉数: ", eileen.Rise, "\n",
"视频投稿数: ", eileen.Video, "\n",
"直播间id: ", eileen.Roomid, "\n",
"舰队: ", eileen.GuardNum, "\n",
"直播总排名: ", eileen.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672342685", "\n\n",
"uid: ", bella.Mid, "\n",
"名字: ", bella.Uname, "\n",
"当前粉丝数: ", bella.Follower, "\n",
"今日涨粉数: ", bella.Rise, "\n",
"视频投稿数: ", bella.Video, "\n",
"直播间id: ", bella.Roomid, "\n",
"舰队: ", bella.GuardNum, "\n",
"直播总排名: ", bella.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672353429", "\n\n",
"uid: ", bella.Mid, "\n",
"名字: ", bella.Uname, "\n",
"当前粉丝数: ", bella.Follower, "\n",
"今日涨粉数: ", bella.Rise, "\n",
"视频投稿数: ", bella.Video, "\n",
"直播间id: ", bella.Roomid, "\n",
"舰队: ", bella.GuardNum, "\n",
"直播总排名: ", bella.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672353429", "\n\n",
"uid: ", carol.Mid, "\n",
"名字: ", carol.Uname, "\n",
"当前粉丝数: ", carol.Follower, "\n",
"今日涨粉数: ", carol.Rise, "\n",
"视频投稿数: ", carol.Video, "\n",
"直播间id: ", carol.Roomid, "\n",
"舰队: ", carol.GuardNum, "\n",
"直播总排名: ", carol.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "351609538",
))
return true
})
"uid: ", carol.Mid, "\n",
"名字: ", carol.Uname, "\n",
"当前粉丝数: ", carol.Follower, "\n",
"今日涨粉数: ", carol.Rise, "\n",
"视频投稿数: ", carol.Video, "\n",
"直播间id: ", carol.Roomid, "\n",
"舰队: ", carol.GuardNum, "\n",
"直播总排名: ", carol.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "351609538",
)
}
// 获取数据拼接消息链并发送
func sendNotice() {
m, ok := control.Lookup("fansdaily")
if ok {
msg := getMsg()
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
for _, g := range ctx.GetGroupList().Array() {
grp := g.Get("group_id").Int()
if m.IsEnabledIn(grp) {
ctx.SendGroupMessage(grp, msg)
}
}
return true
})
}
}
// 请求api

View File

@@ -16,8 +16,7 @@ var engine = control.Register("bilibili", &control.Options{
DisableOnDefault: false,
Help: "bilibili\n" +
"- >vup info [名字|uid]\n" +
"- >user info [名字|uid]\n" +
"- /开启粉丝日报",
"- >user info [名字|uid]",
})
// 查成分的

View File

@@ -69,9 +69,9 @@ func init() {
Handle(func(ctx *zero.Ctx) {
keyword := ctx.State["regex_matched"].([]string)[1]
soutujson := soutuapi(keyword)
pom1 := "https://i.pixiv.cat"
pom1 := "https://i.pixiv.re"
rannum := randintn(len(soutujson.Illusts))
pom2 := soutujson.Illusts[rannum].ImageUrls.Large[19:]
pom2 := soutujson.Illusts[rannum].ImageUrls.Medium[19:]
ctx.SendChain(message.Image(pom1 + pom2))
})
}

View File

@@ -2,6 +2,7 @@ package moyu
import (
"fmt"
"strconv"
"time"
)
@@ -20,7 +21,7 @@ func NewHoliday(name string, dur, year int, month time.Month, day int) *holiday
func (h *holiday) String() string {
d := time.Until(h.date)
if d >= 0 {
return "距离" + h.name + "还有: " + d.String()
return "距离" + h.name + "还有: " + strconv.FormatFloat(d.Hours()/24.0, 'f', 2, 64) + "天!"
} else if d+h.dur >= 0 {
return "好好享受 " + h.name + " 假期吧!"
} else {

View File

@@ -13,8 +13,8 @@ import (
func init() { // 插件主体
// 定时任务每天10点执行一次
c := cron.New()
_, err := c.AddFunc("0 0 10 * * ?", func() { sendNotice() })
if err != nil {
_, err := c.AddFunc("0 10 * * *", func() { sendNotice() })
if err == nil {
c.Start()
}
@@ -65,8 +65,7 @@ func sendNotice() {
ctx.SendGroupMessage(grp,
[]message.MessageSegment{
message.Text(time.Now().Format("2006-01-02")),
message.Text("上午好,摸鱼人!\n工作再累一定不要忘记摸鱼哦有事没事起身去茶水间去厕所去廊道走走别老在工位上坐着钱是老板的,但命是自己的。"),
message.Text("\n"),
message.Text("上午好,摸鱼人!\n工作再累一定不要忘记摸鱼哦有事没事起身去茶水间去厕所去廊道走走别老在工位上坐着钱是老板的,但命是自己的。\n"),
message.Text(weekend()),
message.Text("\n"),
message.Text(NewHoliday("元旦", 1, 2022, 1, 1)),
@@ -83,7 +82,7 @@ func sendNotice() {
message.Text("\n"),
message.Text(NewHoliday("国庆节", 7, 2022, 10, 1)),
message.Text("\n"),
message.Text("\n\n上班是帮老板赚钱,摸鱼是赚老板的钱!最后,祝愿天下所有摸鱼人,都能愉快的渡过每一天…"),
message.Text("上班是帮老板赚钱,摸鱼是赚老板的钱!最后,祝愿天下所有摸鱼人,都能愉快的渡过每一天…"),
},
)
}

131
plugin_nativesetu/data.go Normal file
View File

@@ -0,0 +1,131 @@
package nativesetu
import (
"bytes"
"image"
"io"
"io/fs"
"os"
"sync"
"github.com/corona10/goimagehash"
"github.com/sirupsen/logrus"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"golang.org/x/image/webp"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
)
// setuclass holds setus in a folder, which is the class name.
type setuclass struct {
ImgID int64 `db:"imgid"` // ImgID 图片唯一 id (dhash)
Name string `db:"name"` // Name 图片名
Path string `db:"path"` // Path 图片路径
}
var (
setuclasses []string
db = &sql.Sqlite{DBPath: dbfile}
mu sync.RWMutex
)
func init() {
go func() {
process.SleepAbout1sTo2s()
err := os.MkdirAll(datapath, 0755)
if err != nil {
panic(err)
}
if file.IsExist(cfgfile) {
b, err := os.ReadFile(cfgfile)
if err == nil {
setupath = helper.BytesToString(b)
logrus.Println("[nsetu] set setu dir to", setupath)
}
}
if file.IsExist(dbfile) {
err := db.Open()
if err == nil {
setuclasses, err = db.ListTables()
}
if err != nil {
logrus.Errorln("[nsetu]", err)
}
}
}()
}
func scanall(path string) error {
setuclasses = nil
model := &setuclass{}
root := os.DirFS(path)
_ = db.Close()
_ = os.Remove(dbfile)
return fs.WalkDir(root, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
clsn := d.Name()
if clsn != "." {
mu.Lock()
err = db.Create(clsn, model)
setuclasses = append(setuclasses, clsn)
mu.Unlock()
if err == nil {
err = scanclass(root, path, clsn)
if err != nil {
logrus.Errorln("[nsetu]", err)
return err
}
}
}
}
return nil
})
}
func scanclass(root fs.FS, path, clsn string) error {
ds, err := fs.ReadDir(root, path)
if err != nil {
return err
}
mu.Lock()
_ = db.Truncate(clsn)
mu.Unlock()
for _, d := range ds {
if !d.IsDir() {
relpath := path + "/" + d.Name()
fullpath := setupath + "/" + relpath
logrus.Debugln("[nsetu] read", fullpath)
f, e := os.ReadFile(fullpath)
if e != nil {
return e
}
b := bytes.NewReader(f)
img, _, e := image.Decode(b)
if e != nil {
b.Seek(0, io.SeekStart)
img, e = webp.Decode(b)
}
if e != nil {
return e
}
dh, e := goimagehash.DifferenceHash(img)
if e != nil {
return e
}
dhi := int64(dh.GetHash())
logrus.Debugln("[nsetu] insert", d.Name(), "with id", dhi, "into", clsn)
mu.Lock()
err = db.Insert(clsn, &setuclass{ImgID: dhi, Name: d.Name(), Path: relpath})
mu.Unlock()
if err != nil {
return err
}
}
}
return nil
}

94
plugin_nativesetu/main.go Normal file
View File

@@ -0,0 +1,94 @@
package nativesetu
import (
"fmt"
"os"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/rule"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
)
const (
datapath = "data/nsetu"
dbfile = datapath + "/data.db"
cfgfile = datapath + "/setupath.txt"
)
var (
setupath = "/tmp" // 绝对路径,图片根目录
)
func init() {
engine := control.Register("nativesetu", &control.Options{
DisableOnDefault: false,
Help: "本地涩图\n" +
"- 本地[xxx]\n" +
"- 刷新本地[xxx]\n" +
"- 设置本地setu绝对路径[xxx]\n" +
"- 刷新所有本地setu\n" +
"- 所有本地setu分类",
})
engine.OnRegex(`^本地(.*)$`, func(ctx *zero.Ctx) bool { return rule.FirstValueInList(setuclasses)(ctx) }).SetBlock(true).SetPriority(36).
Handle(func(ctx *zero.Ctx) {
imgtype := ctx.State["regex_matched"].([]string)[1]
sc := new(setuclass)
mu.RLock()
err := db.Pick(imgtype, sc)
mu.RUnlock()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
} else {
p := "file:///" + setupath + "/" + sc.Path
ctx.SendChain(message.Text(imgtype, ": ", sc.Name, "\n"), message.Image(p))
}
})
engine.OnRegex(`^刷新本地(.*)$`, func(ctx *zero.Ctx) bool { return rule.FirstValueInList(setuclasses)(ctx) }, zero.SuperUserPermission).SetBlock(true).SetPriority(36).
Handle(func(ctx *zero.Ctx) {
imgtype := ctx.State["regex_matched"].([]string)[1]
err := scanclass(os.DirFS(setupath), imgtype, imgtype)
if err == nil {
ctx.SendChain(message.Text("成功!"))
} else {
ctx.SendChain(message.Text("ERROR: ", err))
}
})
engine.OnRegex(`^设置本地setu绝对路径(.*)$`, zero.SuperUserPermission).SetBlock(true).SetPriority(36).
Handle(func(ctx *zero.Ctx) {
setupath = ctx.State["regex_matched"].([]string)[1]
err := os.WriteFile(cfgfile, helper.StringToBytes(setupath), 0644)
if err == nil {
ctx.SendChain(message.Text("成功!"))
} else {
ctx.SendChain(message.Text("ERROR: ", err))
}
})
engine.OnFullMatch("刷新所有本地setu", zero.SuperUserPermission).SetBlock(true).SetPriority(36).
Handle(func(ctx *zero.Ctx) {
err := scanall(setupath)
if err == nil {
ctx.SendChain(message.Text("成功!"))
} else {
ctx.SendChain(message.Text("ERROR: ", err))
}
})
engine.OnFullMatch("所有本地setu分类").SetBlock(true).SetPriority(36).
Handle(func(ctx *zero.Ctx) {
msg := "所有本地setu分类"
mu.RLock()
for i, c := range setuclasses {
n, err := db.Count(c)
if err == nil {
msg += fmt.Sprintf("\n%02d. %s(%d)", i, c, n)
} else {
msg += fmt.Sprintf("\n%02d. %s(error)", i, c)
logrus.Errorln("[nsetu]", err)
}
}
mu.RUnlock()
ctx.SendChain(message.Text(msg))
})
}

View File

@@ -21,7 +21,7 @@ import (
)
var (
prio = 100
prio = 256
bucket = rate.NewManager(time.Minute, 20) // 青云客接口回复
engine *zero.Engine
)

View File

@@ -20,6 +20,7 @@ import (
"github.com/FloatTech/ZeroBot-Plugin/control"
fileutil "github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
"github.com/FloatTech/ZeroBot-Plugin/utils/rule"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
)
@@ -112,7 +113,7 @@ func init() { // 插件主体
"- 删除[涩图/二次元/风景/车万][P站图片ID]\n" +
"- >setu status",
})
engine.OnRegex(`^来份(.*)$`, firstValueInList(pool.List)).SetBlock(true).SetPriority(20).
engine.OnRegex(`^来份(.*)$`, rule.FirstValueInList(pool.List)).SetBlock(true).SetPriority(20).
Handle(func(ctx *zero.Ctx) {
if !limit.Load(ctx.Event.UserID).Acquire() {
ctx.SendChain(message.Text("请稍后重试0x0..."))
@@ -125,7 +126,7 @@ func init() { // 插件主体
for i := 0; i < times; i++ {
illust := &pixiv.Illust{}
// 查询出一张图片
if err := pool.DB.Find(imgtype, illust, "ORDER BY RANDOM() limit 1"); err != nil {
if err := pool.DB.Pick(imgtype, illust); err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
continue
}
@@ -155,7 +156,7 @@ func init() { // 插件主体
}
})
engine.OnRegex(`^添加(.*?)(\d+)$`, firstValueInList(pool.List), zero.SuperUserPermission).SetBlock(true).SetPriority(21).
engine.OnRegex(`^添加(.*?)(\d+)$`, rule.FirstValueInList(pool.List), zero.SuperUserPermission).SetBlock(true).SetPriority(21).
Handle(func(ctx *zero.Ctx) {
var (
imgtype = ctx.State["regex_matched"].([]string)[1]
@@ -186,7 +187,7 @@ func init() { // 插件主体
ctx.SendChain(message.Text("添加成功"))
})
engine.OnRegex(`^删除(.*?)(\d+)$`, firstValueInList(pool.List), zero.SuperUserPermission).SetBlock(true).SetPriority(22).
engine.OnRegex(`^删除(.*?)(\d+)$`, rule.FirstValueInList(pool.List), zero.SuperUserPermission).SetBlock(true).SetPriority(22).
Handle(func(ctx *zero.Ctx) {
var (
imgtype = ctx.State["regex_matched"].([]string)[1]
@@ -218,19 +219,6 @@ func init() { // 插件主体
})
}
// firstValueInList 判断正则匹配的第一个参数是否在列表中
func firstValueInList(list []string) zero.Rule {
return func(ctx *zero.Ctx) bool {
first := ctx.State["regex_matched"].([]string)[1]
for i := range list {
if first == list[i] {
return true
}
}
return false
}
}
// size 返回缓冲池指定类型的现有大小
func (p *imgpool) size(imgtype string) int {
return len(p.Pool[imgtype])

View File

@@ -28,7 +28,7 @@ func vtbDaily() {
}
func vtbData() {
db := model.Init(dbpath)
db := model.Initialize(dbfile)
if db != nil {
for _, v := range db.GetVtbList() {
db.StoreVtb(v)

View File

@@ -7,30 +7,36 @@ import (
"os"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
)
const pburl = "https://codechina.csdn.net/u011570312/ZeroBot-Plugin/-/raw/master/" + dbpath
const pburl = "https://codechina.csdn.net/u011570312/ZeroBot-Plugin/-/raw/master/" + dbfile
// 加载数据库
func init() {
if !file.IsExist(dbpath) { // 如果没有数据库,则从 url 下载
f, err := os.Create(dbpath)
if err != nil {
panic(err)
}
defer f.Close()
resp, err := http.Get(pburl)
if err == nil {
defer resp.Body.Close()
if resp.ContentLength > 0 {
log.Printf("[vtb]从镜像下载数据库%d字节...", resp.ContentLength)
data, err := io.ReadAll(resp.Body)
if err == nil && len(data) > 0 {
_, _ = f.Write(data)
}
go func() {
process.SleepAbout1sTo2s()
_ = os.MkdirAll(dbpath, 0755)
if !file.IsExist(dbfile) { // 如果没有数据库,则从 url 下载
f, err := os.Create(dbfile)
if err != nil {
panic(err)
}
defer f.Close()
resp, err := http.Get(pburl)
if err == nil {
defer resp.Body.Close()
if resp.ContentLength > 0 {
log.Printf("[vtb]从镜像下载数据库%d字节...", resp.ContentLength)
data, err := io.ReadAll(resp.Body)
if err == nil && len(data) > 0 {
_, _ = f.Write(data)
return
}
panic(err)
}
}
panic(err)
}
panic(err)
}
}()
}

View File

@@ -8,7 +8,6 @@ import (
"strconv"
"strings"
"time"
"unsafe"
"github.com/jinzhu/gorm"
_ "github.com/logoove/sqlite"
@@ -18,7 +17,7 @@ import (
type VtbDB gorm.DB
func Init(dbpath string) *VtbDB {
func Initialize(dbpath string) *VtbDB {
var err error
if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) {
// 生成文件
@@ -33,7 +32,7 @@ func Init(dbpath string) *VtbDB {
panic(err)
}
gdb.AutoMigrate(FirstCategory{}).AutoMigrate(SecondCategory{}).AutoMigrate(ThirdCategory{})
return (*VtbDB)(unsafe.Pointer(gdb))
return (*VtbDB)(gdb)
}
func Open(dbpath string) (*VtbDB, error) {
@@ -41,7 +40,7 @@ func Open(dbpath string) (*VtbDB, error) {
if err != nil {
return nil, err
} else {
return (*VtbDB)(unsafe.Pointer(db)), nil
return (*VtbDB)(db), nil
}
}
@@ -91,7 +90,7 @@ func (ThirdCategory) TableName() string {
// GetAllFirstCategoryMessage 取出所有vtb
func (vdb *VtbDB) GetAllFirstCategoryMessage() string {
db := (*gorm.DB)(unsafe.Pointer(vdb))
db := (*gorm.DB)(vdb)
firstStepMessage := "请选择一个vtb并发送序号:\n"
var fc FirstCategory
rows, err := db.Model(&FirstCategory{}).Rows()
@@ -111,7 +110,7 @@ func (vdb *VtbDB) GetAllFirstCategoryMessage() string {
// GetAllSecondCategoryMessageByFirstIndex 取得同一个vtb所有语录类别
func (vdb *VtbDB) GetAllSecondCategoryMessageByFirstIndex(firstIndex int) string {
db := (*gorm.DB)(unsafe.Pointer(vdb))
db := (*gorm.DB)(vdb)
SecondStepMessage := "请选择一个语录类别并发送序号:\n"
var sc SecondCategory
var count int
@@ -136,7 +135,7 @@ func (vdb *VtbDB) GetAllSecondCategoryMessageByFirstIndex(firstIndex int) string
// GetAllThirdCategoryMessageByFirstIndexAndSecondIndex 取得同一个vtb同个类别的所有语录
func (vdb *VtbDB) GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(firstIndex, secondIndex int) string {
db := (*gorm.DB)(unsafe.Pointer(vdb))
db := (*gorm.DB)(vdb)
ThirdStepMessage := "请选择一个语录并发送序号:\n"
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc)
@@ -160,7 +159,7 @@ func (vdb *VtbDB) GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(firstInde
// GetThirdCategory
func (vdb *VtbDB) GetThirdCategory(firstIndex, secondIndex, thirdIndex int) ThirdCategory {
db := (*gorm.DB)(unsafe.Pointer(vdb))
db := (*gorm.DB)(vdb)
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc)
var tc ThirdCategory
@@ -169,7 +168,7 @@ func (vdb *VtbDB) GetThirdCategory(firstIndex, secondIndex, thirdIndex int) Thir
}
func (vdb *VtbDB) RandomVtb() ThirdCategory {
db := (*gorm.DB)(unsafe.Pointer(vdb))
db := (*gorm.DB)(vdb)
rand.Seed(time.Now().UnixNano())
var count int
db.Model(&ThirdCategory{}).Count(&count)
@@ -181,7 +180,7 @@ func (vdb *VtbDB) RandomVtb() ThirdCategory {
}
func (vdb *VtbDB) GetFirstCategoryByFirstUid(firstUid string) FirstCategory {
db := (*gorm.DB)(unsafe.Pointer(vdb))
db := (*gorm.DB)(vdb)
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_uid = ?", firstUid).Take(&fc)
// logrus.Info(fc)
@@ -189,14 +188,14 @@ func (vdb *VtbDB) GetFirstCategoryByFirstUid(firstUid string) FirstCategory {
}
func (vdb *VtbDB) Close() error {
db := (*gorm.DB)(unsafe.Pointer(vdb))
db := (*gorm.DB)(vdb)
return db.Close()
}
const vtbUrl = "https://vtbkeyboard.moe/api/get_vtb_list"
func (vdb *VtbDB) GetVtbList() []string {
db := (*gorm.DB)(unsafe.Pointer(vdb))
db := (*gorm.DB)(vdb)
client := &http.Client{}
req, err := http.NewRequest("GET", vtbUrl, nil)
if err != nil {
@@ -256,7 +255,7 @@ func (vdb *VtbDB) GetVtbList() []string {
}
func (vdb *VtbDB) StoreVtb(uid string) {
db := (*gorm.DB)(unsafe.Pointer(vdb))
db := (*gorm.DB)(vdb)
vtbUrl := "https://vtbkeyboard.moe/api/get_vtb_page?uid=" + uid
client := &http.Client{}
req, err := http.NewRequest("GET", vtbUrl, nil)

View File

@@ -17,7 +17,8 @@ import (
)
const regStr = ".*/(.*)"
const dbpath = "data/VtbQuotation/vtb.db"
const dbpath = "data/VtbQuotation/"
const dbfile = dbpath + "vtb.db"
var engine = control.Register("vtbquotation", &control.Options{
DisableOnDefault: false,
@@ -33,7 +34,7 @@ func init() {
echo, cancel := ctx.FutureEvent("message",
ctx.CheckSession()). // 只复读开启复读模式的人的消息
Repeat() // 不断监听复读
db, err := model.Open(dbpath)
db, err := model.Open(dbfile)
if err != nil {
logrus.Errorln(err)
return
@@ -133,7 +134,7 @@ func init() {
})
engine.OnFullMatch("随机vtb").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
db, err := model.Open(dbpath)
db, err := model.Open(dbfile)
if err != nil {
logrus.Errorln(err)
return

72
plugin_wtf/main.go Normal file
View File

@@ -0,0 +1,72 @@
package wtf
import (
"fmt"
"strconv"
"time"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension/rate"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
)
var (
// 限制调用频率
limit = rate.NewManager(time.Minute*5, 5)
)
func init() {
en := control.Register("wtf", &control.Options{
DisableOnDefault: false,
Help: "鬼东西\n- 鬼东西列表\n- 查询鬼东西[序号][@xxx]",
})
en.OnFullMatch("鬼东西列表").SetBlock(true).SetPriority(30).
Handle(func(ctx *zero.Ctx) {
s := ""
for i, w := range table {
s += fmt.Sprintf("%02d. %s\n", i, w.name)
i++
}
ctx.SendChain(message.Text(s))
})
en.OnRegex(`^查询鬼东西(\d*)`).SetBlock(true).SetPriority(30).
Handle(func(ctx *zero.Ctx) {
if !limit.Load(ctx.Event.UserID).Acquire() {
ctx.SendChain(message.Text("请稍后重试0x0..."))
return
}
// 调用接口
i, err := strconv.Atoi(ctx.State["regex_matched"].([]string)[1])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
w := NewWtf(i)
if w == nil {
ctx.SendChain(message.Text("没有这项内容!"))
return
}
// 获取名字
var name string
var secondname string
if len(ctx.Event.Message) > 1 && ctx.Event.Message[1].Type == "at" {
qq, _ := strconv.ParseInt(ctx.Event.Message[1].Data["qq"], 10, 64)
secondname = ctx.GetGroupMemberInfo(ctx.Event.GroupID, qq, false).Get("nickname").Str
}
name = ctx.Event.Sender.NickName
var text string
if secondname != "" {
text, err = w.Predict(name, secondname)
} else {
text, err = w.Predict(name)
}
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
// TODO: 可注入
ctx.Send(text)
})
}

155
plugin_wtf/model.go Normal file
View File

@@ -0,0 +1,155 @@
package wtf
import (
"encoding/json"
"errors"
"io"
"net/http"
"net/url"
)
/* JS path getter for https://wtf.hiigara.net/ranking
a = document.getElementById("testList").getElementsByTagName("a")
s = ""
for(i=0; i<a.length; i++) {
s += "\"" + a[i].innerText + "\":\"" + a[i].href + "\",\n";
}
*/
const apiprefix = "https://wtf.hiigara.net/api/run/"
type Wtf struct {
name string
path string
}
var table = [...]*Wtf{
{"你的意义是什么?", "mRIFuS"},
{"【ABO】性別和信息素", "KXyy9"},
{"测测cp", "ZoGXQd"},
{"xxx和xxx的關係是", "L4HfA"},
{"在JOJO世界你的替身会是什么", "lj0a8o"},
{"稱號產生器", "titlegen"},
{"成分报告", "2PCeo1"},
{"測驗你跟你的朋友是攻/受", "LkQXO3"},
{"测试两人的关系?", "uwjQQt"},
{"【Fate系列】當你成為了從者 2.0", "LHStH2"},
{"想不到自己未來要做什麼工作嗎?", "D1agGa"},
{"(σ゚∀゚)σ名字產生器", "LNxXq7"},
{"人設生產器", "LBtPu5"},
{"測驗你在ABO世界的訊息素", "SwmdU"},
{"爱是什么", "llpBEY"},
{"測測你和哪位名人相似?", "RHQeXu"},
{"S/M测试", "Ga47oZ"},
{"测测你是谁", "aV1AEi"},
{"取個綽號吧", "LTkyUy"},
{"什麼都不是", "vyrSCb"},
{"今天中午吃什麼", "LdS4K6"},
{"測試你的中二稱號", "LwUmQ6"},
{"神奇海螺", "Lon1h7"},
{"ABO測試", "H1Tgd"},
{"女主角姓名產生器", "MsQBTd"},
{"您是什么人", "49PwSd"},
{"如果你成为了干员", "ok5e7n"},
{"abo人设生成~", "Di8enA"},
{"✡你的命運✡塔羅占卜🔮", "ohCzID"},
{"小說大綱生產器", "Lnstjz"},
{"他会喜欢你吗?", "pezX3a"},
{"抽签!你明年的今天会干什么", "IF31kS"},
{"如果你是受,會是哪種受呢?", "Dr6zpF"},
{"cp文梗", "vEO2KD"},
{"您是什么人?", "TQ5qyl"},
{"你成為......的機率", "g0uoBL"},
{"ABO性別與信息素", "KFPju"},
{"異國名稱產生器(國家、人名、星球...)", "OBpu4"},
{"對方到底喜不喜歡你", "JSLoZC"},
{"【脑叶公司】测一测你在脑叶公司的经历", "uPBhjC"},
{"当你成为魔法少女", "7ZiGcJ"},
{"你是yyds吗?", "SpBnCa"},
{"○○喜歡你嗎?", "S6Uceo"},
{"测测你的sm属性", "dOtcO5"},
{"你/妳究竟是攻還是受呢?", "RXALH"},
{"神秘藏书阁", "tDRyET"},
{"中午吃什么?", "L0Wsis"},
{"十年后你cp的结局是", "VUwnXQ"},
{"高维宇宙与常数的你", "6Zql97"},
{"色色的東東", "o2eg74"},
{"文章標題產生器", "Ky25WO"},
{"你的成績怎麼樣", "6kZv69"},
{"智能SM偵測器ヾ(*ΦωΦ)ツ", "9pY6HQ"},
{"你的使用注意事項", "La4Gir"},
{"戀愛指數", "Jsgz0"},
{"测试你今晚拉的屎", "N8dbcL"},
{"成為情侶的機率ᶫᵒᵛᵉᵧₒᵤ♥", "eDURch"},
{"他對你...", "CJxHMf"},
{"你的明日方舟人际关系", "u5z4Mw"},
{"日本姓氏產生器", "JJ5Ctb"},
{"當你轉生到了異世界,你將成為...", "FTpwK"},
{"魔幻世界大穿越2.0", "wUATOq"},
{"未來男朋友", "F3dSV"},
{"ABO與信息素", "KFOGA"},
{"你必將就這樣一事無成啊アホ", "RWw9oX"},
{"用習慣舉手的方式測試你的戀愛運!<3", "wv5bzA"},
{"攻受", "RaKmY"},
{"你和你喜歡的人的微h寵溺段子XD", "LdQqGz"},
{"我的藝名", "LBaTx"},
{"你是什麼神?", "LqZORE"},
{"你的起源是什麼?", "HXWwC"},
{"測你喜歡什麼", "Sue5g2"},
{"看看朋友的秘密", "PgKb8r"},
{"你在動漫裡的名字", "Lz82V7"},
{"小說男角名字產生器", "LyGDRr"},
{"測試短文", "S48yA"},
{"我們兩人在一起的機率......", "LBZbgE"},
{"創造小故事", "Kjy3AS"},
{"你的另外一個名字", "LuyYQA"},
{"與你最匹配的攻君屬性 ", "I7pxy"},
{"英文全名生產器(女)", "HcYbq"},
{"BL文章生產器", "LBZMO"},
{"輕小說書名產生器", "NFucA"},
{"長相評分", "2cQSDP"},
{"日本名字產生器(女孩子)", "JRiKv"},
{"中二技能名產生器", "Ky1BA"},
{"抽籤", "XqxfuH"},
{"你的蘿莉控程度全國排名", "IIWh9k"},
}
func NewWtf(index int) *Wtf {
if index >= 0 && index < len(table) {
return table[index]
}
return nil
}
type result struct {
Text string `json:"text"`
// Path string `json:"path"`
Ok bool `json:"ok"`
Msg string `json:"msg"`
}
func (w *Wtf) Predict(names ...string) (string, error) {
name := ""
for _, n := range names {
name += "/" + url.QueryEscape(n)
}
u := apiprefix + w.path + name
resp, err := http.Get(u)
if err != nil {
return "", err
}
r, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return "", err
}
re := new(result)
err = json.Unmarshal(r, re)
if err != nil {
return "", err
}
if re.Ok {
return "> " + w.name + "\n" + re.Text, nil
}
return "", errors.New(re.Msg)
}

16
utils/rule/extension.go Normal file
View File

@@ -0,0 +1,16 @@
package rule
import zero "github.com/wdvxdr1123/ZeroBot"
// FirstValueInList 判断正则匹配的第一个参数是否在列表中
func FirstValueInList(list []string) zero.Rule {
return func(ctx *zero.Ctx) bool {
first := ctx.State["regex_matched"].([]string)[1]
for _, v := range list {
if first == v {
return true
}
}
return false
}
}

View File

@@ -3,6 +3,7 @@ package sql
import (
"database/sql"
"errors"
"reflect"
"strings"
@@ -15,6 +16,27 @@ type Sqlite struct {
DBPath string
}
// Open 打开数据库
func (db *Sqlite) Open() (err error) {
if db.DB == nil {
database, err := sql.Open("sqlite3", db.DBPath)
if err != nil {
return err
}
db.DB = database
}
return
}
// Close 关闭数据库
func (db *Sqlite) Close() (err error) {
if db.DB != nil {
err = db.DB.Close()
db.DB = nil
}
return
}
// Create 生成数据库
// 默认结构体的第一个元素为主键
// 返回错误
@@ -56,7 +78,7 @@ func (db *Sqlite) Create(table string, objptr interface{}) (err error) {
// 默认结构体的第一个元素为主键
// 返回错误
func (db *Sqlite) Insert(table string, objptr interface{}) error {
rows, err := db.DB.Query("SELECT * FROM " + table + ";")
rows, err := db.DB.Query("SELECT * FROM " + table + " limit 1;")
if err != nil {
return err
}
@@ -66,9 +88,9 @@ func (db *Sqlite) Insert(table string, objptr interface{}) error {
tags, _ := rows.Columns()
rows.Close()
var (
values = values(objptr)
top = len(tags) - 1
cmd = []string{}
vals = values(objptr)
top = len(tags) - 1
cmd = []string{}
)
cmd = append(cmd, "REPLACE INTO")
cmd = append(cmd, table)
@@ -104,7 +126,7 @@ func (db *Sqlite) Insert(table string, objptr interface{}) error {
if err != nil {
return err
}
_, err = stmt.Exec(values...)
_, err = stmt.Exec(vals...)
if err != nil {
return err
}
@@ -129,16 +151,22 @@ func (db *Sqlite) Find(table string, objptr interface{}, condition string) error
}
defer rows.Close()
if !rows.Next() {
return errors.New("sql.Find: null result")
}
err = rows.Scan(addrs(objptr)...)
for rows.Next() {
if err != nil {
return err
}
err = rows.Scan(addrs(objptr)...)
if err != nil {
return err
}
}
return nil
return err
}
// Pick 从 table 随机一行
func (db *Sqlite) Pick(table string, objptr interface{}) error {
return db.Find(table, objptr, "ORDER BY RANDOM() limit 1")
}
// ListTables 列出所有表名
@@ -166,7 +194,7 @@ func (db *Sqlite) ListTables() (s []string, err error) {
return
}
// Del 删除数据库
// Del 删除数据库表项
// condition 可为"WHERE id = 0"
// 返回错误
func (db *Sqlite) Del(table string, condition string) error {
@@ -185,11 +213,27 @@ func (db *Sqlite) Del(table string, condition string) error {
return stmt.Close()
}
// Truncate 清空数据库表
func (db *Sqlite) Truncate(table string) error {
var cmd = []string{}
cmd = append(cmd, "TRUNCATE TABLE")
cmd = append(cmd, table)
stmt, err := db.DB.Prepare(strings.Join(cmd, " ") + ";")
if err != nil {
return err
}
_, err = stmt.Exec()
if err != nil {
return err
}
return stmt.Close()
}
// Count 查询数据库行数
// 返回行数以及错误
func (db *Sqlite) Count(table string) (num int, err error) {
var cmd = []string{}
cmd = append(cmd, "SELECT * FROM")
cmd = append(cmd, "SELECT COUNT(1) FROM")
cmd = append(cmd, table)
rows, err := db.DB.Query(strings.Join(cmd, " ") + ";")
if err != nil {
@@ -198,8 +242,8 @@ func (db *Sqlite) Count(table string) (num int, err error) {
if rows.Err() != nil {
return num, rows.Err()
}
for rows.Next() {
num++
if rows.Next() {
rows.Scan(&num)
}
rows.Close()
return num, nil
@@ -229,8 +273,22 @@ func kinds(objptr interface{}) []string {
}
for i, flen := 0, elem.Type().NumField(); i < flen; i++ {
switch elem.Field(i).Type().String() {
case "int64":
case "int8":
kinds = append(kinds, "TINYINT")
case "uint8", "byte":
kinds = append(kinds, "UNSIGNED TINYINT")
case "int16":
kinds = append(kinds, "SMALLINT")
case "uint16":
kinds = append(kinds, "UNSIGNED SMALLINT")
case "int32":
kinds = append(kinds, "INT")
case "uint32":
kinds = append(kinds, "UNSIGNED INT")
case "int64":
kinds = append(kinds, "BIGINT")
case "uint64":
kinds = append(kinds, "UNSIGNED BIGINT")
case "string":
kinds = append(kinds, "TEXT")
default:
@@ -249,14 +307,7 @@ func values(objptr interface{}) []interface{} {
elem = elem.Field(0)
}
for i, flen := 0, elem.Type().NumField(); i < flen; i++ {
switch elem.Field(i).Type().String() {
case "int64":
values = append(values, elem.Field(i).Int())
case "string":
values = append(values, elem.Field(i).String())
default:
values = append(values, elem.Field(i).String())
}
values = append(values, elem.Field(i).Interface())
}
return values
}