Skip to content

Commit

Permalink
feat: whitelist
Browse files Browse the repository at this point in the history
  • Loading branch information
RikaCelery committed Feb 10, 2025
1 parent 5dfbd36 commit c8266f4
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 27 deletions.
2 changes: 2 additions & 0 deletions basic/ban/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func init() {
}
proxy.OnCommands([]string{"开启"}, zero.OnlyToMe).SetBlock(true).FirstPriority().Handle(openPlugin)
proxy.OnCommands([]string{"关闭"}, zero.OnlyToMe).SetBlock(true).FirstPriority().Handle(closePlugin)
proxy.OnCommands([]string{"白名单模式"}, zero.OnlyToMe).SetBlock(true).FirstPriority().Handle(setModeWhite)
proxy.OnCommands([]string{"黑名单模式"}, zero.OnlyToMe).SetBlock(true).FirstPriority().Handle(setModeBlack)
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)
Expand Down
71 changes: 54 additions & 17 deletions basic/ban/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,29 @@ func SetUserPluginStatus(status bool, userID int64, plugin *manager.PluginCondit
var key string
if plugin != nil {
key = plugin.Key
} else { // plugin 为空,代表所有插件
key = AllPluginKey
} else {
panic("SetGroupPluginStatus: plugin is nil")
}
// 更新数据库
var preUser dao.UserSetting
proxy.GetDB().Take(&preUser, userID)
preUser.ID = userID
if status { // 启用
preUser.BlackPlugins = delPluginKey(preUser.BlackPlugins, key)
} else { // 关闭
preUser.BlackPlugins = addPluginKey(preUser.BlackPlugins, key)
if preUser.WhiteMode {
if status { // 启用
preUser.WhitePlugins = addPluginKey(preUser.WhitePlugins, key)
} else { // 关闭
preUser.WhitePlugins = delPluginKey(preUser.WhitePlugins, key)
}
} else {
if status { // 启用
preUser.BlackPlugins = delPluginKey(preUser.BlackPlugins, key)
} else { // 关闭
preUser.BlackPlugins = addPluginKey(preUser.BlackPlugins, key)
}
}
if err := proxy.GetDB().Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{"black_plugins"}), // Upsert
DoUpdates: clause.AssignmentColumns([]string{"black_plugins", "white_plugins"}), // Upsert
}).Create(&preUser).Error; err != nil {
log.Errorf("set user(%v) black_plugins error(sql): %v", userID, err)
return err
Expand All @@ -51,21 +59,29 @@ func SetGroupPluginStatus(status bool, groupID int64, plugin *manager.PluginCond
var key string
if plugin != nil {
key = plugin.Key
} else { // plugin 为空,代表所有插件
key = AllPluginKey
} else {
panic("SetGroupPluginStatus: plugin is nil")
}
// 更新数据库
var preGroup dao.GroupSetting
proxy.GetDB().Take(&preGroup, groupID)
preGroup.ID = groupID
if status { // 启用
preGroup.BlackPlugins = delPluginKey(preGroup.BlackPlugins, key)
} else { // 关闭
preGroup.BlackPlugins = addPluginKey(preGroup.BlackPlugins, key)
if preGroup.WhiteMode {
if status { // 启用
preGroup.WhitePlugins = addPluginKey(preGroup.WhitePlugins, key)
} else { // 关闭
preGroup.WhitePlugins = delPluginKey(preGroup.WhitePlugins, key)
}
} else {
if status { // 启用
preGroup.BlackPlugins = delPluginKey(preGroup.BlackPlugins, key)
} else { // 关闭
preGroup.BlackPlugins = addPluginKey(preGroup.BlackPlugins, key)
}
}
if err := proxy.GetDB().Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{"black_plugins"}), // Upsert
DoUpdates: clause.AssignmentColumns([]string{"black_plugins", "white_plugins"}), // Upsert
}).Create(&preGroup).Error; err != nil {
log.Errorf("set group(%v) black_plugins error(sql): %v", groupID, err)
return err
Expand All @@ -92,7 +108,11 @@ func GetUserPluginStatus(userID int64, plugin *manager.PluginCondition) bool {
// 查询
var preUser dao.UserSetting
proxy.GetDB().Take(&preUser, userID)
return !(hasPluginKey(preUser.BlackPlugins, key) || hasPluginKey(preUser.BlackPlugins, AllPluginKey))
if preUser.WhiteMode { // 白名单模式
return hasPluginKey(preUser.WhitePlugins, key)
} else {
return !(hasPluginKey(preUser.BlackPlugins, key) || hasPluginKey(preUser.BlackPlugins, AllPluginKey))
}
}

// GetGroupPluginStatus 获取群插件状态(能否使用)
Expand All @@ -101,11 +121,28 @@ func GetGroupPluginStatus(groupID int64, plugin *manager.PluginCondition) bool {
var key string
if plugin != nil {
key = plugin.Key
} else { // plugin 为空,代表所有插件
} else {
key = AllPluginKey
}
// 查询
var preGroup dao.GroupSetting
proxy.GetDB().Take(&preGroup, groupID)
return !(hasPluginKey(preGroup.BlackPlugins, key) || hasPluginKey(preGroup.BlackPlugins, AllPluginKey))
if preGroup.WhiteMode { // 白名单模式
return hasPluginKey(preGroup.WhitePlugins, key)
} else {
return !(hasPluginKey(preGroup.BlackPlugins, key) || hasPluginKey(preGroup.BlackPlugins, AllPluginKey))
}
}

// GetGroupRunningMode 获取群运行模式(白名单模式为true,黑名单为false)
func GetGroupRunningMode(groupID int64) bool {
var preGroup dao.GroupSetting
proxy.GetDB().Take(&preGroup, groupID)
return preGroup.WhiteMode
}

func GetUserRunningMode(userID int64) bool {
var preUser dao.UserSetting
proxy.GetDB().Take(&preUser, userID)
return preUser.WhiteMode
}
79 changes: 79 additions & 0 deletions basic/ban/switch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package ban

import (
"fmt"
"github.com/RicheyJang/PaimengBot/basic/auth"
"github.com/RicheyJang/PaimengBot/basic/dao"
"gorm.io/gorm/clause"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -84,3 +87,79 @@ func switchPlugin(status bool, ctx *zero.Ctx) {
}
dealGroupPluginStatus(ctx, status, ctx.Event.GroupID, plugin, period)
}

func setModeWhite(ctx *zero.Ctx) {
if utils.IsMessageGroup(ctx) {
// 查询
var preGroup dao.GroupSetting
proxy.GetDB().Take(&preGroup, ctx.Event.GroupID)
if preGroup.WhiteMode {
ctx.Send("该群已处于白名单模式,无需再设置")
return
}
preGroup.WhiteMode = true
if err := proxy.GetDB().Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{"white_mode"}), // Upsert
}).Create(&preGroup).Error; err != nil {
log.Errorf("setModeWhite err: %v", err)
ctx.Send("失败了...")
return
}
ctx.Send(fmt.Sprintf("群%d运行模式切换为白名单", ctx.Event.GroupID))
} else {
//私聊如果是超级管理员设置全局
if utils.IsSuperUser(ctx.Event.UserID) {
var preUser dao.UserSetting
if err := proxy.GetDB().Model(&preUser).Where("id = ?", 0).Update("white_mode", false).Error; err != nil {
log.Errorf("setModeBlack err: %v", err)
ctx.Send("失败了...")
return
}
ctx.Send("全局运行模式切换为白名单")
return
}
ctx.Send("请在群聊环境设置运行模式,如需帮助请联系BOT主人")
}
}
func setModeBlack(ctx *zero.Ctx) {
if utils.IsMessageGroup(ctx) {
if !auth.CheckPriority(ctx, 5, false) {
return
}
// 查询
var preGroup dao.GroupSetting
proxy.GetDB().Take(&preGroup, ctx.Event.GroupID)
if !preGroup.WhiteMode {
ctx.Send("该群已处于黑名单模式,无需再设置")
return
}
preGroup.WhiteMode = false
if preGroup.WhitePlugins == "" {
preGroup.WhitePlugins = "auth|ban|event|help|invite|limiter|nickname|sc"
}
if err := proxy.GetDB().Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{"white_mode"}), // Upsert
}).Create(&preGroup).Error; err != nil {
log.Errorf("setModeBlack err: %v", err)
ctx.Send("失败了...")
return
}
ctx.Send(fmt.Sprintf("群%d运行模式切换为黑名单", ctx.Event.GroupID))
} else {
//私聊如果是超级管理员设置全局
if utils.IsSuperUser(ctx.Event.UserID) {
var preUser dao.UserSetting
if err := proxy.GetDB().Model(&preUser).Where("id = ?", 0).Update("white_mode", true).Error; err != nil {
log.Errorf("setModeBlack err: %v", err)
ctx.Send("失败了...")
return
}
ctx.Send("全局运行模式切换为黑名单")
return
}
ctx.Send("请在群聊环境设置运行模式,如需帮助请联系BOT主人")
}

}
6 changes: 4 additions & 2 deletions basic/dao/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import (

type UserSetting struct {
ID int64 `gorm:"primaryKey;autoIncrement:false"`
BlackPlugins string `gorm:"size:512"` // 白名单插件
WhitePlugins string `gorm:"size:512"` // 黑名单插件
BlackPlugins string `gorm:"size:512"` // 黑名单插件
WhitePlugins string `gorm:"size:512"` // 白名单插件
WhiteMode bool //是否以白名单模式运行
Nickname string // 昵称
Likeability float64 // 好感度(无用,抱歉...)
Flag string // 非空时代表该用户尚未成为好友,是他的好友请求flag
Expand All @@ -22,6 +23,7 @@ type GroupSetting struct {
ID int64 `gorm:"primaryKey;autoIncrement:false"`
BlackPlugins string `gorm:"size:512"`
WhitePlugins string `gorm:"size:512"`
WhiteMode bool //是否以白名单模式运行
Flag string // 非空时代表该群尚未加入,是邀请入群请求flag
CouldAdd bool `gorm:"default:false"` // 能否入此群标志位
Welcome string
Expand Down
30 changes: 27 additions & 3 deletions basic/help/init.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package help

import (
"github.com/RicheyJang/PaimengBot/basic/ban"
"math"
"strings"

Expand Down Expand Up @@ -41,15 +42,24 @@ func helpHandle(ctx *zero.Ctx) {
isSuper := utils.IsSuperUser(ctx.Event.UserID)
arg := strings.TrimSpace(utils.GetArgs(ctx))
level := auth.GetGroupUserPriority(ctx.Event.GroupID, ctx.Event.UserID)
blacks := getBlackKeys(ctx.Event.UserID, ctx.Event.GroupID)
whiteMode := ban.GetGroupRunningMode(ctx.Event.GroupID)
if !utils.IsMessageGroup(ctx) {
whiteMode = ban.GetUserRunningMode(ctx.Event.UserID)
}
var keys map[string]struct{}
if whiteMode {
keys = getWhiteKeys(ctx.Event.UserID, ctx.Event.GroupID)
} else {
keys = getBlackKeys(ctx.Event.UserID, ctx.Event.GroupID)
}
if utils.IsGroupAnonymous(ctx) { // 匿名用户单独处理
isSuper = false
level = math.MaxInt
}
if len(arg) == 0 {
ctx.SendChain(formSummaryHelpMsg(isSuper, utils.IsMessagePrimary(ctx), level, blacks))
ctx.SendChain(formSummaryHelpMsg(isSuper, utils.IsMessagePrimary(ctx), level, whiteMode, keys))
} else {
ctx.SendChain(formSingleHelpMsg(arg, isSuper, utils.IsMessagePrimary(ctx), level, blacks))
ctx.SendChain(formSingleHelpMsg(arg, isSuper, utils.IsMessagePrimary(ctx), level, whiteMode, keys))
}
}

Expand Down Expand Up @@ -85,3 +95,17 @@ func getBlackKeys(userID, groupID int64) map[string]struct{} {
return utils.FormSetByStrings(strings.Split(groupS.BlackPlugins, "|"),
strings.Split(usersKey, "|"))
}
func getWhiteKeys(userID, groupID int64) map[string]struct{} {
var users []dao.UserSetting
var groupS dao.GroupSetting
proxy.GetDB().Find(&users, []int64{0, userID})
if groupID != 0 {
proxy.GetDB().Find(&groupS, groupID)
}
var usersKey string
for _, user := range users {
usersKey += user.BlackPlugins
}
return utils.FormSetByStrings(strings.Split(groupS.WhitePlugins, "|"),
strings.Split(usersKey, "|"))
}
7 changes: 5 additions & 2 deletions basic/help/single.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
)

func formSingleHelpMsg(cmd string, isSuper, isPrimary bool, priority int, blackKeys map[string]struct{}) message.MessageSegment {
func formSingleHelpMsg(cmd string, isSuper, isPrimary bool, priority int, white bool, blackKeys map[string]struct{}) message.MessageSegment {
plugins := manager.GetAllPluginConditions()
// 寻找插件
var selected *manager.PluginCondition
Expand All @@ -31,7 +31,10 @@ func formSingleHelpMsg(cmd string, isSuper, isPrimary bool, priority int, blackK
return message.Text("没有找到这个功能哦,或在群聊中无法查看功能详情")
}
// 插件状态检查
if _, ok := blackKeys[selected.Key]; ok {
if _, ok := blackKeys[selected.Key]; !white && ok {
return message.Text("功能被禁用中")
}
if _, ok := blackKeys[selected.Key]; white && !ok {
return message.Text("功能被禁用中")
}
// 生成图片 名称|普通用法|超级用户用法
Expand Down
9 changes: 6 additions & 3 deletions basic/help/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,23 @@ import (
const defaultClassify = "一般功能"
const passiveClassify = "被动"

func formSummaryHelpMsg(isSuper, isPrimary bool, priority int, blackKeys map[string]struct{}) message.MessageSegment {
func formSummaryHelpMsg(isSuper, isPrimary bool, priority int, white bool, keys map[string]struct{}) message.MessageSegment {
plugins := manager.GetAllPluginConditions()
// 获取所有插件信息
var helps helpSummaryMap = make(map[string]*blockInfo)
for _, plugin := range plugins {
// 过滤
if !checkPluginCouldShow(plugin, isSuper, isPrimary, priority, blackKeys) {
if !checkPluginCouldShow(plugin, isSuper, isPrimary, priority, keys) {
continue
}
// 生成项目(一个插件)
var item blockItem
item.name = plugin.Name
item.color = "black"
if _, ok := blackKeys[plugin.Key]; ok {
if _, ok := keys[plugin.Key]; white && !ok {
item.disabled = true // 插件对该用户或群被禁用
}
if _, ok := keys[plugin.Key]; !white && ok {
item.disabled = true // 插件对该用户或群被禁用
}
if plugin.IsPassive && len(plugin.Classify) != 0 && plugin.Classify != passiveClassify {
Expand Down

0 comments on commit c8266f4

Please sign in to comment.