添加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 package antiabuse
import ( import (
"strconv"
"strings" "strings"
"time" "time"
@ -16,10 +17,12 @@ import (
"github.com/wdvxdr1123/ZeroBot/message" "github.com/wdvxdr1123/ZeroBot/message"
) )
const banhour = 4
var ( var (
managers *ctrl.Manager[*zero.Ctx] // managers lazy load managers *ctrl.Manager[*zero.Ctx] // managers lazy load
cache = ttl.NewCacheOn(4*time.Hour, [4]func(int64, struct{}){nil, nil, onDel, nil}) cache = ttl.NewCacheOn(banhour*time.Hour, [4]func(int64, struct{}){nil, nil, onDel, nil})
db = &antidb{} db *antidb
) )
func onDel(uid int64, _ struct{}) { func onDel(uid int64, _ struct{}) {
@ -27,7 +30,10 @@ func onDel(uid int64, _ struct{}) {
return return
} }
if err := managers.DoUnblock(uid); err != nil { 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 { onceRule := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
managers = ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager managers = ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager
db.DBPath = engine.DataFolder() + "anti_abuse.db" var err error
err := db.Open(time.Hour * 4) db, err = newantidb(engine.DataFolder() + "anti_abuse.db")
if err != nil { if err != nil {
ctx.SendChain(message.Text("ERROR: ", err)) ctx.SendChain(message.Text("ERROR: ", err))
return false return false
@ -61,9 +67,22 @@ func init() {
msg = strings.ReplaceAll(msg, ";", "") msg = strings.ReplaceAll(msg, ";", "")
if db.isInAntiList(uid, gid, msg) { if db.isInAntiList(uid, gid, msg) {
if err := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager.DoBlock(uid); err == nil { if err := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager.DoBlock(uid); err == nil {
t := time.Now().Unix()
cache.Set(uid, struct{}{}) cache.Set(uid, struct{}{})
ctx.SetGroupBan(gid, uid, 4*3600) ctx.SetGroupBan(gid, uid, banhour*3600)
ctx.SendChain(message.Text("检测到违禁词, 已封禁/屏蔽4小时")) 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 { } else {
ctx.SendChain(message.Text("ERROR: block user: ", err)) ctx.SendChain(message.Text("ERROR: block user: ", err))
} }

View File

@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time"
sqlite "github.com/FloatTech/sqlite" sqlite "github.com/FloatTech/sqlite"
) )
@ -18,7 +19,34 @@ type banWord struct {
Word string `db:"word"` 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 { func (db *antidb) isInAntiList(uid, gid int64, msg string) bool {
grp := strconv.FormatInt(gid, 36) grp := strconv.FormatInt(gid, 36)
@ -52,15 +80,21 @@ func (db *antidb) listWords(gid int64) string {
grp := strconv.FormatInt(gid, 36) grp := strconv.FormatInt(gid, 36)
word := &banWord{} word := &banWord{}
sb := strings.Builder{} sb := strings.Builder{}
db.Lock() sb.WriteByte('[')
defer db.Unlock() i := 0
db.RLock()
defer db.RUnlock()
_ = db.FindFor(grp, word, "", func() error { _ = db.FindFor(grp, word, "", func() error {
if i > 0 {
sb.WriteString(" | ")
}
sb.WriteString(word.Word) sb.WriteString(word.Word)
sb.WriteString(" | ") i++
return nil return nil
}) })
if sb.Len() <= 3 { if sb.Len() <= 4 {
return "" return "[]"
} }
return sb.String()[:sb.Len()-3] sb.WriteByte(']')
return sb.String()
} }