Skip to content

Commit 4fdedd0

Browse files
committed
✏️ 增加黑名单 (#2)
1 parent f4bc43e commit 4fdedd0

File tree

4 files changed

+139
-12
lines changed

4 files changed

+139
-12
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ zerobot -h -t token -u url [-d|w] [-g 监听地址:端口] qq1 qq2 qq3 ...
5252
- [x] /全局启用 xxx
5353
- [x] /全局禁用 xxx
5454
- [x] /还原 xxx (在发送的群/用户还原xxx的开启状态到初始状态)
55+
- [x] /禁止 service qq1 qq2... (禁止 qqs 使用服务 service)
56+
- [x] /允许 service qq1 qq2... (重新允许 qqs 使用服务 service)
5557
- [x] /用法 xxx
5658
- [x] /服务列表
5759
- [x] /服务详情

control/register.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ var enmap = make(map[string]*zero.Engine)
99
// Register 注册插件控制器
1010
func Register(service string, o *Options) *zero.Engine {
1111
engine := zero.New()
12-
engine.UsePreHandler(newctrl(service, o).Handler())
12+
engine.UsePreHandler(newctrl(service, o).Handler)
1313
enmap[service] = engine
1414
return engine
1515
}

control/rule.go

Lines changed: 130 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
package control
33

44
import (
5+
"crypto/md5"
6+
"encoding/binary"
7+
"fmt"
58
"os"
69
"strconv"
710
"strings"
@@ -11,6 +14,7 @@ import (
1114
zero "github.com/wdvxdr1123/ZeroBot"
1215
"github.com/wdvxdr1123/ZeroBot/extension"
1316
"github.com/wdvxdr1123/ZeroBot/message"
17+
"github.com/wdvxdr1123/ZeroBot/utils/helper"
1418

1519
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
1620
)
@@ -47,6 +51,10 @@ func newctrl(service string, o *Options) *Control {
4751
if err != nil {
4852
panic(err)
4953
}
54+
err = db.Create(service+"ban", &ban{})
55+
if err != nil {
56+
panic(err)
57+
}
5058
return m
5159
}
5260

@@ -125,6 +133,78 @@ func (m *Control) IsEnabledIn(gid int64) bool {
125133
return !m.options.DisableOnDefault
126134
}
127135

136+
// Ban 禁止某人在某群使用本插件
137+
func (m *Control) Ban(uid, gid int64) {
138+
var err error
139+
var digest [16]byte
140+
logrus.Debugln("[control] Ban recv gid =", gid, "uid =", uid)
141+
if gid != 0 { // 特定群
142+
digest = md5.Sum(helper.StringToBytes(fmt.Sprintf("%d_%d", uid, gid)))
143+
m.RLock()
144+
err = db.Insert(m.service+"ban", &ban{ID: int64(binary.LittleEndian.Uint64(digest[:8])), UserID: uid, GroupID: gid})
145+
m.RUnlock()
146+
if err == nil {
147+
logrus.Debugf("[control] plugin %s is banned in grp %d for usr %d.", m.service, gid, uid)
148+
return
149+
}
150+
}
151+
// 所有群
152+
digest = md5.Sum(helper.StringToBytes(fmt.Sprintf("%d_all", uid)))
153+
m.RLock()
154+
err = db.Insert(m.service+"ban", &ban{ID: int64(binary.LittleEndian.Uint64(digest[:8])), UserID: uid, GroupID: 0})
155+
m.RUnlock()
156+
if err == nil {
157+
logrus.Debugf("[control] plugin %s is banned in all grp for usr %d.", m.service, uid)
158+
}
159+
}
160+
161+
// Permit 允许某人在某群使用本插件
162+
func (m *Control) Permit(uid, gid int64) {
163+
var digest [16]byte
164+
logrus.Debugln("[control] Permit recv gid =", gid, "uid =", uid)
165+
if gid != 0 { // 特定群
166+
digest = md5.Sum(helper.StringToBytes(fmt.Sprintf("%d_%d", uid, gid)))
167+
m.RLock()
168+
_ = db.Del(m.service+"ban", "WHERE id = "+strconv.FormatInt(int64(binary.LittleEndian.Uint64(digest[:8])), 10))
169+
m.RUnlock()
170+
logrus.Debugf("[control] plugin %s is permitted in grp %d for usr %d.", m.service, gid, uid)
171+
return
172+
}
173+
// 所有群
174+
digest = md5.Sum(helper.StringToBytes(fmt.Sprintf("%d_all", uid)))
175+
m.RLock()
176+
_ = db.Del(m.service+"ban", "WHERE id = "+strconv.FormatInt(int64(binary.LittleEndian.Uint64(digest[:8])), 10))
177+
m.RUnlock()
178+
logrus.Debugf("[control] plugin %s is permitted in all grp for usr %d.", m.service, uid)
179+
}
180+
181+
// IsBannedIn 某人是否在某群被 ban
182+
func (m *Control) IsBannedIn(uid, gid int64) bool {
183+
var b ban
184+
var err error
185+
var digest [16]byte
186+
logrus.Debugln("[control] IsBannedIn recv gid =", gid, "uid =", uid)
187+
if gid != 0 {
188+
digest = md5.Sum(helper.StringToBytes(fmt.Sprintf("%d_%d", uid, gid)))
189+
m.RLock()
190+
err = db.Find(m.service+"ban", &b, "WHERE id = "+strconv.FormatInt(int64(binary.LittleEndian.Uint64(digest[:8])), 10))
191+
m.RUnlock()
192+
if err == nil && gid == b.GroupID && uid == b.UserID {
193+
logrus.Debugf("[control] plugin %s is banned in grp %d for usr %d.", m.service, b.GroupID, b.UserID)
194+
return true
195+
}
196+
}
197+
digest = md5.Sum(helper.StringToBytes(fmt.Sprintf("%d_all", uid)))
198+
m.RLock()
199+
err = db.Find(m.service+"ban", &b, "WHERE id = "+strconv.FormatInt(int64(binary.LittleEndian.Uint64(digest[:8])), 10))
200+
m.RUnlock()
201+
if err == nil && b.GroupID == 0 && uid == b.UserID {
202+
logrus.Debugf("[control] plugin %s is banned in all grp for usr %d.", m.service, b.UserID)
203+
return true
204+
}
205+
return false
206+
}
207+
128208
// GetData 获取某个群的 63 字节配置信息
129209
func (m *Control) GetData(gid int64) int64 {
130210
var c grpcfg
@@ -173,21 +253,19 @@ func (m *Control) SetData(groupID int64, data int64) error {
173253
}
174254

175255
// Handler 返回 预处理器
176-
func (m *Control) Handler() zero.Rule {
177-
return func(ctx *zero.Ctx) bool {
178-
ctx.State["manager"] = m
179-
grp := ctx.Event.GroupID
180-
if grp == 0 {
181-
// 个人用户
182-
grp = -ctx.Event.UserID
183-
}
184-
logrus.Debugln("[control] handler get gid =", grp)
185-
return m.IsEnabledIn(grp)
256+
func (m *Control) Handler(ctx *zero.Ctx) bool {
257+
ctx.State["manager"] = m
258+
grp := ctx.Event.GroupID
259+
if grp == 0 {
260+
// 个人用户
261+
return m.IsEnabledIn(-ctx.Event.UserID)
186262
}
263+
logrus.Debugln("[control] handler get gid =", grp)
264+
return m.IsEnabledIn(grp) && !m.IsBannedIn(ctx.Event.UserID, grp)
187265
}
188266

189267
// Lookup returns a Manager by the service name, if
190-
// not exist, it will returns nil.
268+
// not exist, it will return nil.
191269
func Lookup(service string) (*Control, bool) {
192270
mu.RLock()
193271
m, ok := managers[service]
@@ -276,6 +354,47 @@ func init() {
276354
ctx.SendChain(message.Text("已还原服务的默认启用状态: " + model.Args))
277355
})
278356

357+
zero.OnCommandGroup([]string{
358+
"禁止", "ban", "允许", "permit",
359+
"全局禁止", "banall", "全局允许", "permitall",
360+
}, zero.OnlyGroup, zero.AdminPermission).Handle(func(ctx *zero.Ctx) {
361+
model := extension.CommandModel{}
362+
_ = ctx.Parse(&model)
363+
args := strings.Split(model.Args, " ")
364+
if len(args) >= 2 {
365+
service, ok := Lookup(args[0])
366+
if !ok {
367+
ctx.SendChain(message.Text("没有找到指定服务!"))
368+
return
369+
}
370+
grp := ctx.Event.GroupID
371+
if strings.Contains(model.Command, "全局") || strings.Contains(model.Command, "all") {
372+
grp = 0
373+
}
374+
msg := "**" + args[0] + "报告**"
375+
if strings.Contains(model.Command, "允许") || strings.Contains(model.Command, "permit") {
376+
for _, usr := range args[1:] {
377+
uid, err := strconv.ParseInt(usr, 10, 64)
378+
if err == nil {
379+
service.Permit(uid, grp)
380+
msg += "\n+ 已允许" + usr
381+
}
382+
}
383+
} else {
384+
for _, usr := range args[1:] {
385+
uid, err := strconv.ParseInt(usr, 10, 64)
386+
if err == nil {
387+
service.Ban(uid, grp)
388+
msg += "\n- 已禁止" + usr
389+
}
390+
}
391+
}
392+
ctx.SendChain(message.Text(msg))
393+
return
394+
}
395+
ctx.SendChain(message.Text("参数错误!"))
396+
})
397+
279398
zero.OnCommandGroup([]string{"用法", "usage"}, userOrGrpAdmin).
280399
Handle(func(ctx *zero.Ctx) {
281400
model := extension.CommandModel{}

control/tables.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ type grpcfg struct {
66
Disable int64 `db:"disable"` // Disable 默认启用该插件
77
}
88

9+
type ban struct {
10+
ID int64 `db:"id"`
11+
UserID int64 `db:"uid"`
12+
GroupID int64 `db:"gid"`
13+
}
14+
915
// Options holds the optional parameters for the Manager.
1016
type Options struct {
1117
DisableOnDefault bool

0 commit comments

Comments
 (0)