diff --git a/go.mod b/go.mod index d5e5571f..d8a66c83 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/FloatTech/AnimeAPI v1.3.3-0.20220415110058-2e4bd994628f github.com/FloatTech/sqlite v0.2.1 - github.com/FloatTech/zbputils v1.3.3-0.20220415105141-e69a077a7905 + github.com/FloatTech/zbputils v1.3.3-0.20220415152725-74a07dd318ad github.com/antchfx/htmlquery v1.2.4 github.com/corona10/goimagehash v1.0.3 github.com/fogleman/gg v1.3.0 diff --git a/go.sum b/go.sum index aec309f8..8c36680a 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,10 @@ github.com/FloatTech/AnimeAPI v1.3.3-0.20220415110058-2e4bd994628f h1:z+VXjigJ1Q github.com/FloatTech/AnimeAPI v1.3.3-0.20220415110058-2e4bd994628f/go.mod h1:HXlKP24hAdQocJcOIG2ZEFYd789fRyatSflt2wUT/b4= github.com/FloatTech/sqlite v0.2.1 h1:9t6Me48XJJCIoPy4nLRvcdhcVKfT0c2lilp7SEKROG8= github.com/FloatTech/sqlite v0.2.1/go.mod h1:6NfHRzqOo9RWeMJEoAQVuo51Omd5LFNxCNQhMF02/9U= -github.com/FloatTech/zbputils v1.3.3-0.20220415105141-e69a077a7905 h1:tA1Tgz5yO+KP/npiz9AU+amBeer+wuSdya9+VvZqYMk= -github.com/FloatTech/zbputils v1.3.3-0.20220415105141-e69a077a7905/go.mod h1:a6vKTjBt//Mr4M8VSSj5ER597/ZjJ+dJAIQSVU/M/oY= +github.com/FloatTech/zbputils v1.3.3-0.20220415150756-e428c8ec6615 h1:Bi/lMkR43Y30vemaAsKCANanN+cU42jOndCiy8Ni1VA= +github.com/FloatTech/zbputils v1.3.3-0.20220415150756-e428c8ec6615/go.mod h1:a6vKTjBt//Mr4M8VSSj5ER597/ZjJ+dJAIQSVU/M/oY= +github.com/FloatTech/zbputils v1.3.3-0.20220415152725-74a07dd318ad h1:bhZUiOA5WvCXWF8hT0keeX65jBbMWwxGyyfoVlFtMjA= +github.com/FloatTech/zbputils v1.3.3-0.20220415152725-74a07dd318ad/go.mod h1:a6vKTjBt//Mr4M8VSSj5ER597/ZjJ+dJAIQSVU/M/oY= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/RomiChan/syncx v0.0.0-20220404072119-d7ea0ae15a4c h1:cNPOdTNiVwxLpROLjXCgbIPvdkE+BwvxDvgmdYmWx6Q= github.com/RomiChan/syncx v0.0.0-20220404072119-d7ea0ae15a4c/go.mod h1:KqZzu7slNKROh3TSYEH/IUMG6f4M+1qubZ5e52QypsE= diff --git a/plugin/bilibili/info.go b/plugin/bilibili/info.go index 29ed9db8..9b6570d8 100644 --- a/plugin/bilibili/info.go +++ b/plugin/bilibili/info.go @@ -11,6 +11,7 @@ import ( "time" control "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/zbputils/file" "github.com/FloatTech/zbputils/img" "github.com/FloatTech/zbputils/img/text" @@ -36,14 +37,21 @@ var engine = control.Register("bilibili", &control.Options{ // 查成分的 func init() { cachePath := engine.DataFolder() + "cache/" - dbfile := engine.DataFolder() + "bilibili.db" - go func() { - _ = os.MkdirAll(cachePath, 0755) + _ = os.RemoveAll(cachePath) + _ = os.MkdirAll(cachePath, 0755) + var getdb = ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { + var err error + dbfile := engine.DataFolder() + "bilibili.db" _, _ = file.GetLazyData(dbfile, false, false) - vdb = initialize(dbfile) - }() + vdb, err = initialize(dbfile) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + return true + }) - engine.OnRegex(`^>user info\s?(.{1,25})$`).SetBlock(true). + engine.OnRegex(`^>user info\s?(.{1,25})$`, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { keyword := ctx.State["regex_matched"].([]string)[1] uidRes, err := search(keyword) @@ -95,7 +103,7 @@ func init() { )) }) - engine.OnRegex(`^查成分\s?(.{1,25})$`).SetBlock(true). + engine.OnRegex(`^查成分\s?(.{1,25})$`, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { keyword := ctx.State["regex_matched"].([]string)[1] searchRes, err := search(keyword) @@ -256,7 +264,7 @@ func init() { ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile)) }) - engine.OnRegex(`^设置b站cookie?\s+(.{1,100})$`, zero.SuperUserPermission).SetBlock(true). + engine.OnRegex(`^设置b站cookie?\s+(.{1,100})$`, zero.SuperUserPermission, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { cookie := ctx.State["regex_matched"].([]string)[1] err := vdb.setBilibiliCookie(cookie) @@ -267,7 +275,7 @@ func init() { ctx.SendChain(message.Text("成功设置b站cookie为" + cookie)) }) - engine.OnFullMatch("更新vup", zero.SuperUserPermission).SetBlock(true). + engine.OnFullMatch("更新vup", zero.SuperUserPermission, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { ctx.SendChain(message.Text("少女祈祷中...")) err := updateVup() diff --git a/plugin/bilibili/model.go b/plugin/bilibili/model.go index dbf6b727..774be045 100644 --- a/plugin/bilibili/model.go +++ b/plugin/bilibili/model.go @@ -42,21 +42,21 @@ func (config) TableName() string { } // initialize 初始化vtb数据库 -func initialize(dbpath string) *vupdb { +func initialize(dbpath string) (*vupdb, error) { if _, err := os.Stat(dbpath); err != nil || os.IsNotExist(err) { // 生成文件 f, err := os.Create(dbpath) if err != nil { - return nil + return nil, err } defer f.Close() } gdb, err := gorm.Open("sqlite3", dbpath) if err != nil { - panic(err) + return nil, err } gdb.Debug().AutoMigrate(&vup{}).AutoMigrate(&config{}) - return (*vupdb)(gdb) + return (*vupdb)(gdb), nil } func (vdb *vupdb) insertVupByMid(mid int64, uname string, roomid int64) (err error) { diff --git a/plugin/book_review/book_review.go b/plugin/book_review/book_review.go index c4f00b58..9df8cc6e 100644 --- a/plugin/book_review/book_review.go +++ b/plugin/book_review/book_review.go @@ -8,6 +8,7 @@ import ( "github.com/FloatTech/zbputils/binary" "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/zbputils/file" "github.com/FloatTech/zbputils/img/text" ) @@ -19,24 +20,27 @@ func init() { PublicDataFolder: "BookReview", }) - go func() { + getdb := ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { dbpath := engine.DataFolder() db.DBPath = dbpath + "bookreview.db" // os.RemoveAll(dbpath) _, _ = file.GetLazyData(db.DBPath, false, true) err := db.Create("bookreview", &book{}) if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } n, err := db.Count("bookreview") if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } - log.Printf("[bookreview]读取%d条书评", n) - }() + log.Infof("[bookreview]读取%d条书评", n) + return true + }) // 中文、英文、数字但不包括下划线等符号 - engine.OnRegex("^书评([\u4E00-\u9FA5A-Za-z0-9]{1,25})$").SetBlock(true). + engine.OnRegex("^书评([\u4E00-\u9FA5A-Za-z0-9]{1,25})$", getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { b := getBookReviewByKeyword(ctx.State["regex_matched"].([]string)[1]) data, err := text.RenderToBase64(b.BookReview, text.FontFile, 400, 20) @@ -49,7 +53,7 @@ func init() { } }) - engine.OnFullMatch("随机书评").SetBlock(true). + engine.OnFullMatch("随机书评", getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { br := getRandomBookReview() data, err := text.RenderToBase64(br.BookReview, text.FontFile, 400, 20) diff --git a/plugin/chouxianghua/chouxianghua.go b/plugin/chouxianghua/chouxianghua.go index 9974c994..2b4077ec 100644 --- a/plugin/chouxianghua/chouxianghua.go +++ b/plugin/chouxianghua/chouxianghua.go @@ -7,6 +7,7 @@ import ( "github.com/wdvxdr1123/ZeroBot/message" "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/zbputils/file" ) @@ -17,23 +18,26 @@ func init() { PublicDataFolder: "ChouXiangHua", }) - go func() { - dbpath := en.DataFolder() - db.DBPath = dbpath + "cxh.db" - // os.RemoveAll(dbpath) - _, _ = file.GetLazyData(db.DBPath, false, true) - err := db.Create("pinyin", &pinyin{}) - if err != nil { - panic(err) - } - n, err := db.Count("pinyin") - if err != nil { - panic(err) - } - logrus.Printf("[chouxianghua]读取%d条拼音", n) - }() - - en.OnRegex("^抽象翻译((\\s|[\\r\\n]|[\\p{Han}\\p{P}A-Za-z0-9])+)$").SetBlock(true). + en.OnRegex("^抽象翻译((\\s|[\\r\\n]|[\\p{Han}\\p{P}A-Za-z0-9])+)$", + ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { + dbpath := en.DataFolder() + db.DBPath = dbpath + "cxh.db" + // os.RemoveAll(dbpath) + _, _ = file.GetLazyData(db.DBPath, false, true) + err := db.Create("pinyin", &pinyin{}) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + n, err := db.Count("pinyin") + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + logrus.Printf("[chouxianghua]读取%d条拼音", n) + return true + }), + ).SetBlock(true). Handle(func(ctx *zero.Ctx) { r := cx(ctx.State["regex_matched"].([]string)[1]) ctx.SendChain(message.Text(r)) diff --git a/plugin/cpstory/cpstory.go b/plugin/cpstory/cpstory.go index c722a968..c5120f92 100644 --- a/plugin/cpstory/cpstory.go +++ b/plugin/cpstory/cpstory.go @@ -9,6 +9,7 @@ import ( "github.com/wdvxdr1123/ZeroBot/message" control "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/zbputils/file" "github.com/FloatTech/zbputils/math" ) @@ -20,23 +21,26 @@ func init() { PublicDataFolder: "CpStory", }) - go func() { + getdb := ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { dbpath := engine.DataFolder() db.DBPath = dbpath + "cp.db" // os.RemoveAll(dbpath) _, _ = file.GetLazyData(db.DBPath, false, true) err := db.Create("cp_story", &cpstory{}) if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } n, err := db.Count("cp_story") if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } logrus.Printf("[cpstory]读取%d条故事", n) - }() + return true + }) - engine.OnRegex("^组cp.*?(\\d+).*?(\\d+)", zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) { + engine.OnRegex("^组cp.*?(\\d+).*?(\\d+)", zero.OnlyGroup, getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) { cs := getRandomCpStory() gong := ctx.CardOrNickName(math.Str2Int64(ctx.State["regex_matched"].([]string)[1])) shou := ctx.CardOrNickName(math.Str2Int64(ctx.State["regex_matched"].([]string)[2])) @@ -46,7 +50,7 @@ func init() { text = strings.ReplaceAll(text, cs.Shou, gong) ctx.SendChain(message.Text(text)) }) - engine.OnPrefix("磕cp").SetBlock(true).Handle(func(ctx *zero.Ctx) { + engine.OnPrefix("磕cp", getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) { cs := getRandomCpStory() params := strings.Split(ctx.State["args"].(string), " ") if len(params) < 2 { diff --git a/plugin/curse/curse.go b/plugin/curse/curse.go index 53cc1aa8..b04cecc7 100644 --- a/plugin/curse/curse.go +++ b/plugin/curse/curse.go @@ -24,34 +24,41 @@ func init() { PublicDataFolder: "Curse", }) - go func() { + getdb := ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { dbpath := engine.DataFolder() db.DBPath = dbpath + "curse.db" _, err := file.GetLazyData(db.DBPath, false, true) if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } err = db.Create("curse", &curse{}) if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + c, err := db.Count("curse") + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false } - c, _ := db.Count("curse") logrus.Infoln("[curse]加载", c, "条骂人语录") - }() + return true + }) - engine.OnFullMatch("骂我").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) { + engine.OnFullMatch("骂我", getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) { process.SleepAbout1sTo2s() text := getRandomCurseByLevel(minLevel).Text ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(text)) }) - engine.OnFullMatch("大力骂我").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) { + engine.OnFullMatch("大力骂我", getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) { process.SleepAbout1sTo2s() text := getRandomCurseByLevel(maxLevel).Text ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(text)) }) - engine.OnKeywordGroup([]string{"他妈", "公交车", "你妈", "操", "屎", "去死", "快死", "我日", "逼", "尼玛", "艾滋", "癌症", "有病", "烦你", "你爹", "屮", "cnm"}, zero.OnlyToMe).SetBlock(true). + engine.OnKeywordGroup([]string{"他妈", "公交车", "你妈", "操", "屎", "去死", "快死", "我日", "逼", "尼玛", "艾滋", "癌症", "有病", "烦你", "你爹", "屮", "cnm"}, zero.OnlyToMe, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { text := getRandomCurseByLevel(maxLevel).Text ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(text)) diff --git a/plugin/diana/bing.go b/plugin/diana/bing.go index 6714f93a..e787fc96 100644 --- a/plugin/diana/bing.go +++ b/plugin/diana/bing.go @@ -6,6 +6,7 @@ import ( "github.com/wdvxdr1123/ZeroBot/message" control "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/ZeroBot-Plugin/plugin/diana/data" ) @@ -21,26 +22,29 @@ var engine = control.Register("diana", &control.Options{ }) func init() { - go func() { - datapath := engine.DataFolder() - dbfile := datapath + "text.db" - data.LoadText(dbfile) - }() + getdb := ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { + err := data.LoadText(engine.DataFolder() + "text.db") + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + return true + }) // 随机发送一篇上面的小作文 - engine.OnFullMatch("小作文").SetBlock(true). + engine.OnFullMatch("小作文", getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { // 绕过第一行发病 ctx.SendChain(message.Text(data.RandText())) }) // 逆天 - engine.OnFullMatch("发大病").SetBlock(true). + engine.OnFullMatch("发大病", getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { // 第一行是发病 ctx.SendChain(message.Text(data.HentaiText())) }) // 增加小作文 - engine.OnRegex(`^教你一篇小作文(.*)$`, zero.AdminPermission).SetBlock(true). + engine.OnRegex(`^教你一篇小作文(.*)$`, zero.AdminPermission, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { err := data.AddText(ctx.State["regex_matched"].([]string)[1]) if err != nil { diff --git a/plugin/diana/data/text.go b/plugin/diana/data/text.go index 7d6ab005..a9d1907b 100644 --- a/plugin/diana/data/text.go +++ b/plugin/diana/data/text.go @@ -19,18 +19,22 @@ type text struct { } // LoadText 加载小作文 -func LoadText(dbfile string) { +func LoadText(dbfile string) error { _, err := file.GetLazyData(dbfile, false, false) db.DBPath = dbfile if err != nil { - panic(err) + return err } err = db.Create("text", &text{}) if err != nil { - panic(err) + return err + } + c, err := db.Count("text") + if err != nil { + return err } - c, _ := db.Count("text") logrus.Printf("[Diana]读取%d条小作文", c) + return nil } // AddText 添加小作文 diff --git a/plugin/fortune/fortune.go b/plugin/fortune/fortune.go index 1e51f585..661dde4d 100644 --- a/plugin/fortune/fortune.go +++ b/plugin/fortune/fortune.go @@ -61,25 +61,9 @@ func init() { if err != nil { panic(err) } - go func() { - for i, s := range table { - index[s] = uint8(i) - } - data, err := file.GetLazyData(omikujson, true, false) - if err != nil { - panic(err) - } - err = json.Unmarshal(data, &omikujis) - if err != nil { - panic(err) - } - }() - go func() { - _, err := file.GetLazyData(font, false, true) - if err != nil { - panic(err) - } - }() + for i, s := range table { + index[s] = uint8(i) + } en.OnRegex(`^设置底图\s?(.*)`).SetBlock(true). Handle(func(ctx *zero.Ctx) { gid := ctx.Event.GroupID @@ -104,7 +88,26 @@ func init() { } ctx.SendChain(message.Text("没有这个底图哦~")) }) - en.OnFullMatchGroup([]string{"运势", "抽签"}).SetBlock(true). + en.OnFullMatchGroup([]string{"运势", "抽签"}, ctxext.DoOnceOnSuccess( + func(ctx *zero.Ctx) bool { + data, err := file.GetLazyData(omikujson, true, false) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + err = json.Unmarshal(data, &omikujis) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + _, err = file.GetLazyData(font, false, true) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + return true + }, + )).SetBlock(true). Handle(func(ctx *zero.Ctx) { // 获取该群背景类型,默认车万 kind := "车万" diff --git a/plugin/funny/laugh.go b/plugin/funny/laugh.go index ad5dfe56..4bdba9ad 100644 --- a/plugin/funny/laugh.go +++ b/plugin/funny/laugh.go @@ -29,22 +29,27 @@ func init() { PublicDataFolder: "Funny", }) - go func() { + en.OnPrefix("讲个笑话", ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { dbpath := en.DataFolder() db.DBPath = dbpath + "jokes.db" _, err := file.GetLazyData(db.DBPath, false, true) if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } err = db.Create("jokes", &joke{}) if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + c, err := db.Count("jokes") + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false } - c, _ := db.Count("jokes") logrus.Infoln("[funny]加载", c, "个笑话") - }() - - en.OnPrefix("讲个笑话").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) { + return true + })).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) { // 获取名字 name := ctx.NickName() var j joke diff --git a/plugin/genshin/ys.go b/plugin/genshin/ys.go index 82c6c155..66f86c9f 100644 --- a/plugin/genshin/ys.go +++ b/plugin/genshin/ys.go @@ -38,18 +38,6 @@ func init() { PublicDataFolder: "Genshin", }).ApplySingle(ctxext.DefaultSingle) - go func() { - zipfile := engine.DataFolder() + "Genshin.zip" - _, err := file.GetLazyData(zipfile, false, false) - if err != nil { - panic(err) - } - err = parsezip(zipfile) - if err != nil { - panic(err) - } - }() - engine.OnFullMatch("切换原神卡池").SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { c, ok := control.Lookup("genshin") @@ -76,7 +64,22 @@ func init() { } }) - engine.OnFullMatch("原神十连").SetBlock(true).Limit(ctxext.LimitByUser). + engine.OnFullMatch("原神十连", ctxext.DoOnceOnSuccess( + func(ctx *zero.Ctx) bool { + zipfile := engine.DataFolder() + "Genshin.zip" + _, err := file.GetLazyData(zipfile, false, false) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + err = parsezip(zipfile) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + return true + }, + )).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { c, ok := control.Lookup("genshin") if !ok { diff --git a/plugin/jandan/jandan.go b/plugin/jandan/jandan.go index 4db48c51..95959b25 100644 --- a/plugin/jandan/jandan.go +++ b/plugin/jandan/jandan.go @@ -9,6 +9,7 @@ import ( "github.com/FloatTech/zbputils/binary" "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/zbputils/file" "github.com/antchfx/htmlquery" "github.com/sirupsen/logrus" @@ -27,22 +28,25 @@ func init() { PublicDataFolder: "Jandan", }) - go func() { + getdb := ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { dbpath := engine.DataFolder() db.DBPath = dbpath + "pics.db" _, _ = file.GetLazyData(db.DBPath, false, false) err := db.Create("picture", &picture{}) if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } n, err := db.Count("picture") if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } logrus.Printf("[jandan]读取%d张图片", n) - }() + return true + }) - engine.OnRegex(`来份[屌|弔|吊]图`).SetBlock(true). + engine.OnRegex(`来份[屌|弔|吊]图`, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { u, err := getRandomPicture() if err != nil { @@ -52,7 +56,7 @@ func init() { ctx.SendChain(message.Image(u)) }) - engine.OnRegex(`更新[屌|弔|吊]图`, zero.SuperUserPermission).SetBlock(true). + engine.OnRegex(`更新[屌|弔|吊]图`, zero.SuperUserPermission, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { ctx.Send("少女更新中...") webpageURL := api diff --git a/plugin/omikuji/sensou.go b/plugin/omikuji/sensou.go index 7b68067e..16cae129 100644 --- a/plugin/omikuji/sensou.go +++ b/plugin/omikuji/sensou.go @@ -3,11 +3,11 @@ package omikuji import ( "fmt" + "log" "math/rand" "strconv" "time" - log "github.com/sirupsen/logrus" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" "github.com/wdvxdr1123/ZeroBot/utils/helper" @@ -28,21 +28,6 @@ func init() { // 插件主体 PublicDataFolder: "Omikuji", }).ApplySingle(ctxext.DefaultSingle) - go func() { - dbpath := engine.DataFolder() - db.DBPath = dbpath + "kuji.db" - _, _ = file.GetLazyData(db.DBPath, false, true) - err := db.Create("kuji", &kuji{}) - if err != nil { - panic(err) - } - n, err := db.Count("kuji") - if err != nil { - panic(err) - } - log.Printf("[kuji]读取%d条签文", n) - }() - engine.OnFullMatchGroup([]string{"求签", "占卜"}).SetBlock(true). Handle(func(ctx *zero.Ctx) { miku, err := bangoToday(ctx.Event.UserID) @@ -56,7 +41,29 @@ func init() { // 插件主体 message.Image(fmt.Sprintf(bed, miku, 1)), ) }) - engine.OnFullMatchGroup([]string{"解签"}).SetBlock(true). + engine.OnFullMatch("解签", ctxext.DoOnceOnSuccess( + func(ctx *zero.Ctx) bool { + dbpath := engine.DataFolder() + db.DBPath = dbpath + "kuji.db" + _, err := file.GetLazyData(db.DBPath, false, true) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + err = db.Create("kuji", &kuji{}) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + n, err := db.Count("kuji") + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + log.Printf("[kuji]读取%d条签文", n) + return true + }, + )).SetBlock(true). Handle(func(ctx *zero.Ctx) { bg, err := bangoToday(ctx.Event.UserID) if err != nil { diff --git a/plugin/reborn/main.go b/plugin/reborn/main.go index 449bb7ad..1c8e7806 100644 --- a/plugin/reborn/main.go +++ b/plugin/reborn/main.go @@ -5,7 +5,8 @@ import ( "fmt" "math/rand" - control "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" wr "github.com/mroth/weightedrand" "github.com/sirupsen/logrus" zero "github.com/wdvxdr1123/ZeroBot" @@ -18,26 +19,31 @@ func init() { Help: "投胎\n- reborn", PublicDataFolder: "Reborn", }) - go func() { - datapath := en.DataFolder() - jsonfile := datapath + "rate.json" - area := make(rate, 226) - err := load(&area, jsonfile) - if err != nil { - panic(err) - } - choices := make([]wr.Choice, len(area)) - for i, a := range area { - choices[i].Item = a.Name - choices[i].Weight = uint(a.Weight * 1e9) - } - areac, err = wr.NewChooser(choices...) - if err != nil { - panic(err) - } - logrus.Printf("[Reborn]读取%d个国家/地区", len(area)) - }() - en.OnFullMatch("reborn").SetBlock(true). + + en.OnFullMatch("reborn", ctxext.DoOnceOnSuccess( + func(ctx *zero.Ctx) bool { + datapath := en.DataFolder() + jsonfile := datapath + "rate.json" + area := make(rate, 226) + err := load(&area, jsonfile) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + choices := make([]wr.Choice, len(area)) + for i, a := range area { + choices[i].Item = a.Name + choices[i].Weight = uint(a.Weight * 1e9) + } + areac, err = wr.NewChooser(choices...) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + logrus.Printf("[Reborn]读取%d个国家/地区", len(area)) + return true + }, + )).SetBlock(true). Handle(func(ctx *zero.Ctx) { if rand.Int31() > 1<<27 { ctx.SendChain(message.At(ctx.Event.UserID), message.Text(fmt.Sprintf("投胎成功!\n您出生在 %s, 是 %s。", randcoun(), randgen()))) diff --git a/plugin/setutime/setu_geter.go b/plugin/setutime/setu_geter.go index acc202d7..06aec80d 100644 --- a/plugin/setutime/setu_geter.go +++ b/plugin/setutime/setu_geter.go @@ -59,22 +59,25 @@ func init() { // 插件主体 PublicDataFolder: "SetuTime", }) - go func() { + getdb := ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { // 如果数据库不存在则下载 pool.db.DBPath = engine.DataFolder() + "SetuTime.db" _, _ = fileutil.GetLazyData(pool.db.DBPath, false, false) err := pool.db.Open() if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } for _, imgtype := range pool.List() { if err := pool.db.Create(imgtype, &pixiv.Illust{}); err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } } - }() + return true + }) - engine.OnRegex(`^来份(.+)$`, ctxext.FirstValueInList(pool)).SetBlock(true).Limit(ctxext.LimitByUser). + engine.OnRegex(`^来份(.+)$`, getdb, ctxext.FirstValueInList(pool)).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { var imgtype = ctx.State["regex_matched"].([]string)[1] // 补充池子 @@ -94,7 +97,7 @@ func init() { // 插件主体 } }) - engine.OnRegex(`^添加(.+)\s?(\d+)$`, zero.SuperUserPermission).SetBlock(true). + engine.OnRegex(`^添加(.+)\s?(\d+)$`, zero.SuperUserPermission, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { var ( imgtype = ctx.State["regex_matched"].([]string)[1] @@ -108,7 +111,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("成功向分类", imgtype, "添加图片", id)) }) - engine.OnRegex(`^删除(.+)\s?(\d+)$`, ctxext.FirstValueInList(pool), zero.SuperUserPermission).SetBlock(true). + engine.OnRegex(`^删除(.+)\s?(\d+)$`, getdb, ctxext.FirstValueInList(pool), zero.SuperUserPermission).SetBlock(true). Handle(func(ctx *zero.Ctx) { var ( imgtype = ctx.State["regex_matched"].([]string)[1] @@ -123,7 +126,7 @@ func init() { // 插件主体 }) // 查询数据库涩图数量 - engine.OnFullMatchGroup([]string{">setu status"}).SetBlock(true). + engine.OnFullMatch(">setu status", getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { state := []string{"[SetuTime]"} pool.dbmu.RLock() diff --git a/plugin/tiangou/tiangou.go b/plugin/tiangou/tiangou.go index 325a1058..7f97a2a4 100644 --- a/plugin/tiangou/tiangou.go +++ b/plugin/tiangou/tiangou.go @@ -26,22 +26,29 @@ func init() { PublicDataFolder: "Tiangou", }) - go func() { - dbpath := en.DataFolder() - db.DBPath = dbpath + "tiangou.db" - _, err := file.GetLazyData(db.DBPath, false, true) - if err != nil { - panic(err) - } - err = db.Create("tiangou", &tiangou{}) - if err != nil { - panic(err) - } - c, _ := db.Count("tiangou") - logrus.Infoln("[tiangou]加载", c, "条舔狗日记") - }() - - en.OnFullMatch("舔狗日记").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) { + en.OnFullMatch("舔狗日记", ctxext.DoOnceOnSuccess( + func(ctx *zero.Ctx) bool { + dbpath := en.DataFolder() + db.DBPath = dbpath + "tiangou.db" + _, err := file.GetLazyData(db.DBPath, false, true) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + err = db.Create("tiangou", &tiangou{}) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + c, err := db.Count("tiangou") + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + logrus.Infoln("[tiangou]加载", c, "条舔狗日记") + return true + }, + )).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) { var t tiangou err := db.Pick("tiangou", &t) if err != nil { diff --git a/plugin/vtb_quotation/vtb_quotation.go b/plugin/vtb_quotation/vtb_quotation.go index 4a82e975..34b06e04 100644 --- a/plugin/vtb_quotation/vtb_quotation.go +++ b/plugin/vtb_quotation/vtb_quotation.go @@ -18,6 +18,7 @@ import ( "github.com/wdvxdr1123/ZeroBot/utils/helper" control "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/zbputils/file" "github.com/FloatTech/zbputils/img/text" "github.com/FloatTech/zbputils/web" @@ -40,14 +41,21 @@ func init() { }) dbfile := engine.DataFolder() + "vtb.db" storePath := engine.DataFolder() + "store/" - go func() { + getdb := ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { err := os.MkdirAll(storePath, 0755) if err != nil { - panic(err) + ctx.SendChain(message.Text("ERROR:", err)) + return false } - _, _ = file.GetLazyData(dbfile, false, false) - }() - engine.OnFullMatch("vtb语录").SetBlock(true). + _, err = file.GetLazyData(dbfile, false, false) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + return true + }) + + engine.OnFullMatch("vtb语录", getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { var firstIndex int var secondIndex int @@ -238,7 +246,7 @@ func init() { } } }) - engine.OnFullMatch("随机vtb").SetBlock(true). + engine.OnFullMatch("随机vtb", getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { db, err := model.Open(dbfile) if err != nil { @@ -274,7 +282,7 @@ func init() { ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile)) } }) - engine.OnFullMatch("更新vtb", zero.SuperUserPermission).SetBlock(true). + engine.OnFullMatch("更新vtb", zero.SuperUserPermission, getdb).SetBlock(true). Handle(func(ctx *zero.Ctx) { ctx.Send("少女祈祷中......") db := model.Initialize(dbfile) diff --git a/plugin/wordle/wordle.go b/plugin/wordle/wordle.go index b120941e..257e349c 100644 --- a/plugin/wordle/wordle.go +++ b/plugin/wordle/wordle.go @@ -9,10 +9,12 @@ import ( "sort" "strings" "sync" + "sync/atomic" "time" "github.com/FloatTech/AnimeAPI/tl" + "github.com/FloatTech/zbputils/binary" "github.com/FloatTech/zbputils/control" "github.com/FloatTech/zbputils/ctxext" "github.com/FloatTech/zbputils/file" @@ -55,10 +57,7 @@ type dictionary map[int]struct { cet4 []string } -var ( - words = make(dictionary) - wordsmu sync.Mutex -) +var words = make(dictionary) func init() { en := control.Register("wordle", &control.Options{ @@ -77,35 +76,53 @@ func init() { ) }), )) - for i := 5; i <= 7; i++ { - go func(i int) { - dc, err := file.GetLazyData(fmt.Sprintf("%scet-4_%d.txt", en.DataFolder(), i), true, true) - if err != nil { - panic(err) + + en.OnRegex(`(个人|团队)(五阶|六阶|七阶)?猜单词`, zero.OnlyGroup, ctxext.DoOnceOnSuccess( + func(ctx *zero.Ctx) bool { + var errcnt uint32 + var wg sync.WaitGroup + var mu sync.Mutex + for i := 5; i <= 7; i++ { + wg.Add(2) + go func(i int) { + defer wg.Done() + dc, err := file.GetLazyData(fmt.Sprintf("%scet-4_%d.txt", en.DataFolder(), i), true, true) + if err != nil { + atomic.AddUint32(&errcnt, 1) + return + } + c := strings.Split(binary.BytesToString(dc), "\n") + sort.Strings(c) + mu.Lock() + tmp := words[i] + tmp.cet4 = c + words[i] = tmp + mu.Unlock() + }(i) + go func(i int) { + defer wg.Done() + dd, err := file.GetLazyData(fmt.Sprintf("%sdict_%d.txt", en.DataFolder(), i), true, true) + if err != nil { + atomic.AddUint32(&errcnt, 1) + return + } + d := strings.Split(binary.BytesToString(dd), "\n") + sort.Strings(d) + mu.Lock() + tmp := words[i] + tmp.dict = d + words[i] = tmp + mu.Unlock() + }(i) } - c := strings.Split(string(dc), "\n") - sort.Strings(c) - wordsmu.Lock() - tmp := words[i] - tmp.cet4 = c - words[i] = tmp - wordsmu.Unlock() - }(i) - go func(i int) { - dd, err := file.GetLazyData(fmt.Sprintf("%sdict_%d.txt", en.DataFolder(), i), true, true) - if err != nil { - panic(err) + wg.Wait() + if errcnt > 0 { + ctx.SendChain(message.Text("ERROR:下载字典时发生", errcnt, "个错误")) + return false } - d := strings.Split(string(dd), "\n") - sort.Strings(d) - wordsmu.Lock() - tmp := words[i] - tmp.dict = d - words[i] = tmp - wordsmu.Unlock() - }(i) - } - en.OnRegex(`(个人|团队)(五阶|六阶|七阶)?猜单词`, zero.OnlyGroup).SetBlock(true).Limit(ctxext.LimitByUser). + return true + }, + )).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { class := classdict[ctx.State["regex_matched"].([]string)[2]] target := words[class].cet4[rand.Intn(len(words[class].cet4))] diff --git a/plugin/ymgal/model.go b/plugin/ymgal/model.go index 4a845d4a..0ffd921b 100644 --- a/plugin/ymgal/model.go +++ b/plugin/ymgal/model.go @@ -38,22 +38,21 @@ func (ymgal) TableName() string { } // initialize 初始化ymgaldb数据库 -func initialize(dbpath string) *ymgaldb { - var err error +func initialize(dbpath string) (db *ymgaldb, err error) { if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) { // 生成文件 f, err := os.Create(dbpath) if err != nil { - return nil + return nil, err } - defer f.Close() + _ = f.Close() } gdb, err := gorm.Open("sqlite3", dbpath) if err != nil { - panic(err) + return } gdb.AutoMigrate(&ymgal{}) - return (*ymgaldb)(gdb) + return (*ymgaldb)(gdb), nil } func (gdb *ymgaldb) insertOrUpdateYmgalByID(id int64, title, pictureType, pictureDescription, pictureList string) (err error) { diff --git a/plugin/ymgal/ymgal.go b/plugin/ymgal/ymgal.go index ac09cf22..739df257 100644 --- a/plugin/ymgal/ymgal.go +++ b/plugin/ymgal/ymgal.go @@ -18,11 +18,20 @@ func init() { PublicDataFolder: "Ymgal", }) dbfile := engine.DataFolder() + "ymgal.db" - go func() { - _, _ = file.GetLazyData(dbfile, false, false) - gdb = initialize(dbfile) - }() - engine.OnRegex("^随机gal(CG|表情包)$").Limit(ctxext.LimitByUser).SetBlock(true). + getdb := ctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { + _, err := file.GetLazyData(dbfile, false, false) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + gdb, err = initialize(dbfile) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err)) + return false + } + return true + }) + engine.OnRegex("^随机gal(CG|表情包)$", getdb).Limit(ctxext.LimitByUser).SetBlock(true). Handle(func(ctx *zero.Ctx) { ctx.Send("少女祈祷中......") pictureType := ctx.State["regex_matched"].([]string)[1] @@ -34,7 +43,7 @@ func init() { } sendYmgal(y, ctx) }) - engine.OnRegex("^gal(CG|表情包)([一-龥ぁ-んァ-ヶA-Za-z0-9]{1,25})$").Limit(ctxext.LimitByUser).SetBlock(true). + engine.OnRegex("^gal(CG|表情包)([一-龥ぁ-んァ-ヶA-Za-z0-9]{1,25})$", getdb).Limit(ctxext.LimitByUser).SetBlock(true). Handle(func(ctx *zero.Ctx) { ctx.Send("少女祈祷中......") pictureType := ctx.State["regex_matched"].([]string)[1] @@ -47,7 +56,7 @@ func init() { } sendYmgal(y, ctx) }) - engine.OnFullMatch("更新gal", zero.SuperUserPermission).SetBlock(true).Handle( + engine.OnFullMatch("更新gal", zero.SuperUserPermission, getdb).SetBlock(true).Handle( func(ctx *zero.Ctx) { ctx.Send("少女祈祷中......") err := updatePic()