Skip to content

Commit 4862924

Browse files
authored
add anti_abuse plugin (#392)
add anti_abuse plugin
1 parent e5f186a commit 4862924

File tree

5 files changed

+254
-2
lines changed

5 files changed

+254
-2
lines changed

main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import (
2424
// vvvvvvv高优先级区vvvvvvv //
2525
// vvvvvvvvvvvvvv //
2626
// vvvv //
27-
28-
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chat" // 基础词库
27+
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/antiabuse" // 违禁词
28+
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chat" // 基础词库
2929

3030
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/sleep_manage" // 统计睡眠时间
3131

plugin/antiabuse/anti.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Package antiabuse defines anti_abuse plugin ,support abuse words check and add/remove abuse words
2+
package antiabuse
3+
4+
import (
5+
"fmt"
6+
"strings"
7+
"time"
8+
9+
fcext "github.com/FloatTech/floatbox/ctxext"
10+
ctrl "github.com/FloatTech/zbpctrl"
11+
"github.com/FloatTech/zbputils/control"
12+
zero "github.com/wdvxdr1123/ZeroBot"
13+
"github.com/wdvxdr1123/ZeroBot/message"
14+
)
15+
16+
func init() {
17+
engine := control.Register("anti_abuse", &ctrl.Options[*zero.Ctx]{
18+
DisableOnDefault: false,
19+
Help: "违禁词检测",
20+
PrivateDataFolder: "anti_abuse",
21+
})
22+
onceRule := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
23+
db.DBPath = engine.DataFolder() + "anti_abuse.db"
24+
err := db.Open(time.Hour * 4)
25+
if err != nil {
26+
ctx.SendChain(message.Text("open db error: ", err))
27+
return false
28+
}
29+
err = db.Create("banUser", &banUser{})
30+
if err != nil {
31+
ctx.SendChain(message.Text("create table error: ", err))
32+
return false
33+
}
34+
err = db.Create("banWord", &banWord{})
35+
if err != nil {
36+
ctx.SendChain(message.Text("create table error: ", err))
37+
return false
38+
}
39+
err = recoverUser()
40+
if err != nil {
41+
ctx.SendChain(message.Text("recover data error: ", err))
42+
return false
43+
}
44+
err = recoverWord()
45+
if err != nil {
46+
ctx.SendChain(message.Text("recover data error: ", err))
47+
return false
48+
}
49+
return true
50+
})
51+
engine.OnMessage(zero.OnlyGroup, onceRule, banRule)
52+
engine.OnCommand("添加违禁词", zero.OnlyGroup, zero.AdminPermission, onceRule).Handle(
53+
func(ctx *zero.Ctx) {
54+
if err := insertWord(ctx.Event.GroupID, ctx.State["args"].(string)); err != nil {
55+
ctx.SendChain(message.Text("add ban word error:", err))
56+
}
57+
})
58+
engine.OnCommand("删除违禁词", zero.OnlyGroup, zero.AdminPermission, onceRule).Handle(
59+
func(ctx *zero.Ctx) {
60+
if err := deleteWord(ctx.Event.GroupID, ctx.State["args"].(string)); err != nil {
61+
ctx.SendChain(message.Text("add ban word error:", err))
62+
}
63+
})
64+
engine.OnCommand("查看违禁词", zero.OnlyGroup, onceRule).Handle(
65+
func(ctx *zero.Ctx) {
66+
gidPrefix := fmt.Sprintf("%d-", ctx.Event.GroupID)
67+
var words []string
68+
_ = wordSet.Iter(func(s string) error {
69+
trueWord := strings.SplitN(s, gidPrefix, 1)[1]
70+
words = append(words, trueWord)
71+
return nil
72+
})
73+
ctx.SendChain(message.Text("本群违禁词有:\n", strings.Join(words, " |")))
74+
})
75+
76+
}

