mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 22:00:11 +08:00
✨ 优化代码结构
This commit is contained in:
parent
ff4a33c51c
commit
cde7669c0b
15
README.md
15
README.md
@ -66,7 +66,7 @@ zerobot [-h] [-t token] [-u url] [-n nickname] [-p prefix] [-d|w] [-g 监听地
|
|||||||
- [x] /服务列表
|
- [x] /服务列表
|
||||||
- [x] /服务详情
|
- [x] /服务详情
|
||||||
- [x] @Bot 插件冲突检测 (会在本群发送一条消息并在约 1s 后撤回以检测其它同类 bot 中已启用的插件并禁用)
|
- [x] @Bot 插件冲突检测 (会在本群发送一条消息并在约 1s 后撤回以检测其它同类 bot 中已启用的插件并禁用)
|
||||||
- **定时指令触发器** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/job"`
|
- **定时指令触发器** `import _ "github.com/FloatTech/zbputils/job"`
|
||||||
- [x] 记录以"完全匹配关键词"触发的(代表我执行的)指令
|
- [x] 记录以"完全匹配关键词"触发的(代表我执行的)指令
|
||||||
- [x] 取消以"完全匹配关键词"触发的(代表我执行的)指令
|
- [x] 取消以"完全匹配关键词"触发的(代表我执行的)指令
|
||||||
- [x] 记录在"cron"触发的指令
|
- [x] 记录在"cron"触发的指令
|
||||||
@ -194,9 +194,17 @@ print("run[CQ:image,file="+j["img"]+"]")
|
|||||||
- **摸鱼** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu"`
|
- **摸鱼** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu"`
|
||||||
- [x] /启用 moyu
|
- [x] /启用 moyu
|
||||||
- [x] /禁用 moyu
|
- [x] /禁用 moyu
|
||||||
|
```
|
||||||
|
记录在"0 10 * * *"触发的指令
|
||||||
|
摸鱼提醒
|
||||||
|
```
|
||||||
- **摸鱼人日历** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu_calendar"`
|
- **摸鱼人日历** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu_calendar"`
|
||||||
- [x] /启用 moyucalendar
|
- [x] /启用 moyucalendar
|
||||||
- [x] /禁用 moyucalendar
|
- [x] /禁用 moyucalendar
|
||||||
|
```
|
||||||
|
记录在"30 8 * * *"触发的指令
|
||||||
|
摸鱼人日历
|
||||||
|
```
|
||||||
- **涩图** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/setutime"`
|
- **涩图** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/setutime"`
|
||||||
- [x] 来份[涩图/二次元/风景/车万]
|
- [x] 来份[涩图/二次元/风景/车万]
|
||||||
- [x] 添加[涩图/二次元/风景/车万][P站图片ID]
|
- [x] 添加[涩图/二次元/风景/车万][P站图片ID]
|
||||||
@ -349,9 +357,10 @@ print("run[CQ:image,file="+j["img"]+"]")
|
|||||||
- **城市疫情查询** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/epidemic"`
|
- **城市疫情查询** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/epidemic"`
|
||||||
- [x] xxx疫情
|
- [x] xxx疫情
|
||||||
- **早报** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/zaobao"`
|
- **早报** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/zaobao"`
|
||||||
> api早上8点更新,推荐定时在8点30后。配合插件`job`中的记录在"cron"触发的指令使用。
|
- api早上8点更新,推荐定时在8点30后。配合插件`job`中的记录在"cron"触发的指令使用
|
||||||
|
- [x] /启用 zaobao
|
||||||
|
- [x] /禁用 zaobao
|
||||||
```
|
```
|
||||||
/启用 zaobao
|
|
||||||
记录在"00 9 * * *"触发的指令
|
记录在"00 9 * * *"触发的指令
|
||||||
今日早报
|
今日早报
|
||||||
```
|
```
|
||||||
|
|||||||
4
go.mod
4
go.mod
@ -3,9 +3,9 @@ module github.com/FloatTech/ZeroBot-Plugin
|
|||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/FloatTech/AnimeAPI v1.3.1-0.20220311024222-ed58ddf6834e
|
github.com/FloatTech/AnimeAPI v1.3.1
|
||||||
github.com/FloatTech/sqlite v0.2.1
|
github.com/FloatTech/sqlite v0.2.1
|
||||||
github.com/FloatTech/zbputils v1.3.1-0.20220311032316-df8ab8b3c180
|
github.com/FloatTech/zbputils v1.3.1
|
||||||
github.com/antchfx/htmlquery v1.2.4
|
github.com/antchfx/htmlquery v1.2.4
|
||||||
github.com/corona10/goimagehash v1.0.3
|
github.com/corona10/goimagehash v1.0.3
|
||||||
github.com/fogleman/gg v1.3.0
|
github.com/fogleman/gg v1.3.0
|
||||||
|
|||||||
9
go.sum
9
go.sum
@ -1,11 +1,10 @@
|
|||||||
github.com/FloatTech/AnimeAPI v1.3.1-0.20220311024222-ed58ddf6834e h1:PKm/g1M7rYu6YMOV5k8xCOkgXTKF2Tk9v2exeYyCe+0=
|
github.com/FloatTech/AnimeAPI v1.3.1 h1:EBNz9pzfH5vYqs8HyME9AL3gXjO+iJ5DgWmqOfdNb18=
|
||||||
github.com/FloatTech/AnimeAPI v1.3.1-0.20220311024222-ed58ddf6834e/go.mod h1:JNF2O/RdbrsDIccSQ29a4g1pQRrZsN0Jh3ggFZYzZuY=
|
github.com/FloatTech/AnimeAPI v1.3.1/go.mod h1:rEBMdnN1yPKt9DdL/BRSRibp7jR1SQiLIaEeQ53R+dk=
|
||||||
github.com/FloatTech/bot-manager v1.0.0/go.mod h1:8YYRJ16oroGHQGD2En0oVnmcKJkxR9O/jd5BPSfWfOQ=
|
github.com/FloatTech/bot-manager v1.0.0/go.mod h1:8YYRJ16oroGHQGD2En0oVnmcKJkxR9O/jd5BPSfWfOQ=
|
||||||
github.com/FloatTech/sqlite v0.2.1 h1:9t6Me48XJJCIoPy4nLRvcdhcVKfT0c2lilp7SEKROG8=
|
github.com/FloatTech/sqlite v0.2.1 h1:9t6Me48XJJCIoPy4nLRvcdhcVKfT0c2lilp7SEKROG8=
|
||||||
github.com/FloatTech/sqlite v0.2.1/go.mod h1:6NfHRzqOo9RWeMJEoAQVuo51Omd5LFNxCNQhMF02/9U=
|
github.com/FloatTech/sqlite v0.2.1/go.mod h1:6NfHRzqOo9RWeMJEoAQVuo51Omd5LFNxCNQhMF02/9U=
|
||||||
github.com/FloatTech/zbputils v1.3.1-0.20220307143543-1139754cacdf/go.mod h1:u+PiX1khNvtAgfRVTVP4hkA2oUnn5q5dTZSk1Cgp0Gw=
|
github.com/FloatTech/zbputils v1.3.1 h1:ZdK5vkjdtDoeB83FoPAd+vIRmKdILeDSsLLiDIdanVI=
|
||||||
github.com/FloatTech/zbputils v1.3.1-0.20220311032316-df8ab8b3c180 h1:8tE9DYu0+YMk3oKeO0ffl80818ZrPM9afbRgb2ag0tQ=
|
github.com/FloatTech/zbputils v1.3.1/go.mod h1:ByNutpHjwyrhaxo54dRjJDEppko0Fcot2iOv7WrIDUg=
|
||||||
github.com/FloatTech/zbputils v1.3.1-0.20220311032316-df8ab8b3c180/go.mod h1:u+PiX1khNvtAgfRVTVP4hkA2oUnn5q5dTZSk1Cgp0Gw=
|
|
||||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc h1:AAx50/fb/xS4lvsdQg+bFbGvqSDhyV1MF+p2PLCamZ0=
|
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc h1:AAx50/fb/xS4lvsdQg+bFbGvqSDhyV1MF+p2PLCamZ0=
|
||||||
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc/go.mod h1:OMmITAib6POA37xCichWM0aRnoVpSMZO1rB/G01wrr0=
|
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc/go.mod h1:OMmITAib6POA37xCichWM0aRnoVpSMZO1rB/G01wrr0=
|
||||||
|
|||||||
3
main.go
3
main.go
@ -35,6 +35,8 @@ import (
|
|||||||
|
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus" // 词典匹配回复
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus" // 词典匹配回复
|
||||||
|
|
||||||
|
_ "github.com/FloatTech/zbputils/job" // 定时指令触发器
|
||||||
|
|
||||||
// ^^^^ //
|
// ^^^^ //
|
||||||
// ^^^^^^^^^^^^^^ //
|
// ^^^^^^^^^^^^^^ //
|
||||||
// ^^^^^^^高优先级区^^^^^^^ //
|
// ^^^^^^^高优先级区^^^^^^^ //
|
||||||
@ -79,7 +81,6 @@ import (
|
|||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/image_finder" // 关键字搜图
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/image_finder" // 关键字搜图
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/inject" // 注入指令
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/inject" // 注入指令
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/jandan" // 煎蛋网无聊图
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/jandan" // 煎蛋网无聊图
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/job" // 定时指令触发器
|
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/juejuezi" // 绝绝子生成器
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/juejuezi" // 绝绝子生成器
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/lolicon" // lolicon 随机图片
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/lolicon" // lolicon 随机图片
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu" // 摸鱼
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu" // 摸鱼
|
||||||
|
|||||||
@ -1,541 +0,0 @@
|
|||||||
// Package job 定时指令触发器
|
|
||||||
package job
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"hash/crc64"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/FloatTech/zbputils/binary"
|
|
||||||
"github.com/FloatTech/zbputils/control"
|
|
||||||
"github.com/FloatTech/zbputils/control/order"
|
|
||||||
"github.com/FloatTech/zbputils/ctxext"
|
|
||||||
"github.com/FloatTech/zbputils/process"
|
|
||||||
"github.com/FloatTech/zbputils/vevent"
|
|
||||||
"github.com/FloatTech/zbputils/web"
|
|
||||||
"github.com/fumiama/cron"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/tidwall/gjson"
|
|
||||||
zero "github.com/wdvxdr1123/ZeroBot"
|
|
||||||
"github.com/wdvxdr1123/ZeroBot/extension/rate"
|
|
||||||
"github.com/wdvxdr1123/ZeroBot/message"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
lo map[int64]vevent.Loop
|
|
||||||
entries = map[int64]cron.EntryID{} // id entryid
|
|
||||||
matchers = map[int64]*zero.Matcher{}
|
|
||||||
mu sync.Mutex
|
|
||||||
limit = rate.NewLimiter(time.Second*2, 1)
|
|
||||||
en = control.Register("job", order.AcquirePrio(), &control.Options{
|
|
||||||
DisableOnDefault: false,
|
|
||||||
Help: "定时指令触发器\n- 记录以\"完全匹配关键词\"触发的指令\n- 取消以\"完全匹配关键词\"触发的指令\n- 记录在\"cron\"触发的指令\n- 取消在\"cron\"触发的指令\n- 查看所有触发指令\n- 查看在\"cron\"触发的指令\n- 查看以\"完全匹配关键词\"触发的指令\n- 注入指令结果:任意指令\n- 执行指令:任意指令",
|
|
||||||
PrivateDataFolder: "job",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
db.DBPath = en.DataFolder() + "job.db"
|
|
||||||
err := db.Open()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
process.GlobalInitMutex.Lock()
|
|
||||||
process.SleepAbout1sTo2s()
|
|
||||||
lo = make(map[int64]vevent.Loop, len(zero.BotConfig.Driver))
|
|
||||||
for _, drv := range zero.BotConfig.Driver {
|
|
||||||
id := drv.SelfID()
|
|
||||||
ids := strconv.FormatInt(id, 36)
|
|
||||||
c := &cmd{}
|
|
||||||
lo[id] = vevent.NewLoop(id)
|
|
||||||
err := db.Create(ids, c)
|
|
||||||
logrus.Infoln("[job]创建表", ids)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
_ = db.FindFor(ids, c, "", func() error {
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
if strings.HasPrefix(c.Cron, "fm:") {
|
|
||||||
m := en.OnFullMatch(c.Cron[3:] /* skip fm: */).SetBlock(true)
|
|
||||||
m.Handle(generalhandler(c))
|
|
||||||
matchers[c.ID] = getmatcher(m)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(c.Cron, "sm:") {
|
|
||||||
m := en.OnFullMatch(c.Cron[3:] /* skip fm: */).SetBlock(true)
|
|
||||||
m.Handle(superuserhandler(c))
|
|
||||||
matchers[c.ID] = getmatcher(m)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
eid, err := process.CronTab.AddFunc(c.Cron, inject(id, []byte(c.Cmd)))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
entries[c.ID] = eid
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
logrus.Infoln("[job]本地环回初始化完成")
|
|
||||||
process.GlobalInitMutex.Unlock()
|
|
||||||
}()
|
|
||||||
en.OnRegex(`^记录在"(.*)"触发的指令$`, ctxext.UserOrGrpAdmin, islonotnil, isfirstregmatchnotnil, logevent).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
cron := ctx.State["regex_matched"].([]string)[1]
|
|
||||||
command := ctx.State["job_raw_event"].(string)
|
|
||||||
c := &cmd{
|
|
||||||
ID: idof(cron, command),
|
|
||||||
Cron: cron,
|
|
||||||
Cmd: command,
|
|
||||||
}
|
|
||||||
err := addcmd(ctx.Event.SelfID, c)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text("成功!"))
|
|
||||||
})
|
|
||||||
en.OnRegex(`^记录以"(.*)"触发的指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil, logevent).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
cron := "fm:" + ctx.State["regex_matched"].([]string)[1]
|
|
||||||
command := ctx.State["job_new_event"].(gjson.Result).Get("message").Raw
|
|
||||||
logrus.Debugln("[job] get cmd:", command)
|
|
||||||
c := &cmd{
|
|
||||||
ID: idof(cron, command),
|
|
||||||
Cron: cron,
|
|
||||||
Cmd: command,
|
|
||||||
}
|
|
||||||
err := registercmd(ctx.Event.SelfID, c)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text("成功!"))
|
|
||||||
})
|
|
||||||
en.OnRegex(`^记录以"(.*)"触发的代表我执行的指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil, logevent).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
cron := "sm:" + ctx.State["regex_matched"].([]string)[1]
|
|
||||||
command := ctx.State["job_raw_event"].(string)
|
|
||||||
logrus.Debugln("[job] get cmd:", command)
|
|
||||||
c := &cmd{
|
|
||||||
ID: idof(cron, command),
|
|
||||||
Cron: cron,
|
|
||||||
Cmd: command,
|
|
||||||
}
|
|
||||||
err := registercmd(ctx.Event.SelfID, c)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text("成功!"))
|
|
||||||
})
|
|
||||||
en.OnRegex(`^取消在"(.*)"触发的指令$`, ctxext.UserOrGrpAdmin, islonotnil, isfirstregmatchnotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
cron := ctx.State["regex_matched"].([]string)[1]
|
|
||||||
err := rmcmd(ctx.Event.SelfID, ctx.Event.UserID, cron)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text("成功!"))
|
|
||||||
})
|
|
||||||
en.OnRegex(`^取消以"(.*)"触发的(代表我执行的)?指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
issu := ctx.State["regex_matched"].([]string)[2] != ""
|
|
||||||
cron := ""
|
|
||||||
if issu {
|
|
||||||
cron = "sm:"
|
|
||||||
} else {
|
|
||||||
cron = "fm:"
|
|
||||||
}
|
|
||||||
cron += ctx.State["regex_matched"].([]string)[1]
|
|
||||||
err := delcmd(ctx.Event.SelfID, cron)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text("成功!"))
|
|
||||||
})
|
|
||||||
en.OnFullMatch("查看所有触发指令", zero.SuperUserPermission, islonotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
c := &cmd{}
|
|
||||||
ids := strconv.FormatInt(ctx.Event.SelfID, 36)
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
n, err := db.Count(ids)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lst := make([]string, 0, n)
|
|
||||||
err = db.FindFor(ids, c, "GROUP BY cron", func() error {
|
|
||||||
lst = append(lst, c.Cron+"\n")
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text(lst))
|
|
||||||
})
|
|
||||||
en.OnRegex(`^查看在"(.*)"触发的指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
c := &cmd{}
|
|
||||||
ids := strconv.FormatInt(ctx.Event.SelfID, 36)
|
|
||||||
cron := ctx.State["regex_matched"].([]string)[1]
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
n, err := db.Count(ids)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lst := make([]string, 0, n)
|
|
||||||
err = db.FindFor(ids, c, "WHERE cron='"+cron+"'", func() error {
|
|
||||||
lst = append(lst, c.Cmd+"\n")
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text(lst))
|
|
||||||
})
|
|
||||||
en.OnRegex(`^查看以"(.*)"触发的(代表我执行的)?指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
c := &cmd{}
|
|
||||||
ids := strconv.FormatInt(ctx.Event.SelfID, 36)
|
|
||||||
issu := ctx.State["regex_matched"].([]string)[2] != ""
|
|
||||||
cron := ""
|
|
||||||
if issu {
|
|
||||||
cron = "sm:"
|
|
||||||
} else {
|
|
||||||
cron = "fm:"
|
|
||||||
}
|
|
||||||
cron += ctx.State["regex_matched"].([]string)[1]
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
n, err := db.Count(ids)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lst := make([]string, 0, n)
|
|
||||||
err = db.FindFor(ids, c, "WHERE cron='"+cron+"'", func() error {
|
|
||||||
lst = append(lst, c.Cmd+"\n")
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text(lst))
|
|
||||||
})
|
|
||||||
en.OnPrefix("执行指令:", ctxext.UserOrGrpAdmin, islonotnil, func(ctx *zero.Ctx) bool {
|
|
||||||
return ctx.State["args"].(string) != ""
|
|
||||||
}, parseArgs).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
ev := strings.ReplaceAll(ctx.Event.RawEvent.Raw, "执行指令:", "")
|
|
||||||
logrus.Debugln("[job] inject:", ev)
|
|
||||||
inject(ctx.Event.SelfID, binary.StringToBytes(ev))()
|
|
||||||
})
|
|
||||||
en.OnPrefix("注入指令结果:", ctxext.UserOrGrpAdmin, islonotnil, func(ctx *zero.Ctx) bool {
|
|
||||||
return ctx.State["args"].(string) != ""
|
|
||||||
}, parseArgs).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
|
||||||
vevent.NewLoopOf(vevent.NewAPICallerHook(ctx, func(rsp zero.APIResponse, err error) {
|
|
||||||
if err == nil {
|
|
||||||
logrus.Debugln("[job] CallerHook returned")
|
|
||||||
id := message.NewMessageID(rsp.Data.Get("message_id").String())
|
|
||||||
if id.ID() == 0 {
|
|
||||||
ctx.SendChain(message.Text("ERROR:未获取到返回结果"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
msg := ctx.GetMessage(id)
|
|
||||||
ctx.Event.NativeMessage = json.RawMessage("\"" + msg.Elements.String() + "\"")
|
|
||||||
ctx.Event.RawMessageID = json.RawMessage(msg.MessageId.String())
|
|
||||||
ctx.Event.RawMessage = msg.Elements.String()
|
|
||||||
time.Sleep(time.Second * 5) // 防止风控
|
|
||||||
ctx.Event.Time = time.Now().Unix()
|
|
||||||
ctx.DeleteMessage(id)
|
|
||||||
vev, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
|
||||||
err = json.NewEncoder(w).Encode(ctx.Event)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
cl()
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logrus.Debugln("[job] inject:", binary.BytesToString(vev))
|
|
||||||
inject(ctx.Event.SelfID, vev)()
|
|
||||||
cl()
|
|
||||||
}
|
|
||||||
})).Echo(binary.StringToBytes(strings.ReplaceAll(ctx.Event.RawEvent.Raw, "注入指令结果:", "")))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func islonotnil(ctx *zero.Ctx) bool {
|
|
||||||
return len(lo) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func isfirstregmatchnotnil(ctx *zero.Ctx) bool {
|
|
||||||
return ctx.State["regex_matched"].([]string)[1] != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func inject(bot int64, response []byte) func() {
|
|
||||||
return func() {
|
|
||||||
if limit.Acquire() {
|
|
||||||
lo[bot].Echo(response)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func idof(cron, cmd string) int64 {
|
|
||||||
return int64(crc64.Checksum(binary.StringToBytes(cron+cmd), crc64.MakeTable(crc64.ISO)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func addcmd(bot int64, c *cmd) error {
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
eid, err := process.CronTab.AddFunc(c.Cron, inject(bot, []byte(c.Cmd)))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
entries[c.ID] = eid
|
|
||||||
return db.Insert(strconv.FormatInt(bot, 36), c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func registercmd(bot int64, c *cmd) error {
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
m := en.OnFullMatch(c.Cron[3:] /* skip fm: or sm: */).SetBlock(true)
|
|
||||||
if strings.HasPrefix(c.Cron, "sm:") {
|
|
||||||
m.Handle(superuserhandler(c))
|
|
||||||
} else {
|
|
||||||
m.Handle(generalhandler(c))
|
|
||||||
}
|
|
||||||
matchers[c.ID] = getmatcher(m)
|
|
||||||
return db.Insert(strconv.FormatInt(bot, 36), c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func generalhandler(c *cmd) zero.Handler {
|
|
||||||
return func(ctx *zero.Ctx) {
|
|
||||||
ctx.Event.NativeMessage = json.RawMessage(c.Cmd) // c.Cmd only have message
|
|
||||||
ctx.Event.Time = time.Now().Unix()
|
|
||||||
var err error
|
|
||||||
vev, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
|
||||||
err = json.NewEncoder(w).Encode(ctx.Event)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
cl()
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logrus.Debugln("[job] inject:", binary.BytesToString(vev))
|
|
||||||
inject(ctx.Event.SelfID, vev)()
|
|
||||||
cl()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func superuserhandler(c *cmd) zero.Handler {
|
|
||||||
e := &zero.Event{Sender: new(zero.User)}
|
|
||||||
err := json.Unmarshal(binary.StringToBytes(c.Cmd), e)
|
|
||||||
return func(ctx *zero.Ctx) {
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Event.UserID = e.UserID
|
|
||||||
ctx.Event.RawMessage = e.RawMessage
|
|
||||||
ctx.Event.Sender = e.Sender
|
|
||||||
ctx.Event.NativeMessage = e.NativeMessage
|
|
||||||
vev, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
|
||||||
err = json.NewEncoder(w).Encode(ctx.Event)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
cl()
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logrus.Debugln("[job] inject:", binary.BytesToString(vev))
|
|
||||||
inject(ctx.Event.SelfID, vev)()
|
|
||||||
cl()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func rmcmd(bot, caller int64, cron string) error {
|
|
||||||
c := &cmd{}
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
bots := strconv.FormatInt(bot, 36)
|
|
||||||
e := new(zero.Event)
|
|
||||||
var delcmd []string
|
|
||||||
err := db.FindFor(bots, c, "WHERE cron='"+cron+"'", func() error {
|
|
||||||
err := json.Unmarshal(binary.StringToBytes(c.Cmd), e)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if e.UserID != caller {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
eid, ok := entries[c.ID]
|
|
||||||
if ok {
|
|
||||||
process.CronTab.Remove(eid)
|
|
||||||
delete(entries, c.ID)
|
|
||||||
delcmd = append(delcmd, "id="+strconv.FormatInt(c.ID, 10))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(delcmd) > 0 {
|
|
||||||
return db.Del(bots, "WHERE "+strings.Join(delcmd, " or "))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func delcmd(bot int64, cron string) error {
|
|
||||||
c := &cmd{}
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
bots := strconv.FormatInt(bot, 36)
|
|
||||||
var delcmd []string
|
|
||||||
err := db.FindFor(bots, c, "WHERE cron='"+cron+"'", func() error {
|
|
||||||
m, ok := matchers[c.ID]
|
|
||||||
if ok {
|
|
||||||
m.Delete()
|
|
||||||
delete(matchers, c.ID)
|
|
||||||
delcmd = append(delcmd, "id="+strconv.FormatInt(c.ID, 10))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(delcmd) > 0 {
|
|
||||||
return db.Del(bots, "WHERE "+strings.Join(delcmd, " or "))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseArgs(ctx *zero.Ctx) bool {
|
|
||||||
cmds := ctx.State["args"].(string)
|
|
||||||
if !strings.Contains(cmds, "?::") && !strings.Contains(cmds, "!::") {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
args := make(map[int]string)
|
|
||||||
for strings.Contains(ctx.Event.RawEvent.Raw, "?::") {
|
|
||||||
start := strings.Index(ctx.Event.RawEvent.Raw, "?::")
|
|
||||||
msgend := strings.Index(ctx.Event.RawEvent.Raw[start+3:], "::")
|
|
||||||
if msgend < 0 {
|
|
||||||
ctx.SendChain(message.Text("ERROR:找不到结束的::"))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
msgend += start + 3
|
|
||||||
numend := strings.Index(ctx.Event.RawEvent.Raw[msgend+2:], "!")
|
|
||||||
if numend <= 0 {
|
|
||||||
ctx.SendChain(message.Text("ERROR:找不到结束的!"))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
numend += msgend + 2
|
|
||||||
logrus.Debugln("[job]", start, msgend, numend)
|
|
||||||
msg := ctx.Event.RawEvent.Raw[start+3 : msgend]
|
|
||||||
arg, err := strconv.Atoi(ctx.Event.RawEvent.Raw[msgend+2 : numend])
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
arr, ok := args[arg]
|
|
||||||
if !ok {
|
|
||||||
var id message.MessageID
|
|
||||||
if msg == "" {
|
|
||||||
id = ctx.SendChain(message.At(ctx.Event.UserID), message.Text("请输入参数", arg))
|
|
||||||
} else {
|
|
||||||
id = ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[", arg, "] ", msg))
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case <-time.After(time.Second * 120):
|
|
||||||
ctx.Send(message.ReplyWithMessage(id, message.Text("参数读取超时")))
|
|
||||||
if msg[0] != '?' {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case e := <-zero.NewFutureEvent("message", 0, true, zero.CheckUser(ctx.Event.UserID)).Next():
|
|
||||||
args[arg] = e.Message.String()
|
|
||||||
arr = args[arg]
|
|
||||||
process.SleepAbout1sTo2s()
|
|
||||||
ctx.SendChain(message.Reply(e.MessageID), message.Text("已记录"))
|
|
||||||
process.SleepAbout1sTo2s()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.Event.RawEvent.Raw = ctx.Event.RawEvent.Raw[:start] + arr + ctx.Event.RawEvent.Raw[numend+1:]
|
|
||||||
}
|
|
||||||
args = make(map[int]string)
|
|
||||||
for strings.Contains(ctx.Event.RawEvent.Raw, "!::") {
|
|
||||||
start := strings.Index(ctx.Event.RawEvent.Raw, "!::")
|
|
||||||
msgend := strings.Index(ctx.Event.RawEvent.Raw[start+3:], "::")
|
|
||||||
if msgend < 0 {
|
|
||||||
ctx.SendChain(message.Text("ERROR:找不到结束的::"))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
msgend += start + 3
|
|
||||||
numend := strings.Index(ctx.Event.RawEvent.Raw[msgend+2:], "!")
|
|
||||||
if numend <= 0 {
|
|
||||||
ctx.SendChain(message.Text("ERROR:找不到结束的!"))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
numend += msgend + 2
|
|
||||||
logrus.Debugln("[job]", start, msgend, numend)
|
|
||||||
u := ctx.Event.RawEvent.Raw[start+3 : msgend]
|
|
||||||
if u == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
arg, err := strconv.Atoi(ctx.Event.RawEvent.Raw[msgend+2 : numend])
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
arr, ok := args[arg]
|
|
||||||
if !ok {
|
|
||||||
isnilable := u[0] == '?'
|
|
||||||
if isnilable {
|
|
||||||
u = u[1:]
|
|
||||||
if u == "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b, err := web.GetData(u)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
if !isnilable {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(b) > 0 {
|
|
||||||
type fakejson struct {
|
|
||||||
Arg string `json:"arg"`
|
|
||||||
}
|
|
||||||
f := fakejson{Arg: binary.BytesToString(b)}
|
|
||||||
w := binary.SelectWriter()
|
|
||||||
defer binary.PutWriter(w)
|
|
||||||
_ = json.NewEncoder(w).Encode(&f)
|
|
||||||
arr = w.String()[8 : w.Len()-3]
|
|
||||||
args[arg] = arr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w := binary.SelectWriter()
|
|
||||||
w.WriteString(ctx.Event.RawEvent.Raw[:start])
|
|
||||||
w.WriteString(arr)
|
|
||||||
w.WriteString(ctx.Event.RawEvent.Raw[numend+1:])
|
|
||||||
ctx.Event.RawEvent.Raw = string(w.Bytes())
|
|
||||||
binary.PutWriter(w)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func logevent(ctx *zero.Ctx) bool {
|
|
||||||
ctx.SendChain(message.Text("您的下一条指令将被记录,在", ctx.State["regex_matched"].([]string)[1], "时触发"))
|
|
||||||
select {
|
|
||||||
case <-time.After(time.Second * 120):
|
|
||||||
ctx.SendChain(message.Text("指令记录超时"))
|
|
||||||
return false
|
|
||||||
case e := <-zero.NewFutureEvent("message", 0, true, zero.CheckUser(ctx.Event.UserID)).Next():
|
|
||||||
ctx.State["job_raw_event"] = e.RawEvent.Raw
|
|
||||||
ctx.State["job_new_event"] = e.RawEvent
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
package job
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/FloatTech/zbputils/control"
|
|
||||||
zero "github.com/wdvxdr1123/ZeroBot"
|
|
||||||
)
|
|
||||||
|
|
||||||
type matcherinstance struct {
|
|
||||||
m *zero.Matcher
|
|
||||||
}
|
|
||||||
|
|
||||||
func getmatcher(m control.Matcher) *zero.Matcher {
|
|
||||||
return (*matcherinstance)(unsafe.Pointer(&m)).m
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
package job
|
|
||||||
|
|
||||||
import sql "github.com/FloatTech/sqlite"
|
|
||||||
|
|
||||||
type cmd struct {
|
|
||||||
ID int64 `db:"id"`
|
|
||||||
Cron string `db:"cron"`
|
|
||||||
Cmd string `db:"cmd"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var db = &sql.Sqlite{}
|
|
||||||
@ -2,39 +2,39 @@
|
|||||||
package moyu
|
package moyu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
control "github.com/FloatTech/zbputils/control"
|
control "github.com/FloatTech/zbputils/control"
|
||||||
"github.com/FloatTech/zbputils/process"
|
|
||||||
zero "github.com/wdvxdr1123/ZeroBot"
|
zero "github.com/wdvxdr1123/ZeroBot"
|
||||||
"github.com/wdvxdr1123/ZeroBot/message"
|
"github.com/wdvxdr1123/ZeroBot/message"
|
||||||
|
|
||||||
"github.com/FloatTech/zbputils/control/order"
|
"github.com/FloatTech/zbputils/control/order"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
msg message.Message
|
||||||
|
mu sync.Mutex
|
||||||
|
lastupdate time.Time
|
||||||
|
)
|
||||||
|
|
||||||
func init() { // 插件主体
|
func init() { // 插件主体
|
||||||
control.Register("moyu", order.AcquirePrio(), &control.Options{
|
control.Register("moyu", order.AcquirePrio(), &control.Options{
|
||||||
DisableOnDefault: true,
|
DisableOnDefault: true,
|
||||||
Help: "moyu\n" +
|
Help: "moyu\n" +
|
||||||
"- /启用 moyu\n" +
|
"- /启用 moyu\n" +
|
||||||
"- /禁用 moyu",
|
"- /禁用 moyu\n" +
|
||||||
})
|
"- 记录在\"0 10 * * *\"触发的指令\n" +
|
||||||
|
" - 摸鱼提醒",
|
||||||
// 定时任务每天10点执行一次
|
}).OnFullMatch("摸鱼提醒").SetBlock(true).
|
||||||
_, err := process.CronTab.AddFunc("0 10 * * *", func() { sendNotice() })
|
Handle(func(ctx *zero.Ctx) {
|
||||||
if err != nil {
|
mu.Lock()
|
||||||
panic(err)
|
defer mu.Unlock()
|
||||||
}
|
if msg == nil || time.Since(lastupdate) > time.Hour*20 {
|
||||||
}
|
|
||||||
|
|
||||||
// 获取数据拼接消息链并发送
|
|
||||||
func sendNotice() {
|
|
||||||
m, ok := control.Lookup("moyu")
|
|
||||||
if ok {
|
|
||||||
if registry.Connect() != nil {
|
if registry.Connect() != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
msg := message.Message{
|
msg = message.Message{
|
||||||
message.Text(time.Now().Format("2006-01-02")),
|
message.Text(time.Now().Format("2006-01-02")),
|
||||||
message.Text("上午好,摸鱼人!\n工作再累,一定不要忘记摸鱼哦!有事没事起身去茶水间,去厕所,去廊道走走别老在工位上坐着,钱是老板的,但命是自己的。\n"),
|
message.Text("上午好,摸鱼人!\n工作再累,一定不要忘记摸鱼哦!有事没事起身去茶水间,去厕所,去廊道走走别老在工位上坐着,钱是老板的,但命是自己的。\n"),
|
||||||
message.Text(weekend()),
|
message.Text(weekend()),
|
||||||
@ -56,14 +56,8 @@ func sendNotice() {
|
|||||||
message.Text("上班是帮老板赚钱,摸鱼是赚老板的钱!最后,祝愿天下所有摸鱼人,都能愉快的渡过每一天…"),
|
message.Text("上班是帮老板赚钱,摸鱼是赚老板的钱!最后,祝愿天下所有摸鱼人,都能愉快的渡过每一天…"),
|
||||||
}
|
}
|
||||||
_ = registry.Close()
|
_ = registry.Close()
|
||||||
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
|
lastupdate = time.Now()
|
||||||
for _, g := range ctx.GetGroupList().Array() {
|
|
||||||
grp := g.Get("group_id").Int()
|
|
||||||
if m.IsEnabledIn(grp) {
|
|
||||||
ctx.SendGroupMessage(grp, msg)
|
|
||||||
}
|
}
|
||||||
}
|
ctx.Send(msg)
|
||||||
return true
|
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import (
|
|||||||
|
|
||||||
control "github.com/FloatTech/zbputils/control"
|
control "github.com/FloatTech/zbputils/control"
|
||||||
"github.com/FloatTech/zbputils/control/order"
|
"github.com/FloatTech/zbputils/control/order"
|
||||||
"github.com/FloatTech/zbputils/process"
|
|
||||||
zero "github.com/wdvxdr1123/ZeroBot"
|
zero "github.com/wdvxdr1123/ZeroBot"
|
||||||
"github.com/wdvxdr1123/ZeroBot/message"
|
"github.com/wdvxdr1123/ZeroBot/message"
|
||||||
|
|
||||||
@ -31,7 +30,9 @@ func init() {
|
|||||||
DisableOnDefault: true,
|
DisableOnDefault: true,
|
||||||
Help: "摸鱼人日历\n" +
|
Help: "摸鱼人日历\n" +
|
||||||
"- /启用 moyucalendar\n" +
|
"- /启用 moyucalendar\n" +
|
||||||
"- /禁用 moyucalendar",
|
"- /禁用 moyucalendar\n" +
|
||||||
|
"- 记录在\"30 8 * * *\"触发的指令\n" +
|
||||||
|
" - 摸鱼人日历",
|
||||||
}).OnFullMatch("摸鱼人日历").SetBlock(true).
|
}).OnFullMatch("摸鱼人日历").SetBlock(true).
|
||||||
Handle(func(ctx *zero.Ctx) {
|
Handle(func(ctx *zero.Ctx) {
|
||||||
title := fmt.Sprintf("摸鱼人日历 %d月%d日", time.Now().Month(), time.Now().Day())
|
title := fmt.Sprintf("摸鱼人日历 %d月%d日", time.Now().Month(), time.Now().Day())
|
||||||
@ -52,40 +53,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
ctx.SendChain(message.Image(image))
|
ctx.SendChain(message.Image(image))
|
||||||
})
|
})
|
||||||
|
|
||||||
// 定时任务每天8点30分执行一次
|
|
||||||
_, err := process.CronTab.AddFunc("30 8 * * *", func() {
|
|
||||||
m, ok := control.Lookup("moyucalendar")
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
title := fmt.Sprintf("摸鱼人日历 %d月%d日", time.Now().Month(), time.Now().Day())
|
|
||||||
sg, cookies, err := sougou(title, "摸鱼人日历", ua)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
wx, err := redirect(sg, cookies, ua)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
image, err := calendar(wx, ua)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
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, message.Message{message.Image(image)})
|
|
||||||
process.SleepAbout1sTo2s()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sougou(title, publisher, ua string) (string, []*http.Cookie, error) {
|
func sougou(title, publisher, ua string) (string, []*http.Cookie, error) {
|
||||||
|
|||||||
@ -24,20 +24,18 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
picdata []byte
|
picdata []byte
|
||||||
mu sync.RWMutex
|
mu sync.Mutex
|
||||||
pictime time.Time
|
pictime time.Time
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() { // 插件主体
|
func init() { // 插件主体
|
||||||
engine := control.Register("zaobao", order.AcquirePrio(), &control.Options{
|
engine := control.Register("zaobao", order.AcquirePrio(), &control.Options{
|
||||||
DisableOnDefault: true,
|
DisableOnDefault: true,
|
||||||
Help: "zaobao\n" +
|
Help: "易即今日公众号api的今日早报\n" +
|
||||||
"api早上8点更新,推荐定时在8点30后\n" +
|
"api早上8点更新,推荐定时在8点30后\n" +
|
||||||
"配合插件job中的记录在'cron'触发的指令使用\n" +
|
"配合插件job中的记录在\"cron\"触发的指令使用\n" +
|
||||||
"------示例------\n" +
|
"- 记录在\"0 9 * * *\"触发的指令\n" +
|
||||||
"每天早上九点定时发送\n" +
|
" - 今日早报",
|
||||||
"记录在'00 9 * * *'触发的指令\n" +
|
|
||||||
"今日早报",
|
|
||||||
})
|
})
|
||||||
engine.OnFullMatch("今日早报", zero.OnlyGroup).SetBlock(false).
|
engine.OnFullMatch("今日早报", zero.OnlyGroup).SetBlock(false).
|
||||||
Handle(func(ctx *zero.Ctx) {
|
Handle(func(ctx *zero.Ctx) {
|
||||||
@ -51,23 +49,9 @@ func init() { // 插件主体
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getdata() error { // 获取图片链接并且下载
|
func getdata() error { // 获取图片链接并且下载
|
||||||
mu.RLock()
|
|
||||||
if time.Since(pictime) > time.Hour*20 {
|
|
||||||
mu.RUnlock()
|
|
||||||
mu.Lock()
|
|
||||||
picdata = nil
|
|
||||||
pictime = time.Now()
|
|
||||||
mu.Unlock()
|
|
||||||
mu.RLock()
|
|
||||||
}
|
|
||||||
if picdata != nil {
|
|
||||||
mu.RUnlock()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
mu.RUnlock()
|
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
if picdata != nil {
|
if picdata != nil && time.Since(pictime) <= time.Hour*20 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
data, err := web.GetDataWith(web.NewDefaultClient(), api, "GET", "", ua)
|
data, err := web.GetDataWith(web.NewDefaultClient(), api, "GET", "", ua)
|
||||||
@ -78,5 +62,6 @@ func getdata() error { // 获取图片链接并且下载
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
pictime = time.Now()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user