mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-06 20:13:50 +08:00
⚡ improve event filter
This commit is contained in:
parent
1fbaa6107d
commit
947d165ac5
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 strings.Contains(inOperator.operand.String(), payload.String())
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user