plugin/antiabuse/database.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package antiabuse
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
sqlite "github.com/FloatTech/sqlite"
8+
)
9+
10+
var db = &sqlite.Sqlite{}
11+
12+
type banUser struct {
13+
UUID string `db:"uuid"`
14+
DueTime int64 `db:"due_time"`
15+
}
16+
17+
func insertUser(gid, uid int64) error {
18+
obj := &banUser{fmt.Sprintf("%d-%d", gid, uid), time.Now().Add(4 * time.Hour).UnixNano()}
19+
return db.Insert("banUser", obj)
20+
}
21+
22+
func deleteUser(gid, uid int64) error {
23+
sql := fmt.Sprintf("WHERE uuid=%d-%d", gid, uid)
24+
return db.Del("banUser", sql)
25+
}
26+
27+
func recoverUser() error {
28+
obj := &banUser{}
29+
var uuids []string
30+
err := db.FindFor("banUser", obj, "", func() error {
31+
if time.Now().UnixNano() < obj.DueTime {
32+
uuids = append(uuids, obj.UUID)
33+
} else {
34+
if err := db.Del("banUser", "WHERE uuid="+obj.UUID); err != nil {
35+
return err
36+
}
37+
}
38+
return nil
39+
},
40+
)
41+
if err != nil {
42+
return err
43+
}
44+
banSet.AddMany(uuids)
45+
return nil
46+
}
47+
48+
type banWord struct {
49+
GroupWord string `db:"group_word"`
50+
}
51+
52+
func insertWord(gid int64, word string) error {
53+
obj := &banWord{fmt.Sprintf("%d-%s", gid, word)}
54+
return db.Insert("banWord", obj)
55+
}
56+
57+
func deleteWord(gid int64, word string) error {
58+
sql := fmt.Sprintf("WHERE group_word = %d-%s", gid, word)
59+
return db.Del("banWord", sql)
60+
}
61+
62+
func recoverWord() error {
63+
obj := &banWord{}
64+
var groupWords []string
65+
err := db.FindFor("banWord", obj, "", func() error {
66+
groupWords = append(groupWords, obj.GroupWord)
67+
return nil
68+
},
69+
)
70+
if err != nil {
71+
return err
72+
}
73+
wordSet.AddMany(groupWords)
74+
return nil
75+
}

plugin/antiabuse/set.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package antiabuse
2+
3+
import "sync"
4+
5+
//Set defines HashSet structure
6+
type Set struct {
7+
sync.RWMutex
8+
m map[string]struct{}
9+
}
10+
11+
var banSet = &Set{m: make(map[string]struct{})}
12+
var wordSet = &Set{m: make(map[string]struct{})}
13+
14+
// Add adds element to Set
15+
func (s *Set) Add(key string) {
16+
s.Lock()
17+
defer s.Unlock()
18+
s.m[key] = struct{}{}
19+
}
20+
21+
// Include asserts element in Set
22+
func (s *Set) Include(key string) bool {
23+
s.RLock()
24+
defer s.RUnlock()
25+
_, ok := s.m[key]
26+
return ok
27+
}
28+
29+
// Iter calls f when traversing Set
30+
func (s *Set) Iter(f func(string) error) error {
31+
s.Lock()
32+
defer s.Unlock()
33+
var err error
34+
for key := range s.m {
35+
err = f(key)
36+
if err != nil {
37+
return err
38+
}
39+
}
40+
return nil
41+
}
42+
43+
// Remove removes element from Set
44+
func (s *Set) Remove(key string) {
45+
s.Lock()
46+
defer s.Unlock()
47+
delete(s.m, key)
48+
}
49+
50+
// AddMany adds multiple elements to Set
51+
func (s *Set) AddMany(keys []string) {
52+
s.Lock()
53+
defer s.Unlock()
54+
for _, k := range keys {
55+
s.m[k] = struct{}{}
56+
}
57+
}

plugin/antiabuse/utils.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package antiabuse
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"time"
7+
8+
zero "github.com/wdvxdr1123/ZeroBot"
9+
"github.com/wdvxdr1123/ZeroBot/message"
10+
)
11+
12+
func banRule(ctx *zero.Ctx) bool {
13+
gid := ctx.Event.GroupID
14+
uid := ctx.Event.UserID
15+
uuid := fmt.Sprintf("%d-%d", gid, uid)
16+
if banSet.Include(uuid) {
17+
return false
18+
}
19+
gidPrefix := fmt.Sprintf("%d-", ctx.Event.GroupID)
20+
var words []string
21+
_ = wordSet.Iter(func(s string) error {
22+
trueWord := strings.SplitN(s, gidPrefix, 1)[1]
23+
words = append(words, trueWord)
24+
return nil
25+
})
26+
for _, word := range words {
27+
if strings.Contains(ctx.MessageString(), word) {
28+
if err := insertUser(gid, uid); err != nil {
29+
ctx.SendChain(message.Text("ban error: ", err))
30+
}
31+
banSet.Add(uuid)
32+
ctx.SetGroupBan(gid, uid, 4*3600)
33+
time.AfterFunc(4*time.Hour, func() {
34+
banSet.Remove(uuid)
35+
if err := deleteUser(gid, uid); err != nil {
36+
ctx.SendChain(message.Text("ban error: ", err))
37+
}
38+
})
39+
ctx.SendChain(message.Text("检测到违禁词,已封禁/屏蔽4小时"))
40+
return false
41+
}
42+
}
43+
return true
44+
}

0 commit comments

Comments
 (0)