1
0
mirror of https://github.com/Mrs4s/go-cqhttp.git synced 2025-05-06 12:03:50 +08:00

improve event filter

This commit is contained in:
wdvxdr 2020-12-03 20:52:13 +08:00
parent 1fbaa6107d
commit 947d165ac5
2 changed files with 51 additions and 45 deletions

View File

@ -392,22 +392,19 @@ func (bot *CQBot) Release() {
} }
func (bot *CQBot) dispatchEventMessage(m MSG) { func (bot *CQBot) dispatchEventMessage(m MSG) {
payload := gjson.Parse(m.ToJson()) if global.EventFilter != nil && global.EventFilter.Eval(gjson.Parse(m.ToJson())) == false {
filter := global.EventFilter
if filter != nil && (*filter).Eval(payload) == false {
log.Debug("Event filtered!") log.Debug("Event filtered!")
return return
} }
for _, f := range bot.events { for _, f := range bot.events {
fn := f go func(fn func(MSG)) {
go func() {
start := time.Now() start := time.Now()
fn(m) fn(m)
end := time.Now() end := time.Now()
if end.Sub(start) > time.Second*5 { if end.Sub(start) > time.Second*5 {
log.Debugf("警告: 事件处理耗时超过 5 秒 (%v), 请检查应用是否有堵塞.", end.Sub(start)) log.Debugf("警告: 事件处理耗时超过 5 秒 (%v), 请检查应用是否有堵塞.", end.Sub(start))
} }
}() }(f)
} }
} }

View File

