From 793cac09cbbcd8c73493153646e47fb0ecc02395 Mon Sep 17 00:00:00 2001 From: himawari <54976075+guohuiyuan@users.noreply.github.com> Date: Sat, 4 Dec 2021 20:46:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BB=9F=E8=AE=A1=E7=9D=A1?= =?UTF-8?q?=E7=9C=A0=E6=97=B6=E9=97=B4=E5=92=8C=E6=B7=BB=E5=8A=A0=E5=8D=8F?= =?UTF-8?q?=E7=A8=8B=E9=87=8C=E7=9A=84=E5=BC=82=E5=B8=B8=E6=8D=95=E8=8E=B7?= =?UTF-8?q?=20(#84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix:捕获协程异常 * feat:添加睡眠时间 * feat:添加睡眠管理功能 * fix:修改对标时间 * fix:修改注释函数名,使用一个时间 * feat:让大家能够更加清楚的看到每一个功能 * feat:把群管放在control,增加退群信息 * fix:不会recover * fix:原本的正则限制机器人回复回复的消息,故去掉正则 * fix:添加服务详情,整理manager * feat:chat进control Co-authored-by: Guohuiyuan --- README.md | 2 +- control/rule.go | 36 +++++++++ main.go | 14 ++-- plugin_atri/atri.go | 14 +++- plugin_chat/chat.go | 18 +++-- plugin_choose/choose.go | 2 +- plugin_manager/manager.go | 77 ++++++++++-------- plugin_moyu/run.go | 2 +- plugin_qingyunke/qingyunke.go | 6 +- plugin_qingyunke/request.go | 21 ----- plugin_sleep_manage/data.go | 24 ++++++ plugin_sleep_manage/model/model.go | 109 ++++++++++++++++++++++++++ plugin_sleep_manage/sleep_manage.go | 78 ++++++++++++++++++ plugin_vtb_quotation/model/model.go | 11 ++- plugin_vtb_quotation/vtb_quotation.go | 2 +- 15 files changed, 339 insertions(+), 77 deletions(-) delete mode 100644 plugin_qingyunke/request.go create mode 100644 plugin_sleep_manage/data.go create mode 100644 plugin_sleep_manage/model/model.go create mode 100644 plugin_sleep_manage/sleep_manage.go diff --git a/README.md b/README.md index fbe6e2a6..fad2cf9a 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ zerobot -h -t token -u url [-d|w] [-g 监听地址:端口] qq1 qq2 qq3 ... - [x] 修改头衔[@xxx][xxx] - [x] 申请头衔[xxx] - [x] 踢出群聊[@xxx] - - [x] 退出群聊[群号] + - [x] 退出群聊[群号]@Bot - [x] *入群欢迎 - [x] *退群通知 - [x] 设置欢迎语[欢迎~] diff --git a/control/rule.go b/control/rule.go index 1b955594..6335d287 100644 --- a/control/rule.go +++ b/control/rule.go @@ -309,6 +309,42 @@ func init() { }) ctx.SendChain(message.Text(msg)) }) + + zero.OnCommandGroup([]string{"服务详情", "service_detail"}, zero.OnlyGroup). + Handle(func(ctx *zero.Ctx) { + var m message.Message + m = append(m, + message.CustomNode( + ctx.Event.Sender.NickName, + ctx.Event.UserID, + "---服务详情---", + )) + i := 0 + ForEach(func(key string, manager *Control) bool { + service, _ := Lookup(key) + help := service.options.Help + i++ + msg := strconv.Itoa(i) + `: ` + if manager.IsEnabledIn(ctx.Event.GroupID) { + msg += "●" + key + } else { + msg += "○" + key + } + msg += "\n" + help + m = append(m, + message.CustomNode( + ctx.Event.Sender.NickName, + ctx.Event.UserID, + msg, + )) + return true + }) + + ctx.SendGroupForwardMessage( + ctx.Event.GroupID, + m, + ) + }) } } mu.Unlock() diff --git a/main.go b/main.go index 2ae46489..ede2bd89 100644 --- a/main.go +++ b/main.go @@ -18,12 +18,13 @@ import ( _ "github.com/FloatTech/ZeroBot-Plugin/plugin_qingyunke" // 青云客 // 实用类 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_b14" // base16384加解密 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_github" // 搜索GitHub仓库 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_manager" // 群管 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_nbnhhsh" // 拼音首字母缩写释义工具 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_runcode" // 在线运行代码 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin_translation" // 翻译 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_b14" // base16384加解密 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_github" // 搜索GitHub仓库 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_manager" // 群管 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_nbnhhsh" // 拼音首字母缩写释义工具 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_runcode" // 在线运行代码 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_sleep_manage" // 统计睡眠时间 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin_translation" // 翻译 // 娱乐类 // _ "github.com/FloatTech/ZeroBot-Plugin/plugin_wtf" // 鬼东西 @@ -120,6 +121,7 @@ func main() { // 帮助 zero.OnFullMatchGroup([]string{"/help", ".help", "菜单"}, zero.OnlyToMe).SetBlock(true).FirstPriority(). Handle(func(ctx *zero.Ctx) { + ctx.SendChain(message.Text("可发送\"/服务详情\"等指令,查看bot功能")) ctx.SendChain(message.Text(banner)) }) zero.RunAndBlock( diff --git a/plugin_atri/atri.go b/plugin_atri/atri.go index b52415fb..0c3b091c 100644 --- a/plugin_atri/atri.go +++ b/plugin_atri/atri.go @@ -20,13 +20,21 @@ const ( // 服务名 servicename = "atri" // ATRI 所有命令的优先级 - prio = 2 + prio = 5 // ATRI 表情的 codechina 镜像 res = "https://codechina.csdn.net/u011570312/ZeroBot-Plugin/-/raw/master/plugin_atri/" ) func init() { // 插件主体 - engine := control.Register(servicename, &control.Options{}) + engine := control.Register(servicename, &control.Options{ + DisableOnDefault: false, + Help: "本插件基于 ATRI ,为 Golang 移植版\n" + + "- ATRI醒醒\n- ATRI睡吧\n- 萝卜子\n- 喜欢|爱你|爱|suki|daisuki|すき|好き|贴贴|老婆|亲一个|mua\n" + + "- 草你妈|操你妈|脑瘫|废柴|fw|废物|战斗|爬|爪巴|sb|SB|傻B\n- 早安|早哇|早上好|ohayo|哦哈哟|お早う|早好|早|早早早\n" + + "- 中午好|午安|午好\n- 晚安|oyasuminasai|おやすみなさい|晚好|晚上好\n- 高性能|太棒了|すごい|sugoi|斯国一|よかった\n" + + "- 没事|没关系|大丈夫|还好|不要紧|没出大问题|没伤到哪\n- 好吗|是吗|行不行|能不能|可不可以\n- 啊这\n- 我好了\n- ?|?|¿\n" + + "- 离谱\n- 答应我", + }) zero.OnFullMatch("ATRI醒醒", zero.AdminPermission).SetBlock(true).SetPriority(prio). Handle(func(ctx *zero.Ctx) { c, ok := control.Lookup(servicename) @@ -65,7 +73,7 @@ func init() { // 插件主体 process.SleepAbout1sTo2s() ctx.SendChain(randImage("FN.jpg", "WQ.jpg", "WQ1.jpg")) }) - engine.OnFullMatchGroup([]string{"早安", "早哇", "早上好", "ohayo", "哦哈哟", "お早う", "早好", "早"}).SetBlock(true).SetPriority(prio). + engine.OnFullMatchGroup([]string{"早安", "早哇", "早上好", "ohayo", "哦哈哟", "お早う", "早好", "早", "早早早"}).SetBlock(true).SetPriority(prio). Handle(func(ctx *zero.Ctx) { now := time.Now().Hour() process.SleepAbout1sTo2s() diff --git a/plugin_chat/chat.go b/plugin_chat/chat.go index e1110927..bc96964f 100644 --- a/plugin_chat/chat.go +++ b/plugin_chat/chat.go @@ -2,6 +2,7 @@ package chat import ( + "github.com/FloatTech/ZeroBot-Plugin/control" "math/rand" "strconv" "time" @@ -13,9 +14,14 @@ import ( var poke = rate.NewManager(time.Minute*5, 8) // 戳一戳 +var engine = control.Register("chat", &control.Options{ + DisableOnDefault: false, + Help: "chat\n- [BOT名字]\n- [戳一戳BOT]\n- 空调开\n- 空调关\n- 群温度\n- 设置温度[正整数]", +}) + func init() { // 插件主体 // 被喊名字 - zero.OnFullMatch("", zero.OnlyToMe).SetBlock(false).FirstPriority(). + engine.OnFullMatch("", zero.OnlyToMe).SetBlock(true).FirstPriority(). Handle(func(ctx *zero.Ctx) { var nickname = zero.BotConfig.NickName[0] time.Sleep(time.Second * 1) @@ -29,7 +35,7 @@ func init() { // 插件主体 )) }) // 戳一戳 - zero.On("notice/notify/poke", zero.OnlyToMe).SetBlock(false).FirstPriority(). + engine.On("notice/notify/poke", zero.OnlyToMe).SetBlock(false).FirstPriority(). Handle(func(ctx *zero.Ctx) { var nickname = zero.BotConfig.NickName[0] switch { @@ -48,18 +54,18 @@ func init() { // 插件主体 // 群空调 var AirConditTemp = map[int64]int{} var AirConditSwitch = map[int64]bool{} - zero.OnFullMatch("空调开").SetBlock(true).FirstPriority(). + engine.OnFullMatch("空调开").SetBlock(true).FirstPriority(). Handle(func(ctx *zero.Ctx) { AirConditSwitch[ctx.Event.GroupID] = true ctx.SendChain(message.Text("❄️哔~")) }) - zero.OnFullMatch("空调关").SetBlock(true).FirstPriority(). + engine.OnFullMatch("空调关").SetBlock(true).FirstPriority(). Handle(func(ctx *zero.Ctx) { AirConditSwitch[ctx.Event.GroupID] = false delete(AirConditTemp, ctx.Event.GroupID) ctx.SendChain(message.Text("💤哔~")) }) - zero.OnRegex(`设置温度(\d+)`).SetBlock(true).FirstPriority(). + engine.OnRegex(`设置温度(\d+)`).SetBlock(true).FirstPriority(). Handle(func(ctx *zero.Ctx) { if _, exist := AirConditTemp[ctx.Event.GroupID]; !exist { AirConditTemp[ctx.Event.GroupID] = 26 @@ -78,7 +84,7 @@ func init() { // 插件主体 )) } }) - zero.OnFullMatch(`群温度`).SetBlock(true).FirstPriority(). + engine.OnFullMatch(`群温度`).SetBlock(true).FirstPriority(). Handle(func(ctx *zero.Ctx) { if _, exist := AirConditTemp[ctx.Event.GroupID]; !exist { AirConditTemp[ctx.Event.GroupID] = 26 diff --git a/plugin_choose/choose.go b/plugin_choose/choose.go index 246b3503..5001ca04 100644 --- a/plugin_choose/choose.go +++ b/plugin_choose/choose.go @@ -17,7 +17,7 @@ func init() { DisableOnDefault: false, Help: "choose\n" + "- 选择可口可乐还是百事可乐\n" + - "- 选择肯德基还是麦当劳还是必胜客\n", + "- 选择肯德基还是麦当劳还是必胜客", }) engine.OnPrefix("选择").SetBlock(true).FirstPriority().Handle(handle) } diff --git a/plugin_manager/manager.go b/plugin_manager/manager.go index cd60df79..e9ead18e 100644 --- a/plugin_manager/manager.go +++ b/plugin_manager/manager.go @@ -3,6 +3,7 @@ package manager import ( "fmt" + "github.com/FloatTech/ZeroBot-Plugin/control" "io" "math/rand" "os" @@ -38,7 +39,7 @@ const ( "- 修改头衔@QQ XXX\n" + "- 申请头衔 XXX\n" + "- 踢出群聊@QQ\n" + - "- 退出群聊 1234\n" + + "- 退出群聊 1234@bot\n" + "- 群聊转发 1234 XXX\n" + "- 私聊转发 0000 XXX\n" + "- 在MM月dd日的hh点mm分时(用http://url)提醒大家XXX\n" + @@ -58,6 +59,10 @@ var ( limit = rate.NewManager(time.Minute*5, 2) clock timer.Clock ) +var engine = control.Register("manager", &control.Options{ + DisableOnDefault: false, + Help: hint, +}) func init() { // 插件主体 loadConfig() @@ -65,13 +70,8 @@ func init() { // 插件主体 time.Sleep(time.Second + time.Millisecond*time.Duration(rand.Intn(1000))) clock = timer.NewClock(timerfile) }() - // 菜单 - zero.OnFullMatch("群管系统", zero.AdminPermission).SetBlock(true).FirstPriority(). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(message.Text(hint)) - }) // 升为管理 - zero.OnRegex(`^升为管理.*?(\d+)`, zero.OnlyGroup, zero.SuperUserPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^升为管理.*?(\d+)`, zero.OnlyGroup, zero.SuperUserPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupAdmin( ctx.Event.GroupID, @@ -86,7 +86,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text(nickname + " 升为了管理~")) }) // 取消管理 - zero.OnRegex(`^取消管理.*?(\d+)`, zero.OnlyGroup, zero.SuperUserPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^取消管理.*?(\d+)`, zero.OnlyGroup, zero.SuperUserPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupAdmin( ctx.Event.GroupID, @@ -101,7 +101,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("残念~ " + nickname + " 暂时失去了管理员的资格")) }) // 踢出群聊 - zero.OnRegex(`^踢出群聊.*?(\d+)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^踢出群聊.*?(\d+)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupKick( ctx.Event.GroupID, @@ -116,7 +116,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("残念~ " + nickname + " 被放逐")) }) // 退出群聊 - zero.OnRegex(`^退出群聊.*?(\d+)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^退出群聊.*?(\d+)`, zero.OnlyToMe, zero.SuperUserPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupLeave( strToInt(ctx.State["regex_matched"].([]string)[1]), // 要退出的群的群号 @@ -124,7 +124,7 @@ func init() { // 插件主体 ) }) // 开启全体禁言 - zero.OnRegex(`^开启全员禁言$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^开启全员禁言$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupWholeBan( ctx.Event.GroupID, @@ -133,7 +133,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("全员自闭开始~")) }) // 解除全员禁言 - zero.OnRegex(`^解除全员禁言$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^解除全员禁言$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupWholeBan( ctx.Event.GroupID, @@ -142,7 +142,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("全员自闭结束~")) }) // 禁言 - zero.OnRegex(`^禁言.*?(\d+).*?\s(\d+)(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^禁言.*?(\d+).*?\s(\d+)(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { duration := strToInt(ctx.State["regex_matched"].([]string)[2]) switch ctx.State["regex_matched"].([]string)[3] { @@ -166,7 +166,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("小黑屋收留成功~")) }) // 解除禁言 - zero.OnRegex(`^解除禁言.*?(\d+)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^解除禁言.*?(\d+)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupBan( ctx.Event.GroupID, @@ -176,7 +176,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("小黑屋释放成功~")) }) // 自闭禁言 - zero.OnRegex(`^(我要自闭|禅定).*?(\d+)(.*)`, zero.OnlyGroup).SetBlock(true).SetPriority(40). + engine.OnRegex(`^(我要自闭|禅定).*?(\d+)(.*)`, zero.OnlyGroup).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { duration := strToInt(ctx.State["regex_matched"].([]string)[2]) switch ctx.State["regex_matched"].([]string)[3] { @@ -200,7 +200,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("那我就不手下留情了~")) }) // 修改名片 - zero.OnRegex(`^修改名片.*?(\d+).*?\s(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^修改名片.*?(\d+).*?\s(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupCard( ctx.Event.GroupID, @@ -210,7 +210,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("嗯!已经修改了")) }) // 修改头衔 - zero.OnRegex(`^修改头衔.*?(\d+).*?\s(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^修改头衔.*?(\d+).*?\s(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupSpecialTitle( ctx.Event.GroupID, @@ -220,7 +220,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("嗯!已经修改了")) }) // 申请头衔 - zero.OnRegex(`^申请头衔(.*)`, zero.OnlyGroup).SetBlock(true).SetPriority(40). + engine.OnRegex(`^申请头衔(.*)`, zero.OnlyGroup).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SetGroupSpecialTitle( ctx.Event.GroupID, @@ -230,7 +230,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("嗯!不错的头衔呢~")) }) // 群聊转发 - zero.OnRegex(`^群聊转发.*?(\d+)\s(.*)`, zero.SuperUserPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^群聊转发.*?(\d+)\s(.*)`, zero.SuperUserPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { // 对CQ码进行反转义 content := ctx.State["regex_matched"].([]string)[2] @@ -243,7 +243,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("📧 --> " + ctx.State["regex_matched"].([]string)[1])) }) // 私聊转发 - zero.OnRegex(`^私聊转发.*?(\d+)\s(.*)`, zero.SuperUserPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^私聊转发.*?(\d+)\s(.*)`, zero.SuperUserPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { // 对CQ码进行反转义 content := ctx.State["regex_matched"].([]string)[2] @@ -256,7 +256,7 @@ func init() { // 插件主体 ctx.SendChain(message.Text("📧 --> " + ctx.State["regex_matched"].([]string)[1])) }) // 定时提醒 - zero.OnRegex(`^在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分时(用.+)?提醒大家(.*)`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). + engine.OnRegex(`^在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分时(用.+)?提醒大家(.*)`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { dateStrs := ctx.State["regex_matched"].([]string) ts := timer.GetFilledTimer(dateStrs, ctx.Event.SelfID, false) @@ -268,7 +268,7 @@ func init() { // 插件主体 } }) // 定时 cron 提醒 - zero.OnRegex(`^在"(.*)"时(用.+)?提醒大家(.*)`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). + engine.OnRegex(`^在"(.*)"时(用.+)?提醒大家(.*)`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { dateStrs := ctx.State["regex_matched"].([]string) var url, alert string @@ -291,7 +291,7 @@ func init() { // 插件主体 } }) // 取消定时 - zero.OnRegex(`^取消在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分的提醒`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). + engine.OnRegex(`^取消在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分的提醒`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { dateStrs := ctx.State["regex_matched"].([]string) ts := timer.GetFilledTimer(dateStrs, ctx.Event.SelfID, true) @@ -304,7 +304,7 @@ func init() { // 插件主体 } }) // 取消 cron 定时 - zero.OnRegex(`^取消在"(.*)"的提醒`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). + engine.OnRegex(`^取消在"(.*)"的提醒`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { dateStrs := ctx.State["regex_matched"].([]string) ts := timer.Timer{Cron: dateStrs[1]} @@ -317,12 +317,12 @@ func init() { // 插件主体 } }) // 列出本群所有定时 - zero.OnFullMatch("列出所有提醒", zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). + engine.OnFullMatch("列出所有提醒", zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { ctx.SendChain(message.Text(clock.ListTimers(ctx.Event.GroupID))) }) // 随机点名 - zero.OnFullMatchGroup([]string{"翻牌"}, zero.OnlyGroup).SetBlock(true).SetPriority(40). + engine.OnFullMatchGroup([]string{"翻牌"}, zero.OnlyGroup).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { if !limit.Load(ctx.Event.UserID).Acquire() { ctx.SendChain(message.Text("少女祈祷中......")) @@ -360,7 +360,7 @@ func init() { // 插件主体 ) }) // 入群欢迎 - zero.OnNotice().SetBlock(false).FirstPriority(). + engine.OnNotice().SetBlock(false).FirstPriority(). Handle(func(ctx *zero.Ctx) { if ctx.Event.NoticeType == "group_increase" && ctx.Event.SelfID != ctx.Event.UserID { word, ok := config.Welcome[ctx.Event.GroupID] @@ -408,14 +408,16 @@ func init() { // 插件主体 } }) // 退群提醒 - zero.OnNotice().SetBlock(false).SetPriority(40). + engine.OnNotice().SetBlock(false).SetPriority(40). Handle(func(ctx *zero.Ctx) { if ctx.Event.NoticeType == "group_decrease" { - ctx.SendChain(message.Text("有人跑路了~")) + userid := ctx.Event.UserID + nickname := ctx.GetStrangerInfo(userid, false).Get("nickname").String() + ctx.SendChain(message.Text(nickname, "(", userid, ")", "离开了我们~")) } }) // 设置欢迎语 - zero.OnRegex(`^设置欢迎语([\s\S]*)$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^设置欢迎语([\s\S]*)$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { config.Welcome[ctx.Event.GroupID] = ctx.State["regex_matched"].([]string)[1] if saveConfig() == nil { @@ -425,7 +427,7 @@ func init() { // 插件主体 } }) // 入群验证开关 - zero.OnRegex(`^(.*)入群验证$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). + engine.OnRegex(`^(.*)入群验证$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { option := ctx.State["regex_matched"].([]string)[1] switch option { @@ -443,7 +445,7 @@ func init() { // 插件主体 } }) // 运行 CQ 码 - zero.OnRegex(`^run(.*)$`, zero.SuperUserPermission).SetBlock(true).SetPriority(0). + engine.OnRegex(`^run(.*)$`, zero.SuperUserPermission).SetBlock(true).SetPriority(0). Handle(func(ctx *zero.Ctx) { var cmd = ctx.State["regex_matched"].([]string)[1] cmd = strings.ReplaceAll(cmd, "[", "[") @@ -451,6 +453,17 @@ func init() { // 插件主体 // 可注入,权限为主人 ctx.Send(cmd) }) + // 自动同意加好友,被邀请入群(从qingyunke移过来,先注释) + /* + engine.OnRequest().SetBlock(false).FirstPriority().Handle(func(ctx *zero.Ctx) { + if ctx.Event.RequestType == "friend" { + ctx.SetFriendAddRequest(ctx.Event.Flag, true, "") + } + if ctx.Event.RequestType == "group" && ctx.Event.SubType == "invite" { + ctx.SetGroupAddRequest(ctx.Event.Flag, "invite", true, "我爱你,mua~") + } + }) + */ } func strToInt(str string) int64 { diff --git a/plugin_moyu/run.go b/plugin_moyu/run.go index bb156351..b462de20 100644 --- a/plugin_moyu/run.go +++ b/plugin_moyu/run.go @@ -22,7 +22,7 @@ func init() { // 插件主体 DisableOnDefault: true, Help: "moyu\n" + "- 添加摸鱼提醒\n" + - "- 删除摸鱼提醒\n", + "- 删除摸鱼提醒", }).OnFullMatch("删除摸鱼提醒", zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(20). Handle(func(ctx *zero.Ctx) { m, ok := control.Lookup("moyu") diff --git a/plugin_qingyunke/qingyunke.go b/plugin_qingyunke/qingyunke.go index 7d96d3d9..3917f84f 100644 --- a/plugin_qingyunke/qingyunke.go +++ b/plugin_qingyunke/qingyunke.go @@ -32,14 +32,14 @@ func init() { // 插件主体 Help: "青云客\n" + "- @Bot 任意文本(任意一句话回复)", }) - // 回复 匹配中文、英文、数字、空格但不包括下划线等符号 - engine.OnRegex("^([\u4E00-\u9FA5A-Za-z0-9\\s]{1,30})", zero.OnlyToMe).SetBlock(true).SetPriority(prio). + // 回复 @和包括名字 + engine.OnMessage(zero.OnlyToMe).SetBlock(true).SetPriority(prio). Handle(func(ctx *zero.Ctx) { if !bucket.Load(ctx.Event.UserID).Acquire() { // 频繁触发,不回复 return } - msg := ctx.State["regex_matched"].([]string)[1] + msg := ctx.ExtractPlainText() // 调用青云客接口 reply, err := getMessage(msg) if err != nil { diff --git a/plugin_qingyunke/request.go b/plugin_qingyunke/request.go deleted file mode 100644 index cb986c25..00000000 --- a/plugin_qingyunke/request.go +++ /dev/null @@ -1,21 +0,0 @@ -package qingyunke - -// TODO: 移动到 manager 搭配自动验证使用 - -/* -import ( - zero "github.com/wdvxdr1123/ZeroBot" -) - -//自动同意加群,加好友 -func init() { - zero.OnRequest().SetBlock(false).FirstPriority().Handle(func(ctx *zero.Ctx) { - if ctx.Event.RequestType == "friend" { - ctx.SetFriendAddRequest(ctx.Event.Flag, true, "") - } - if ctx.Event.RequestType == "group" && ctx.Event.SubType == "invite" { - ctx.SetGroupAddRequest(ctx.Event.Flag, "invite", true, "我爱你,mua~") - } - }) -} -*/ diff --git a/plugin_sleep_manage/data.go b/plugin_sleep_manage/data.go new file mode 100644 index 00000000..f8cd2ce6 --- /dev/null +++ b/plugin_sleep_manage/data.go @@ -0,0 +1,24 @@ +package plugin_sleep_manage + +import ( + "github.com/FloatTech/ZeroBot-Plugin/plugin_sleep_manage/model" + "github.com/FloatTech/ZeroBot-Plugin/utils/process" + log "github.com/sirupsen/logrus" + "os" +) + +func init() { + go func() { + defer func() { + //recover() //可以打印panic的错误信息 + if err := recover(); err != nil { //产生了panic异常 + log.Println(err) + } + + }() //别忘了(), 调用此匿名函数 + process.SleepAbout1sTo2s() + _ = os.MkdirAll(dbpath, 0755) + model.Initialize(dbfile) + }() + +} diff --git a/plugin_sleep_manage/model/model.go b/plugin_sleep_manage/model/model.go new file mode 100644 index 00000000..fe705cec --- /dev/null +++ b/plugin_sleep_manage/model/model.go @@ -0,0 +1,109 @@ +package model + +import ( + "github.com/jinzhu/gorm" + _ "github.com/logoove/sqlite" + log "github.com/sirupsen/logrus" + "os" + "time" +) + +type SleepDB gorm.DB + +func Initialize(dbpath string) *SleepDB { + var err error + if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) { + // 生成文件 + f, err := os.Create(dbpath) + if err != nil { + return nil + } + defer f.Close() + } + gdb, err := gorm.Open("sqlite3", dbpath) + if err != nil { + panic(err) + } + gdb.AutoMigrate(&SleepManage{}) + return (*SleepDB)(gdb) +} + +func Open(dbpath string) (*SleepDB, error) { + db, err := gorm.Open("sqlite3", dbpath) + if err != nil { + return nil, err + } else { + return (*SleepDB)(db), nil + } +} + +func (sdb *SleepDB) Close() error { + db := (*gorm.DB)(sdb) + return db.Close() +} + +type SleepManage struct { + gorm.Model + GroupId int64 `gorm:"column:group_id"` + UserId int64 `gorm:"column:user_id"` + SleepTime time.Time `gorm:"column:sleep_time"` +} + +func (SleepManage) TableName() string { + return "sleep_manage" +} + +// 更新睡眠时间 +func (sdb *SleepDB) Sleep(groupId, userId int64) (position int, awakeTime time.Duration) { + db := (*gorm.DB)(sdb) + now := time.Now() + + today := now.Add(-time.Hour*time.Duration(3+now.Hour()) - time.Minute*time.Duration(now.Minute()) - time.Second*time.Duration(now.Second())) + st := SleepManage{ + GroupId: groupId, + UserId: userId, + SleepTime: now, + } + if err := db.Debug().Model(&SleepManage{}).Where("group_id = ? and user_id = ?", groupId, userId).First(&st).Error; err != nil { + // error handling... + if gorm.IsRecordNotFoundError(err) { + db.Debug().Model(&SleepManage{}).Create(&st) // newUser not user + } + } else { + log.Println("sleeptime为", st) + awakeTime = now.Sub(st.SleepTime) + db.Debug().Model(&SleepManage{}).Where("group_id = ? and user_id = ?", groupId, userId).Update( + map[string]interface{}{ + "sleep_time": now, + }) + } + db.Debug().Model(&SleepManage{}).Where("group_id = ? and sleep_time <= ? and sleep_time >= ?", groupId, now, today).Count(&position) + return position, awakeTime +} + +// 更新起床时间 +func (sdb *SleepDB) GetUp(groupId, userId int64) (position int, sleepTime time.Duration) { + db := (*gorm.DB)(sdb) + now := time.Now() + today := now.Add(-time.Hour*time.Duration(-6+now.Hour()) - time.Minute*time.Duration(now.Minute()) - time.Second*time.Duration(now.Second())) + st := SleepManage{ + GroupId: groupId, + UserId: userId, + SleepTime: now, + } + if err := db.Debug().Model(&SleepManage{}).Where("group_id = ? and user_id = ?", groupId, userId).First(&st).Error; err != nil { + // error handling... + if gorm.IsRecordNotFoundError(err) { + db.Debug().Model(&SleepManage{}).Create(&st) // newUser not user + } + } else { + log.Println("sleeptime为", st) + sleepTime = now.Sub(st.SleepTime) + db.Debug().Model(&SleepManage{}).Where("group_id = ? and user_id = ?", groupId, userId).Update( + map[string]interface{}{ + "get_up_time": now, + }) + } + db.Debug().Model(&SleepManage{}).Where("group_id = ? and sleep_time <= ? and sleep_time >= ?", groupId, now, today).Count(&position) + return position, sleepTime +} diff --git a/plugin_sleep_manage/sleep_manage.go b/plugin_sleep_manage/sleep_manage.go new file mode 100644 index 00000000..9eb37678 --- /dev/null +++ b/plugin_sleep_manage/sleep_manage.go @@ -0,0 +1,78 @@ +package plugin_sleep_manage + +import ( + "fmt" + "github.com/FloatTech/ZeroBot-Plugin/control" + "github.com/FloatTech/ZeroBot-Plugin/plugin_sleep_manage/model" + log "github.com/sirupsen/logrus" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" + "time" +) + +const dbpath = "data/SleepManage/" +const dbfile = dbpath + "sleepmanage.db" +const prio = 4 + +var engine = control.Register("sleepmanage", &control.Options{ + DisableOnDefault: false, + Help: "sleepmanage\n- 早安\n- 晚安", +}) + +func init() { + engine.OnFullMatch("早安", isMorning, zero.OnlyGroup).SetBlock(true).SetPriority(prio). + Handle(func(ctx *zero.Ctx) { + db, err := model.Open(dbfile) + if err != nil { + log.Errorln(err) + return + } + position, getUpTime := db.GetUp(ctx.Event.GroupID, ctx.Event.UserID) + log.Println(position, getUpTime) + hour, minute, second := timeDuration(getUpTime) + if (hour == 0 && minute == 0 && second == 0) || hour >= 24 { + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(fmt.Sprintf("早安成功!你是今天第%d个起床的", position))) + } else { + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(fmt.Sprintf("早安成功!你的睡眠时长为%d时%d分%d秒,你是今天第%d个起床的", hour, minute, second, position))) + } + db.Close() + + }) + engine.OnFullMatch("晚安", isEvening, zero.OnlyGroup).SetBlock(true).SetPriority(prio). + Handle(func(ctx *zero.Ctx) { + db, err := model.Open(dbfile) + if err != nil { + log.Errorln(err) + return + } + position, sleepTime := db.Sleep(ctx.Event.GroupID, ctx.Event.UserID) + log.Println(position, sleepTime) + hour, minute, second := timeDuration(sleepTime) + if (hour == 0 && minute == 0 && second == 0) || hour >= 24 { + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(fmt.Sprintf("晚安成功!你是今天第%d个睡觉的", position))) + } else { + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(fmt.Sprintf("晚安成功!你的清醒时长为%d时%d分%d秒,你是今天第%d个睡觉的", hour, minute, second, position))) + } + db.Close() + + }) +} + +func timeDuration(time time.Duration) (hour, minute, second int64) { + hour = int64(time) / (1000 * 1000 * 1000 * 60 * 60) + minute = (int64(time) - hour*(1000*1000*1000*60*60)) / (1000 * 1000 * 1000 * 60) + second = (int64(time) - hour*(1000*1000*1000*60*60) - minute*(1000*1000*1000*60)) / (1000 * 1000 * 1000) + return hour, minute, second +} + +//只统计6点到12点的早安 +func isMorning(ctx *zero.Ctx) bool { + now := time.Now().Hour() + return now >= 6 && now <= 12 +} + +//只统计21点到凌晨3点的晚安 +func isEvening(ctx *zero.Ctx) bool { + now := time.Now().Hour() + return now >= 21 || now <= 3 +} diff --git a/plugin_vtb_quotation/model/model.go b/plugin_vtb_quotation/model/model.go index 17ceb39d..9fbead5e 100644 --- a/plugin_vtb_quotation/model/model.go +++ b/plugin_vtb_quotation/model/model.go @@ -194,32 +194,35 @@ func (vdb *VtbDB) Close() error { const vtbUrl = "https://vtbkeyboard.moe/api/get_vtb_list" -func (vdb *VtbDB) GetVtbList() []string { +func (vdb *VtbDB) GetVtbList() (uidList []string) { db := (*gorm.DB)(vdb) client := &http.Client{} req, err := http.NewRequest("GET", vtbUrl, nil) if err != nil { logrus.Errorln(err) + return } // 自定义Header req.Header.Set("User-Agent", randua()) resp, err := client.Do(req) if err != nil { logrus.Errorln(err) + return } defer resp.Body.Close() bytes, err := ioutil.ReadAll(resp.Body) if err != nil { logrus.Errorln(err) + return } // logrus.Println(string(bytes)) vtbListStr, err := strconv.Unquote(strings.Replace(strconv.Quote(string(bytes)), `\\u`, `\u`, -1)) if err != nil { logrus.Errorln(err) + return } // logrus.Println(vtbListStr) - uidList := make([]string, 0) count := gjson.Get(vtbListStr, "#").Int() for i := int64(0); i < count; i++ { item := gjson.Get(vtbListStr, strconv.FormatInt(i, 10)) @@ -261,23 +264,27 @@ func (vdb *VtbDB) StoreVtb(uid string) { req, err := http.NewRequest("GET", vtbUrl, nil) if err != nil { logrus.Errorln(err) + return } // 自定义Header req.Header.Set("User-Agent", randua()) resp, err := client.Do(req) if err != nil { logrus.Errorln(err) + return } defer resp.Body.Close() bytes, err := ioutil.ReadAll(resp.Body) if err != nil { logrus.Errorln(err) + return } //logrus.Println(string(bytes)) vtbStr, err := strconv.Unquote(strings.Replace(strconv.Quote(string(bytes)), `\\u`, `\u`, -1)) if err != nil { logrus.Errorln(err) + return } // logrus.Println(vtbListStr) secondCount := gjson.Get(vtbStr, "data.voices.#").Int() diff --git a/plugin_vtb_quotation/vtb_quotation.go b/plugin_vtb_quotation/vtb_quotation.go index e2871d6d..2f5706d7 100644 --- a/plugin_vtb_quotation/vtb_quotation.go +++ b/plugin_vtb_quotation/vtb_quotation.go @@ -22,7 +22,7 @@ const dbfile = dbpath + "vtb.db" var engine = control.Register("vtbquotation", &control.Options{ DisableOnDefault: false, - Help: "vtbquotation\n- vtb语录\n- 随机vtb\n", + Help: "vtbkeyboard.moe\n- vtb语录\n- 随机vtb", }) func init() {