添加ban人记忆

This commit is contained in:
源文雨 2022-09-06 21:20:32 +08:00
parent 3cfe1a6960
commit ef9f764fa0
2 changed files with 67 additions and 14 deletions

View File

@ -2,6 +2,7 @@
package antiabuse
import (
"strconv"
"strings"
"time"
@ -16,10 +17,12 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
)
const banhour = 4
var (
managers *ctrl.Manager[*zero.Ctx] // managers lazy load
cache = ttl.NewCacheOn(4*time.Hour, [4]func(int64, struct{}){nil, nil, onDel, nil})
db = &antidb{}
cache = ttl.NewCacheOn(banhour*time.Hour, [4]func(int64, struct{}){nil, nil, onDel, nil})
db *antidb
)
func onDel(uid int64, _ struct{}) {
@ -27,7 +30,10 @@ func onDel(uid int64, _ struct{}) {
return
}
if err := managers.DoUnblock(uid); err != nil {
logrus.Errorln("[antiabuse] do unblock:", err)
logrus.Errorln("[antiabuse.onDel] unblock:", err)
}
if err := db.Del("__bantime__", "WHERE id="+strconv.FormatInt(uid, 10)); err != nil {
logrus.Errorln("[antiabuse.onDel] db:", err)
}
}
@ -40,8 +46,8 @@ func init() {
onceRule := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
managers = ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager
db.DBPath = engine.DataFolder() + "anti_abuse.db"
err := db.Open(time.Hour * 4)
var err error
db, err = newantidb(engine.DataFolder() + "anti_abuse.db")
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return false
@ -61,9 +67,22 @@ func init() {
msg = strings.ReplaceAll(msg, ";", "")
if db.isInAntiList(uid, gid, msg) {
if err := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager.DoBlock(uid); err == nil {
t := time.Now().Unix()
cache.Set(uid, struct{}{})
ctx.SetGroupBan(gid, uid, 4*3600)
ctx.SendChain(message.Text("检测到违禁词, 已封禁/屏蔽4小时"))
ctx.SetGroupBan(gid, uid, banhour*3600)
ctx.SendChain(message.Text("检测到违禁词, 已封禁/屏蔽", banhour, "小时"))
db.Lock()
defer db.Unlock()
err := db.Create("__bantime__", nilbt)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return false
}
err = db.Insert("__bantime__", &banTime{ID: uid, Time: t})
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return false
}
} else {
ctx.SendChain(message.Text("ERROR: block user: ", err))
}

View File

@ -5,6 +5,7 @@ import (
"strconv"
"strings"
"sync"
"time"
sqlite "github.com/FloatTech/sqlite"
)
@ -18,7 +19,34 @@ type banWord struct {
Word string `db:"word"`
}
var nilban = &banWord{}
type banTime struct {
ID int64 `db:"id"`
Time int64 `db:"time"`
}
var (
nilban = &banWord{}
nilbt = &banTime{}
)
func newantidb(path string) (*antidb, error) {
db := &antidb{Sqlite: sqlite.Sqlite{DBPath: path}}
err := db.Open(time.Hour * banhour)
if err != nil {
return nil, err
}
_ = db.Del("__bantime__", "WHERE time<="+strconv.FormatInt(time.Now().Add(-time.Hour*banhour).Unix(), 10))
return db, db.FindFor("__bantime__", nilbt, "", func() error {
t := time.Unix(nilbt.Time, 0)
ttl := time.Until(t.Add(time.Hour * banhour)) // second
if ttl < time.Minute {
return nil
}
cache.Set(nilbt.ID, struct{}{})
cache.Touch(nilbt.ID, -time.Since(t))
return nil
})
}
func (db *antidb) isInAntiList(uid, gid int64, msg string) bool {
grp := strconv.FormatInt(gid, 36)
@ -52,15 +80,21 @@ func (db *antidb) listWords(gid int64) string {
grp := strconv.FormatInt(gid, 36)
word := &banWord{}
sb := strings.Builder{}
db.Lock()
defer db.Unlock()
sb.WriteByte('[')
i := 0
db.RLock()
defer db.RUnlock()
_ = db.FindFor(grp, word, "", func() error {
if i > 0 {
sb.WriteString(" | ")
}
sb.WriteString(word.Word)
sb.WriteString(" | ")
i++
return nil
})
if sb.Len() <= 3 {
return ""
if sb.Len() <= 4 {
return "[]"
}
return sb.String()[:sb.Len()-3]
sb.WriteByte(']')
return sb.String()
}