@ -13,13 +13,13 @@ type Filter interface {
Eval(payload gjson.Result) bool Eval(payload gjson.Result) bool
} }
type OperationNode struct { type operationNode struct {
key string key string
filter Filter filter Filter
} }
type NotOperator struct { type NotOperator struct {
operand_ Filter operand Filter
} }
func notOperatorConstruct(argument gjson.Result) *NotOperator { func notOperatorConstruct(argument gjson.Result) *NotOperator {
@ -27,16 +27,16 @@ func notOperatorConstruct(argument gjson.Result) *NotOperator {
panic("the argument of 'not' operator must be an object") panic("the argument of 'not' operator must be an object")
} }
op := new(NotOperator) op := new(NotOperator)
op.operand_ = Generate("and", argument) op.operand = Generate("and", argument)
return op return op
} }
func (notOperator NotOperator) Eval(payload gjson.Result) bool { func (op *NotOperator) Eval(payload gjson.Result) bool {
return !(notOperator.operand_).Eval(payload) return !op.operand.Eval(payload)
} }
type AndOperator struct { type AndOperator struct {
operands []OperationNode operands []operationNode
} }
func andOperatorConstruct(argument gjson.Result) *AndOperator { func andOperatorConstruct(argument gjson.Result) *AndOperator {
@ -51,19 +51,19 @@ func andOperatorConstruct(argument gjson.Result) *AndOperator {
// "bar": "baz" // "bar": "baz"
// } // }
opKey := key.Str[1:] opKey := key.Str[1:]
op.operands = append(op.operands, OperationNode{"", Generate(opKey, value)}) op.operands = append(op.operands, operationNode{"", Generate(opKey, value)})
} else if value.IsObject() { } else if value.IsObject() {
// is an normal key with an object as the value // is an normal key with an object as the value
// "foo": { // "foo": {
// ".bar": "baz" // ".bar": "baz"
// } // }
opKey := key.String() opKey := key.String()
op.operands = append(op.operands, OperationNode{opKey, Generate("and", value)}) op.operands = append(op.operands, operationNode{opKey, Generate("and", value)})
} else { } else {
// is an normal key with a non-object as the value // is an normal key with a non-object as the value
// "foo": "bar" // "foo": "bar"
opKey := key.String() opKey := key.String()
op.operands = append(op.operands, OperationNode{opKey, Generate("eq", value)}) op.operands = append(op.operands, operationNode{opKey, Generate("eq", value)})
} }
return true return true
}) })
@ -106,11 +106,10 @@ func orOperatorConstruct(argument gjson.Result) *OrOperator {
return op return op
} }
func (orOperator OrOperator) Eval(payload gjson.Result) bool { func (op *OrOperator) Eval(payload gjson.Result) bool {
res := false res := false
for _, operand := range orOperator.operands { for _, operand := range op.operands {
res = res || operand.Eval(payload) res = res || operand.Eval(payload)
if res == true { if res == true {
break break
} }
@ -119,35 +118,36 @@ func (orOperator OrOperator) Eval(payload gjson.Result) bool {
} }
type EqualOperator struct { type EqualOperator struct {
value gjson.Result operand string
} }
func equalOperatorConstruct(argument gjson.Result) *EqualOperator { func equalOperatorConstruct(argument gjson.Result) *EqualOperator {
op := new(EqualOperator) op := new(EqualOperator)
op.value = argument op.operand = argument.String()
return op return op
} }
func (equalOperator EqualOperator) Eval(payload gjson.Result) bool { func (op *EqualOperator) Eval(payload gjson.Result) bool {
return payload.String() == equalOperator.value.String() return payload.String() == op.operand
} }
type NotEqualOperator struct { type NotEqualOperator struct {
value gjson.Result operand string
} }
func notEqualOperatorConstruct(argument gjson.Result) *NotEqualOperator { func notEqualOperatorConstruct(argument gjson.Result) *NotEqualOperator {
op := new(NotEqualOperator) op := new(NotEqualOperator)
op.value = argument op.operand = argument.String()
return op return op
} }
func (notEqualOperator NotEqualOperator) Eval(payload gjson.Result) bool { func (op *NotEqualOperator) Eval(payload gjson.Result) bool {
return !(payload.String() == notEqualOperator.value.String()) return !(payload.String() == op.operand)
} }
type InOperator struct { type InOperator struct {
operand gjson.Result operandString string
operandArray []string
} }
func inOperatorConstruct(argument gjson.Result) *InOperator { func inOperatorConstruct(argument gjson.Result) *InOperator {
@ -155,20 +155,29 @@ func inOperatorConstruct(argument gjson.Result) *InOperator {
panic("the argument of 'in' operator must be an array or a string") panic("the argument of 'in' operator must be an array or a string")
} }
op := new(InOperator) op := new(InOperator)
op.operand = argument if argument.IsArray() {
op.operandArray = []string{}
argument.ForEach(func(_, value gjson.Result) bool {
op.operandArray = append(op.operandArray, value.String())
return true
})
} else {
op.operandString = argument.String()
}
return op return op
} }
func (inOperator InOperator) Eval(payload gjson.Result) bool { func (op *InOperator) Eval(payload gjson.Result) bool {
if inOperator.operand.IsArray() { payloadStr := payload.String()
res := false if op.operandArray != nil {
inOperator.operand.ForEach(func(key, value gjson.Result) bool { for _, value := range op.operandArray {
res = res || value.String() == payload.String() if value == payloadStr {
return true return true
}) }
return res }
return false
} }
return strings.Contains(inOperator.operand.String(), payload.String()) return strings.Contains(op.operandString, payloadStr)
} }
type ContainsOperator struct { type ContainsOperator struct {
@ -184,15 +193,15 @@ func containsOperatorConstruct(argument gjson.Result) *ContainsOperator {
return op return op
} }
func (containsOperator ContainsOperator) Eval(payload gjson.Result) bool { func (op *ContainsOperator) Eval(payload gjson.Result) bool {
if payload.IsObject() || payload.IsArray() { if payload.IsObject() || payload.IsArray() {
return false return false
} }
return strings.Contains(payload.String(), containsOperator.operand) return strings.Contains(payload.String(), op.operand)
} }
type RegexOperator struct { type RegexOperator struct {
regex string regex *regexp.Regexp
} }
func regexOperatorConstruct(argument gjson.Result) *RegexOperator { func regexOperatorConstruct(argument gjson.Result) *RegexOperator {
@ -200,12 +209,12 @@ func regexOperatorConstruct(argument gjson.Result) *RegexOperator {
panic("the argument of 'regex' operator must be a string") panic("the argument of 'regex' operator must be a string")
} }
op := new(RegexOperator) op := new(RegexOperator)
op.regex = argument.String() op.regex = regexp.MustCompile(argument.String())
return op return op
} }
func (containsOperator RegexOperator) Eval(payload gjson.Result) bool { func (op *RegexOperator) Eval(payload gjson.Result) bool {
matched, _ := regexp.MatchString(containsOperator.regex, payload.String()) matched := op.regex.MatchString(payload.String())
return matched return matched
} }
@ -232,7 +241,7 @@ func Generate(opName string, argument gjson.Result) Filter {
} }
} }
var EventFilter = new(Filter) var EventFilter Filter = nil
func BootFilter() { func BootFilter() {
defer func() { defer func() {
@ -247,6 +256,6 @@ func BootFilter() {
if err != nil { if err != nil {
panic(err) panic(err)
} else { } else {
*EventFilter = Generate("and", gjson.ParseBytes(f)) EventFilter = Generate("and", gjson.ParseBytes(f))
} }
} }