Files
bl/login/internal/cmd/robot_group_manage.go
xinian 79c014f9cd
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
fix: 修正技能效果索引与实现逻辑
2026-03-31 03:42:46 +08:00

213 lines
6.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package cmd
import (
"fmt"
"regexp"
"strconv"
"strings"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
const (
robotNotifyModeNormal = "普通"
robotNotifyModeAtAll = "艾特全体"
robotNotifyModeEssence = "群精华"
)
var qqCodePattern = regexp.MustCompile(`qq=(\d+)`)
func init() {
zero.OnCommand("群通知", zero.SuperUserPermission).Handle(handleRobotGroupNotify)
zero.OnCommand("通知群列表", zero.SuperUserPermission).Handle(handleRobotNotifyGroupList)
zero.OnCommand("全群拉黑", zero.SuperUserPermission).Handle(handleRobotBlacklistAdd)
zero.OnCommand("全群解黑", zero.SuperUserPermission).Handle(handleRobotBlacklistRemove)
zero.OnCommand("黑名单列表", zero.SuperUserPermission).Handle(handleRobotBlacklistList)
zero.OnRequest().Handle(handleRobotBlacklistRequest)
zero.OnNotice().Handle(handleRobotBlacklistNotice)
}
func handleRobotGroupNotify(ctx *zero.Ctx) {
cfg := loadRobotGroupConfig()
if len(cfg.NotifyGroupIDs) == 0 {
ctx.Send("未配置通知群,请先编辑 public/config/robot_groups.json 的 notify_group_ids")
return
}
mode, content := parseNotifyModeAndContent(ctx.Event.Message.String())
if content == "" {
ctx.Send("用法:/群通知 [普通|艾特全体|群精华] 内容")
return
}
success := make([]string, 0, len(cfg.NotifyGroupIDs))
for _, groupID := range cfg.NotifyGroupIDs {
switch mode {
case robotNotifyModeAtAll:
ctx.SendGroupMessage(groupID, message.Message{message.AtAll(), message.Text("\n", content)})
case robotNotifyModeEssence:
msgID := ctx.SendGroupMessage(groupID, message.Text("【群通知】\n", content))
if msgID != 0 {
ctx.SetGroupEssenceMessage(msgID)
}
default:
ctx.SendGroupMessage(groupID, message.Text("【群通知】\n", content))
}
success = append(success, strconv.FormatInt(groupID, 10))
}
ctx.Send(fmt.Sprintf("已按[%s]发送群通知,共 %d 个群:%s", mode, len(success), strings.Join(success, ", ")))
}
func handleRobotNotifyGroupList(ctx *zero.Ctx) {
cfg := loadRobotGroupConfig()
ctx.Send(formatRobotGroups("通知群", cfg.NotifyGroupIDs) + "\n支持模式普通、艾特全体、群精华")
}
func handleRobotBlacklistAdd(ctx *zero.Ctx) {
cfg := loadRobotGroupConfig()
if len(cfg.ManageGroupIDs) == 0 {
ctx.Send("未配置管理群,请先编辑 public/config/robot_groups.json 的 manage_group_ids")
return
}
userID := extractCommandUserID(ctx.Event.Message.String(), "全群拉黑")
if userID == 0 {
ctx.Send("用法:/全群拉黑 @某人 或 /全群拉黑 QQ号")
return
}
if userID == ctx.Event.SelfID {
ctx.Send("不能把机器人自己加入黑名单")
return
}
if err := addRobotBlacklistUser(userID); err != nil {
ctx.Send("写入黑名单失败:" + err.Error())
return
}
for _, groupID := range cfg.ManageGroupIDs {
ctx.SetGroupKick(groupID, userID, true)
}
ctx.Send(fmt.Sprintf("已将 %d 加入全群黑名单,并在 %d 个管理群执行踢出/拒绝重加", userID, len(cfg.ManageGroupIDs)))
}
func handleRobotBlacklistRemove(ctx *zero.Ctx) {
userID := extractCommandUserID(ctx.Event.Message.String(), "全群解黑")
if userID == 0 {
ctx.Send("用法:/全群解黑 @某人 或 /全群解黑 QQ号")
return
}
if err := removeRobotBlacklistUser(userID); err != nil {
ctx.Send("移出黑名单失败:" + err.Error())
return
}
ctx.Send(fmt.Sprintf("已将 %d 从全群黑名单移除", userID))
}
func handleRobotBlacklistList(ctx *zero.Ctx) {
cfg := loadRobotBlacklist()
if len(cfg.UserIDs) == 0 {
ctx.Send("当前黑名单为空")
return
}
lines := make([]string, 0, len(cfg.UserIDs))
for _, userID := range cfg.UserIDs {
lines = append(lines, strconv.FormatInt(userID, 10))
}
ctx.Send("当前全群黑名单:\n" + strings.Join(lines, "\n"))
}
func handleRobotBlacklistRequest(ctx *zero.Ctx) {
cfg := loadRobotGroupConfig()
if ctx.Event.RequestType != "group" {
return
}
if !isConfiguredGroup(ctx.Event.GroupID, cfg.ManageGroupIDs) {
return
}
if !isRobotBlacklisted(ctx.Event.UserID) {
return
}
ctx.SetGroupAddRequest(ctx.Event.Flag, ctx.Event.SubType, false, "该账号已被机器人拉黑")
}
func handleRobotBlacklistNotice(ctx *zero.Ctx) {
cfg := loadRobotGroupConfig()
if ctx.Event.NoticeType != "group_increase" {
return
}
if !isConfiguredGroup(ctx.Event.GroupID, cfg.ManageGroupIDs) {
return
}
if !isRobotBlacklisted(ctx.Event.UserID) || ctx.Event.UserID == ctx.Event.SelfID {
return
}
ctx.SetGroupKick(ctx.Event.GroupID, ctx.Event.UserID, true)
ctx.SendGroupMessage(ctx.Event.GroupID, message.Text("已自动移除黑名单成员:", strconv.FormatInt(ctx.Event.UserID, 10)))
}
func extractCommandBody(raw, command string) string {
text := strings.TrimSpace(raw)
text = strings.TrimPrefix(text, "/")
text = strings.TrimSpace(text)
text = strings.TrimPrefix(text, command)
return strings.TrimSpace(text)
}
func extractCommandUserID(raw, command string) int64 {
if matches := qqCodePattern.FindStringSubmatch(raw); len(matches) == 2 {
if userID, err := strconv.ParseInt(matches[1], 10, 64); err == nil && userID > 0 {
return userID
}
}
text := extractCommandBody(raw, command)
for _, field := range strings.Fields(text) {
if userID, err := strconv.ParseInt(field, 10, 64); err == nil && userID > 0 {
return userID
}
}
return 0
}
func parseNotifyModeAndContent(raw string) (string, string) {
body := extractCommandBody(raw, "群通知")
if body == "" {
return robotNotifyModeNormal, ""
}
parts := strings.Fields(body)
if len(parts) == 0 {
return robotNotifyModeNormal, ""
}
switch parts[0] {
case robotNotifyModeNormal, robotNotifyModeAtAll, robotNotifyModeEssence:
return parts[0], strings.TrimSpace(strings.Join(parts[1:], " "))
default:
return robotNotifyModeNormal, body
}
}
func formatRobotGroups(title string, groups []int64) string {
if len(groups) == 0 {
return title + ":未配置"
}
lines := make([]string, 0, len(groups)+1)
lines = append(lines, title+"")
for _, groupID := range groups {
lines = append(lines, strconv.FormatInt(groupID, 10))
}
return strings.Join(lines, "\n")
}