You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: anti.go
    path of file: ./repos/ZeroBot-Plugin/plugin/antiabuse
    
    the code of the file until where you have to start completion: // Package antiabuse defines antiabuse plugin ,support abuse words check and add/remove abuse words
package antiabuse

import (
	"strconv"
	"strings"
	"time"

	"github.com/FloatTech/floatbox/binary"
	fcext "github.com/FloatTech/floatbox/ctxext"
	"github.com/FloatTech/ttl"
	ctrl "github.com/FloatTech/zbpctrl"
	"github.com/FloatTech/zbputils/control"
	"github.com/FloatTech/zbputils/img/text"
	"github.com/sirupsen/logrus"
	zero "github.com/wdvxdr1123/ZeroBot"
	"github.com/wdvxdr1123/ZeroBot/message"
)

const bandur time.Duration = time.Minute * 10

var (
	managers *ctrl.Manager[*zero.Ctx] // managers lazy load
	cache    = ttl.NewCacheOn(bandur, [4]func(int64, struct{}){nil, nil, onDel, nil})
	db       *antidb
)

func onDel(uid int64, _ struct{}) {
	if managers == nil {
		return
	}
	if err := managers.DoUnblock(uid); err != nil {
		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)
	}
}

func init() {
	engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
		DisableOnDefault:  false,
		Brief:             "违禁词检测",
		Help:              "- /[添加|删除|查看]违禁词",
		PrivateDataFolder: "anti_abuse",
	})

	onceRule := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
		managers = ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager
		var err error
		db, err = newantidb(engine.DataFolder() + "anti_abuse.db")
		if err != nil {
			ctx.SendChain(message.Text("ERROR: ", err))
			return false
		}
		return true
	})

	engine.OnMessage(onceRule, zero.OnlyGroup, func(ctx *zero.Ctx) bool {
		if !ctx.Event.IsToMe {
			return true
		}
		uid := ctx.Event.UserID
		gid := ctx.Event.GroupID
		msg := strings.ReplaceAll(ctx.MessageString(), "\n", "")
		msg = strings.ReplaceAll(msg, "\r", "")
		msg = strings.ReplaceAll(msg, "\t", "")
		msg = strings.ReplaceAll(msg, ";", "")
		if db.isInAntiList(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.SetThisGroupBan(uid, int64(bandur.Minutes()))
				ctx.SendChain(message.Text("检测到违禁词, 已封禁/屏蔽", bandur))
				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
    
func init() {
	engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
		DisableOnDefault:  false,
		Brief:             "违禁词检测",
		Help:              "- /[添加|删除|查看]违禁词",
		PrivateDataFolder: "anti_abuse",
	})

	onceRule := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
		managers = ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).Manager
		var err error
		db, err = newantidb(engine.DataFolder() + "anti_abuse.db")
		if err != nil {
			ctx.SendChain(message.Text("ERROR: ", err))
			return false
		}
		return true
	})

	engine.OnMessage(onceRule, zero.OnlyGroup, func(ctx *zero.Ctx) bool {
		if !ctx.Event.IsToMe {
			return true
		}
		uid := ctx.Event.UserID
		gid := ctx.Event.GroupID
		msg := strings.ReplaceAll(ctx.MessageString(), "\n", "")
		msg = strings.ReplaceAll(msg, "\r", "")
		msg = strings.ReplaceAll(msg, "\t", "")
		msg = strings.ReplaceAll(msg, ";", "")
		if db.isInAntiList(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.SetThisGroupBan(uid, int64(bandur.Minutes()))
				ctx.SendChain(message.Text("检测到违禁词, 已封禁/屏蔽", bandur))
				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))
			}
			return false
		}
		return true
	})

	engine.OnCommand("添加违禁词", zero.OnlyGroup, zero.AdminPermission, onceRule).Handle(
		func(ctx *zero.Ctx) {
			args := ctx.State["args"].(string)
			if err := db.insertWord(ctx.Event.GroupID, args); err != nil {
				ctx.SendChain(message.Text("ERROR: ", err))
			} else {
				ctx.SendChain(message.Text("成功"))
			}
		})

	engine.OnCommand("删除违禁词", zero.OnlyGroup, zero.AdminPermission, onceRule).Handle(
		func(ctx *zero.Ctx) {
			args := ctx.State["args"].(string)
			if err := db.deleteWord(ctx.Event.GroupID, args); err != nil {
				ctx.SendChain(message.Text("ERROR: ", err))
			} else {
				ctx.SendChain(message.Text("成功"))
			}
		})

	engine.OnCommand("查看违禁词", zero.OnlyGroup, onceRule).Handle(
		func(ctx *zero.Ctx) {
			b, err := text.RenderToBase64(db.listWords(ctx.Event.GroupID), text.FontFile, 400, 20)
			if err != nil {
				ctx.SendChain(message.Text("ERROR: ", err))
				return
			}
			ctx.SendChain(message.Text("本群违禁词有\n"), message.Image("base64://"+binary.BytesToString(b)))
		})
}