|
2 | 2 | package antiabuse
|
3 | 3 |
|
4 | 4 | import (
|
5 |
| - "fmt" |
| 5 | + "strconv" |
6 | 6 | "strings"
|
7 | 7 | "time"
|
8 | 8 |
|
| 9 | + "github.com/FloatTech/floatbox/binary" |
9 | 10 | fcext "github.com/FloatTech/floatbox/ctxext"
|
| 11 | + "github.com/FloatTech/ttl" |
10 | 12 | ctrl "github.com/FloatTech/zbpctrl"
|
11 | 13 | "github.com/FloatTech/zbputils/control"
|
| 14 | + "github.com/FloatTech/zbputils/img/text" |
| 15 | + "github.com/sirupsen/logrus" |
12 | 16 | zero "github.com/wdvxdr1123/ZeroBot"
|
13 | 17 | "github.com/wdvxdr1123/ZeroBot/message"
|
14 | 18 | )
|
15 | 19 |
|
| 20 | +const bandur time.Duration = time.Minute * 10 |
| 21 | + |
| 22 | +var ( |
| 23 | + managers *ctrl.Manager[*zero.Ctx] // managers lazy load |
| 24 | + cache = ttl.NewCacheOn(bandur, [4]func(int64, struct{}){nil, nil, onDel, nil}) |
| 25 | + db *antidb |
| 26 | +) |
| 27 | + |
| 28 | +func onDel(uid int64, _ struct{}) { |
| 29 | + if managers == nil { |
| 30 | + return |
| 31 | + } |
| 32 | + if err := managers.DoUnblock(uid); err != nil { |
| 33 | + logrus.Errorln("[antiabuse.onDel] unblock:", err) |
| 34 | + } |
| 35 | + if err := db.Del("__bantime__", "WHERE id="+strconv.FormatInt(uid, 10)); err != nil { |
| 36 | + logrus.Errorln("[antiabuse.onDel] db:", err) |
| 37 | + } |
| 38 | +} |
| 39 | + |
16 | 40 | func init() {
|
17 | 41 | engine := control.Register("antiabuse", &ctrl.Options[*zero.Ctx]{
|
18 | 42 | DisableOnDefault: false,
|
19 |
| - Help: "违禁词检测", |
| 43 | + Help: "违禁词检测\n- /[添加|删除|查看]违禁词", |
20 | 44 | PrivateDataFolder: "anti_abuse",
|
21 | 45 | })
|
| 46 | + |
22 | 47 | onceRule := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
|
23 | 48 | managers = ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager
|
24 |
| - db.DBPath = engine.DataFolder() + "anti_abuse.db" |
25 |
| - err := db.Open(time.Hour * 4) |
| 49 | + var err error |
| 50 | + db, err = newantidb(engine.DataFolder() + "anti_abuse.db") |
26 | 51 | if err != nil {
|
27 |
| - ctx.SendChain(message.Text("open db error: ", err)) |
| 52 | + ctx.SendChain(message.Text("ERROR: ", err)) |
28 | 53 | return false
|
29 | 54 | }
|
30 |
| - err = db.Create("banWord", &banWord{}) |
31 |
| - if err != nil { |
32 |
| - ctx.SendChain(message.Text("create table error: ", err)) |
33 |
| - return false |
| 55 | + return true |
| 56 | + }) |
| 57 | + |
| 58 | + engine.OnMessage(onceRule, zero.OnlyGroup, func(ctx *zero.Ctx) bool { |
| 59 | + if !ctx.Event.IsToMe { |
| 60 | + return true |
34 | 61 | }
|
35 |
| - err = recoverWord() |
36 |
| - if err != nil { |
37 |
| - ctx.SendChain(message.Text("recover data error: ", err)) |
| 62 | + uid := ctx.Event.UserID |
| 63 | + gid := ctx.Event.GroupID |
| 64 | + msg := strings.ReplaceAll(ctx.MessageString(), "\n", "") |
| 65 | + msg = strings.ReplaceAll(msg, "\r", "") |
| 66 | + msg = strings.ReplaceAll(msg, "\t", "") |
| 67 | + msg = strings.ReplaceAll(msg, ";", "") |
| 68 | + if db.isInAntiList(uid, gid, msg) { |
| 69 | + if err := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager.DoBlock(uid); err == nil { |
| 70 | + t := time.Now().Unix() |
| 71 | + cache.Set(uid, struct{}{}) |
| 72 | + ctx.SetGroupBan(gid, uid, int64(bandur.Minutes())) |
| 73 | + ctx.SendChain(message.Text("检测到违禁词, 已封禁/屏蔽", bandur)) |
| 74 | + db.Lock() |
| 75 | + defer db.Unlock() |
| 76 | + err := db.Create("__bantime__", nilbt) |
| 77 | + if err != nil { |
| 78 | + ctx.SendChain(message.Text("ERROR: ", err)) |
| 79 | + return false |
| 80 | + } |
| 81 | + err = db.Insert("__bantime__", &banTime{ID: uid, Time: t}) |
| 82 | + if err != nil { |
| 83 | + ctx.SendChain(message.Text("ERROR: ", err)) |
| 84 | + return false |
| 85 | + } |
| 86 | + } else { |
| 87 | + ctx.SendChain(message.Text("ERROR: block user: ", err)) |
| 88 | + } |
38 | 89 | return false
|
39 | 90 | }
|
40 | 91 | return true
|
41 | 92 | })
|
42 |
| - engine.OnMessage(onceRule, zero.OnlyGroup, banRule) |
| 93 | + |
43 | 94 | engine.OnCommand("添加违禁词", zero.OnlyGroup, zero.AdminPermission, onceRule).Handle(
|
44 | 95 | func(ctx *zero.Ctx) {
|
45 | 96 | args := ctx.State["args"].(string)
|
46 |
| - if err := insertWord(ctx.Event.GroupID, args); err != nil { |
47 |
| - ctx.SendChain(message.Text("error:", err)) |
| 97 | + if err := db.insertWord(ctx.Event.GroupID, args); err != nil { |
| 98 | + ctx.SendChain(message.Text("ERROR: ", err)) |
48 | 99 | } else {
|
49 |
| - ctx.SendChain(message.Text(fmt.Sprintf("添加违禁词 %s 成功", args))) |
| 100 | + ctx.SendChain(message.Text("成功")) |
50 | 101 | }
|
51 | 102 | })
|
| 103 | + |
52 | 104 | engine.OnCommand("删除违禁词", zero.OnlyGroup, zero.AdminPermission, onceRule).Handle(
|
53 | 105 | func(ctx *zero.Ctx) {
|
54 | 106 | args := ctx.State["args"].(string)
|
55 |
| - if err := deleteWord(ctx.Event.GroupID, args); err != nil { |
56 |
| - ctx.SendChain(message.Text("error:", err)) |
| 107 | + if err := db.deleteWord(ctx.Event.GroupID, args); err != nil { |
| 108 | + ctx.SendChain(message.Text("ERROR: ", err)) |
57 | 109 | } else {
|
58 |
| - ctx.SendChain(message.Text(fmt.Sprintf("删除违禁词 %s 成功", args))) |
| 110 | + ctx.SendChain(message.Text("成功")) |
59 | 111 | }
|
60 | 112 | })
|
| 113 | + |
61 | 114 | engine.OnCommand("查看违禁词", zero.OnlyGroup, onceRule).Handle(
|
62 | 115 | func(ctx *zero.Ctx) {
|
63 |
| - if set, ok := wordMap[ctx.Event.GroupID]; !ok { |
64 |
| - ctx.SendChain(message.Text("本群无违禁词")) |
65 |
| - } else { |
66 |
| - ctx.SendChain(message.Text("本群违禁词有:", strings.Join(set.ToSlice(), " |"))) |
| 116 | + b, err := text.RenderToBase64(db.listWords(ctx.Event.GroupID), text.FontFile, 400, 20) |
| 117 | + if err != nil { |
| 118 | + ctx.SendChain(message.Text("ERROR: ", err)) |
| 119 | + return |
67 | 120 | }
|
| 121 | + ctx.SendChain(message.Text("本群违禁词有\n"), message.Image("base64://"+binary.BytesToString(b))) |
68 | 122 | })
|
69 |
| - |
70 | 123 | }
|
0 commit comments