From f0283a27163fa1cc0d4b39e0c3f8a58e3ffdb54a Mon Sep 17 00:00:00 2001 From: RicheyJang <773602577@qq.com> Date: Tue, 30 Nov 2021 22:06:44 +0800 Subject: [PATCH] add: show black list --- basic/ban/ban.go | 2 +- basic/ban/init.go | 10 ++- basic/ban/show.go | 165 ++++++++++++++++++++++++++++++++++++++++++ basic/ban/switch.go | 2 +- utils/common.go | 5 +- utils/images/tools.go | 6 +- 6 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 basic/ban/show.go diff --git a/basic/ban/ban.go b/basic/ban/ban.go index f7867f3..10eb2f8 100644 --- a/basic/ban/ban.go +++ b/basic/ban/ban.go @@ -57,7 +57,7 @@ func dealBanArgs(ctx *zero.Ctx) (userID int64, plugin *manager.PluginCondition, } func dealBanUser(status bool, ctx *zero.Ctx) { - if ctx.Event.MessageType == "private" { + if utils.IsMessagePrimary(ctx) { if !utils.IsSuperUser(ctx.Event.UserID) { ctx.Send("请在群聊中封禁/解封功能哦,或者联系管理员") return diff --git a/basic/ban/init.go b/basic/ban/init.go index 221adda..181da72 100644 --- a/basic/ban/init.go +++ b/basic/ban/init.go @@ -21,7 +21,8 @@ var info = manager.PluginInfo{ *只有本群最高权限群管理员在群聊中才可触发* 开启\关闭[功能] [时长]?:将开启\关闭本群的指定功能,时长为可选项,形式参照示例 封禁[用户ID] [功能]? [时长]?:封禁指定用户使用指定功能(当指定功能时)或全部功能,时长为可选项,形式参照示例 - 解封[用户ID] [功能]?:封禁指定用户使用指定功能,时长为可选项,形式参照示例 + 解封[用户ID] [功能]?:解封指定用户使用指定功能,时长为可选项,形式参照示例 + 黑名单:获取所有被封禁用户的被封禁功能列表 示例: 封禁123456:封禁用户ID为123456的所有功能 封禁123456 25m:封禁用户ID为123456的所有功能25分钟 @@ -29,8 +30,10 @@ var info = manager.PluginInfo{ `, SuperUsage: ` 用法: - 在私聊中,使用开启\关闭[功能] [时长]?命令,将针对所有用户和群开启\关闭该功能(全局Ban) - 此外还可通过 开启\关闭[群ID] [功能] [时长]? 来开启\关闭指定群的指定功能 + 在私聊中: + 使用开启\关闭[功能] [时长]?命令,将针对所有用户和群开启\关闭该功能(全局Ban) + 还可通过 开启\关闭[群ID] [功能] [时长]? 来开启\关闭指定群的指定功能 + 黑名单:获取所有被封禁用户、群的被封禁功能列表 在群聊中,等同于最高权限群管理员执行命令 `, AdminLevel: 1, @@ -45,6 +48,7 @@ func init() { proxy.OnCommands([]string{"关闭"}, zero.OnlyToMe).SetBlock(true).FirstPriority().Handle(closePlugin) proxy.OnCommands([]string{"封禁", "ban", "Ban"}, zero.OnlyToMe).SetBlock(true).FirstPriority().Handle(banUser) proxy.OnCommands([]string{"解封", "unban", "Unban"}, zero.OnlyToMe).SetBlock(true).FirstPriority().Handle(unbanUser) + proxy.OnCommands([]string{"黑名单"}, zero.OnlyToMe).SetBlock(true).FirstPriority().Handle(showBlack) manager.AddPreHook(checkPluginStatus) } diff --git a/basic/ban/show.go b/basic/ban/show.go new file mode 100644 index 0000000..94e3f3d --- /dev/null +++ b/basic/ban/show.go @@ -0,0 +1,165 @@ +package ban + +import ( + "fmt" + "strings" + + "github.com/wdvxdr1123/ZeroBot/message" + + "github.com/RicheyJang/PaimengBot/utils/images" + + "github.com/RicheyJang/PaimengBot/manager" + + "github.com/RicheyJang/PaimengBot/basic/dao" + "github.com/RicheyJang/PaimengBot/utils" + zero "github.com/wdvxdr1123/ZeroBot" +) + +// userID -> 被封插件列表 +func getUsersBlack() map[int64][]string { + var users []dao.UserSetting + proxy.GetDB().Select("id", "black_plugins").Where("LENGTH(black_plugins) > 1").Find(&users) + res := make(map[int64][]string) + for _, user := range users { + blacks := utils.MergeStringSlices(strings.Split(user.BlackPlugins, "|")) // 去重去空 + if len(blacks) == 0 { + continue + } + res[user.ID] = blacks + } + return res +} + +// groupID -> 被封插件列表 +func getGroupsBlack() map[int64][]string { + var groups []dao.GroupSetting + proxy.GetDB().Select("id", "black_plugins").Where("LENGTH(black_plugins) > 1").Find(&groups) + res := make(map[int64][]string) + for _, group := range groups { + blacks := utils.MergeStringSlices(strings.Split(group.BlackPlugins, "|")) // 去重去空 + if len(blacks) == 0 { + continue + } + res[group.ID] = blacks + } + return res +} + +func showBlack(ctx *zero.Ctx) { + if utils.IsMessagePrimary(ctx) { + if !utils.IsSuperUser(ctx.Event.UserID) { + ctx.Send("请在群聊中问我哦") + return + } + // 超级用户 in 私聊 单独处理 + showBlackInPrimarySuper(ctx) + return + } + // 群管理员 in 群聊 + var str string + userM := getUsersBlack() + rsp := ctx.GetGroupMemberList(ctx.Event.GroupID) // 过滤掉非本群成员 + users := rsp.Array() + for _, user := range users { + id := user.Get("user_id").Int() + if userBlack, ok := userM[id]; ok && id != 0 { + str += fmt.Sprintf("%v(%v %v): %v\n", + user.Get("nickname"), user.Get("card"), id, formBlackDescription(userBlack)) + } + } + if len(str) == 0 { + ctx.Send("大家都是好人,黑名单暂时是空哒") + return + } + // 生成图片 + w, h := images.MeasureStringDefault(str, 24, 1.3) + w, h = w+20, h+20 + img := images.NewImageCtxWithBGRGBA255(int(w), int(h), 255, 255, 255, 255) + err := img.PasteStringDefault(str, 24, 1.3, 10, 10, w) + if err != nil { + ctx.Send(str) + return + } + msg, err := img.GenMessageAuto() + if err != nil { + ctx.Send(str) + return + } + ctx.SendChain(msg) +} + +func showBlackInPrimarySuper(ctx *zero.Ctx) { + userM := getUsersBlack() + groupM := getGroupsBlack() + if len(userM) == 0 && len(groupM) == 0 { + ctx.Send("大家都是好人,黑名单暂时是空哒") + return + } + // 用户 + if len(userM) > 0 { + str := "用户:" + userDesM := make(map[int64]string) + for id, blacks := range userM { + var des string + if id == 0 { // 全体用户(全局) + des = fmt.Sprintf("全体: %v\n", formBlackDescription(blacks)) + } else { // 正常用户 + user := ctx.GetStrangerInfo(id, false) + des = fmt.Sprintf("%v(%v): %v\n", user.Get("nickname"), id, formBlackDescription(blacks)) + } + userDesM[id] = des + str += des + "\n" + } + w, _ := images.MeasureStringDefault(str, 24, 1.3) + msg, err := images.GenQQListMsgWithAva(userDesM, w, true) + if err != nil { + ctx.Send(str) + } else { + ctx.SendChain(message.Text("用户:\n"), msg) + } + } + // 群聊 + if len(groupM) > 0 { + str := "群:" + groupDesM := make(map[int64]string) + for id, blacks := range groupM { + group := ctx.GetGroupInfo(id, false) + des := fmt.Sprintf("%v(%v): %v\n", + group.Name, id, formBlackDescription(blacks)) + groupDesM[id] = des + str += des + "\n" + } + w, _ := images.MeasureStringDefault(str, 24, 1.3) + msg, err := images.GenQQListMsgWithAva(groupDesM, w, false) + if err != nil { + ctx.Send(str) + } else { + ctx.SendChain(message.Text("群:\n"), msg) + } + } +} + +func formBlackDescription(blacks []string) string { + var des string + for i, black := range blacks { + if black == AllPluginKey { + des = "全部功能" + blacks = append(blacks[:i], blacks[i+1:]...) + break + } + } + if len(blacks) > 0 && len(des) > 0 { + des += "+" + } + for _, black := range blacks { + plugin := manager.GetPluginConditionByKey(black) + if plugin == nil { + continue + } + if len(des) > 0 && des[0] != '+' { + des += "、" + } + des += plugin.Name + } + return des +} diff --git a/basic/ban/switch.go b/basic/ban/switch.go index e890819..d080867 100644 --- a/basic/ban/switch.go +++ b/basic/ban/switch.go @@ -58,7 +58,7 @@ func dealSwitchArgs(ctx *zero.Ctx, dealGroup bool) ( } func switchPlugin(status bool, ctx *zero.Ctx) { - if ctx.Event.MessageType == "private" { + if utils.IsMessagePrimary(ctx) { if !utils.IsSuperUser(ctx.Event.UserID) { ctx.Send("请在群聊中开关功能哦,或者联系管理员") return diff --git a/utils/common.go b/utils/common.go index b673224..035784c 100644 --- a/utils/common.go +++ b/utils/common.go @@ -36,10 +36,13 @@ func GoAndWait(handlers ...func() error) (err error) { return err } -// MergeStringSlices 合并多个字符串切片并去重 +// MergeStringSlices 合并多个字符串切片并去重、去除空字符串 func MergeStringSlices(slices ...[]string) (res []string) { mp := FormSetByStrings(slices...) for s, _ := range mp { + if len(s) == 0 { + continue + } res = append(res, s) } return diff --git a/utils/images/tools.go b/utils/images/tools.go index 9b00f10..c70b845 100644 --- a/utils/images/tools.go +++ b/utils/images/tools.go @@ -76,13 +76,13 @@ func ClipImgToCircle(img image.Image) image.Image { return dc.Image() } -// GenQQListMsgWithAva 生成带QQ头像的用户或群(以isFriend参数区分)列表 -func GenQQListMsgWithAva(data map[int64]string, w float64, isFriend bool) (msg message.MessageSegment, err error) { +// GenQQListMsgWithAva 生成带QQ头像的用户或群(以isUser参数区分)列表 +func GenQQListMsgWithAva(data map[int64]string, w float64, isUser bool) (msg message.MessageSegment, err error) { var avaReader io.Reader avaSize, fontSize, height := 100, 24.0, 10 img := NewImageCtxWithBGRGBA255(int(w)+avaSize+30, len(data)*(avaSize+20)+30, 255, 255, 255, 255) for id, str := range data { - if isFriend { + if isUser { avaReader, err = utils.GetQQAvatar(id, avaSize) } else { avaReader, err = utils.GetQQGroupAvatar(id, avaSize)