1
0
mirror of https://github.com/Mrs4s/go-cqhttp.git synced 2025-05-04 19:17:37 +08:00

Fix EventFilter & Add reload_event_filter

修复憨批错误
This commit is contained in:
wdvxdr 2020-09-10 19:28:20 +08:00
parent b33bb37da9
commit faba3e042f
8 changed files with 63 additions and 58 deletions

View File

@ -627,6 +627,11 @@ func (bot *CQBot) CQCanSendRecord() MSG {
return OK(MSG{"yes": true})
}
func (bot *CQBot) CQReloadEventFilter() MSG {
global.BootFilter()
return OK(nil)
}
func (bot *CQBot) CQGetStatus() MSG {
return OK(MSG{
"app_initialized": true,

View File

@ -226,7 +226,7 @@ func (bot *CQBot) Release() {
func (bot *CQBot) dispatchEventMessage(m MSG) {
payload := gjson.Parse(m.ToJson())
filter := global.GetFilter()
filter := global.EventFilter
if filter != nil && (*filter).Eval(payload) == false {
log.Debug("Event filtered!")
return

View File

@ -6,7 +6,6 @@ import (
"io/ioutil"
"regexp"
"strings"
"sync"
)
type Filter interface {
@ -14,7 +13,7 @@ type Filter interface {
}
type OperationNode struct {
key string
key string
filter Filter
}
@ -24,15 +23,14 @@ type NotOperator struct {
func notOperatorConstruct(argument gjson.Result) *NotOperator {
if !argument.IsObject() {
log.Error("the argument of 'not' operator must be an object")
panic("the argument of 'not' operator must be an object")
}
op := new(NotOperator)
op.operand_ = GetOperatorFactory().Generate("and", argument)
op.operand_ = Generate("and", argument)
return op
}
func (notOperator NotOperator) Eval(payload gjson.Result) bool {
log.Debug("not " + payload.Str)
return !(notOperator.operand_).Eval(payload)
}
@ -42,7 +40,7 @@ type AndOperator struct {
func andOperatorConstruct(argument gjson.Result) *AndOperator {
if !argument.IsObject() {
log.Error("the argument of 'and' operator must be an object")
panic("the argument of 'and' operator must be an object")
}
op := new(AndOperator)
argument.ForEach(func(key, value gjson.Result) bool {
@ -52,19 +50,19 @@ func andOperatorConstruct(argument gjson.Result) *AndOperator {
// "bar": "baz"
// }
opKey := key.Str[1:]
op.operands = append(op.operands, OperationNode{"", GetOperatorFactory().Generate(opKey, value)})
op.operands = append(op.operands, OperationNode{"", Generate(opKey, value)})
} else if value.IsObject() {
// is an normal key with an object as the value
// "foo": {
// ".bar": "baz"
// }
opKey := key.Str
op.operands = append(op.operands, OperationNode{opKey, GetOperatorFactory().Generate("and", value)})
opKey := key.String()
op.operands = append(op.operands, OperationNode{opKey, Generate("and", value)})
} else {
// is an normal key with a non-object as the value
// "foo": "bar"
opKey := key.Str
op.operands = append(op.operands, OperationNode{opKey, GetOperatorFactory().Generate("eq", value)})
opKey := key.String()
op.operands = append(op.operands, OperationNode{opKey, Generate("eq", value)})
}
return true
})
@ -72,7 +70,6 @@ func andOperatorConstruct(argument gjson.Result) *AndOperator {
}
func (andOperator *AndOperator) Eval(payload gjson.Result) bool {
log.Debug("and " + payload.Str)
res := true
for _, operand := range andOperator.operands {
@ -98,19 +95,18 @@ type OrOperator struct {
func orOperatorConstruct(argument gjson.Result) *OrOperator {
if !argument.IsArray() {
log.Error("the argument of 'or' operator must be an array")
panic("the argument of 'or' operator must be an array")
}
op := new(OrOperator)
argument.ForEach(func(_, value gjson.Result) bool {
op.operands = append(op.operands, GetOperatorFactory().Generate("and", value))
op.operands = append(op.operands, Generate("and", value))
return true
})
return op
}
func (orOperator OrOperator) Eval(payload gjson.Result) bool {
log.Debug("or "+ payload.Str)
res:= false
res := false
for _, operand := range orOperator.operands {
res = res || operand.Eval(payload)
@ -132,8 +128,7 @@ func equalOperatorConstruct(argument gjson.Result) *EqualOperator {
}
func (equalOperator EqualOperator) Eval(payload gjson.Result) bool {
log.Debug("eq "+ payload.Str + "==" + equalOperator.value.Str)
return payload.Str == equalOperator.value.Str
return payload.String() == equalOperator.value.String()
}
type NotEqualOperator struct {
@ -147,18 +142,16 @@ func notEqualOperatorConstruct(argument gjson.Result) *NotEqualOperator {
}
func (notEqualOperator NotEqualOperator) Eval(payload gjson.Result) bool {
log.Debug("neq " + payload.Str)
return !(payload.Str == notEqualOperator.value.Str)
return !(payload.String() == notEqualOperator.value.String())
}
type InOperator struct {
operand gjson.Result
}
func inOperatorConstruct(argument gjson.Result) *InOperator {
if argument.IsObject() {
log.Error("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.operand = argument
@ -166,16 +159,15 @@ func inOperatorConstruct(argument gjson.Result) *InOperator {
}
func (inOperator InOperator) Eval(payload gjson.Result) bool {
log.Debug("in " + payload.Str)
if inOperator.operand.IsArray() {
res := false
inOperator.operand.ForEach(func(key, value gjson.Result) bool {
res = res || value.Str == payload.Str
res = res || value.String() == payload.String()
return true
})
return res
}
return strings.Contains(inOperator.operand.Str, payload.Str)
return strings.Contains(inOperator.operand.String(), payload.String())
}
type ContainsOperator struct {
@ -184,15 +176,14 @@ type ContainsOperator struct {
func containsOperatorConstruct(argument gjson.Result) *ContainsOperator {
if argument.IsArray() || argument.IsObject() {
log.Error("the argument of 'contains' operator must be a string")
panic("the argument of 'contains' operator must be a string")
}
op := new(ContainsOperator)
op.operand = argument.Str
op.operand = argument.String()
return op
}
func (containsOperator ContainsOperator) Eval(payload gjson.Result) bool {
log.Debug("contains "+ payload.Str)
if payload.IsObject() || payload.IsArray() {
return false
}
@ -205,29 +196,19 @@ type RegexOperator struct {
func regexOperatorConstruct(argument gjson.Result) *RegexOperator {
if argument.IsArray() || argument.IsObject() {
log.Error("the argument of 'regex' operator must be a string")
panic("the argument of 'regex' operator must be a string")
}
op := new(RegexOperator)
op.regex = argument.Str
op.regex = argument.String()
return op
}
func (containsOperator RegexOperator) Eval(payload gjson.Result) bool {
log.Debug("regex " + payload.Str)
matched, _ := regexp.MatchString(containsOperator.regex, payload.Str)
matched, _ := regexp.MatchString(containsOperator.regex, payload.String())
return matched
}
// 单例工厂
type operatorFactory struct{
}
var instance *operatorFactory = &operatorFactory{}
func GetOperatorFactory() *operatorFactory {
return instance
}
func (o operatorFactory) Generate(opName string, argument gjson.Result) Filter {
func Generate(opName string, argument gjson.Result) Filter {
switch opName {
case "not":
return notOperatorConstruct(argument)
@ -246,22 +227,25 @@ func (o operatorFactory) Generate(opName string, argument gjson.Result) Filter {
case "regex":
return regexOperatorConstruct(argument)
default:
log.Warnf("the operator '%s' is not supported", opName)
return nil
panic("the operator " + opName + " is not supported")
}
}
var filter = new(Filter)
var once sync.Once // 过滤器单例模式
var EventFilter = new(Filter)
func GetFilter() *Filter {
once.Do(func() {
f, err := ioutil.ReadFile("filter.json")
if err != nil {
filter = nil
func BootFilter() {
defer func() {
if e := recover(); e != nil {
log.Warnf("事件过滤器启动失败: %v", e)
EventFilter = nil
} else {
*filter = GetOperatorFactory().Generate("and", gjson.ParseBytes(f))
log.Info("事件过滤器启动成功.")
}
})
return filter
}
}()
f, err := ioutil.ReadFile("filter.json")
if err != nil {
panic(err)
} else {
*EventFilter = Generate("and", gjson.ParseBytes(f))
}
}

4
go.mod
View File

@ -12,7 +12,7 @@ require (
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
github.com/jonboulle/clockwork v0.2.0 // indirect
github.com/json-iterator/go v1.1.10 // indirect
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/lestrrat-go/strftime v1.0.3 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
@ -25,7 +25,7 @@ require (
github.com/xujiajun/nutsdb v0.5.0
github.com/yinghau76/go-ascii-art v0.0.0-20190517192627-e7f465a30189
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f // indirect
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
gopkg.in/yaml.v2 v2.3.0 // indirect
)

4
go.sum
View File

@ -70,6 +70,8 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible h1:4mNlp+/SvALIPFpbXV3kxNJJno9iKFWGxSDE13Kl66Q=
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/strftime v1.0.3 h1:qqOPU7y+TM8Y803I8fG9c/DyKG3xH/xkng6keC1015Q=
github.com/lestrrat-go/strftime v1.0.3/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
@ -146,6 +148,8 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f h1:Fqb3ao1hUmOR3GkUOg/Y+BadLwykBIzs5q8Ez2SbHyc=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=

View File

@ -280,6 +280,8 @@ func main() {
for _, rc := range conf.ReverseServers {
server.NewWebsocketClient(rc, conf.AccessToken, b).Run()
}
log.Info("正在加载事件过滤器.")
global.BootFilter()
log.Info("资源初始化完成, 开始处理信息.")
log.Info("アトリは、高性能ですから!")
cli.OnDisconnected(func(bot *client.QQClient, e *client.ClientDisconnectedEvent) {

View File

@ -324,6 +324,10 @@ func (s *httpServer) GetVersionInfo(c *gin.Context) {
c.JSON(200, s.bot.CQGetVersionInfo())
}
func (s *httpServer) ReloadEventFilter(c *gin.Context) {
c.JSON(200, s.bot.CQReloadEventFilter())
}
func (s *httpServer) GetVipInfo(c *gin.Context) {
uid, _ := strconv.ParseInt(getParam(c, "user_id"), 10, 64)
c.JSON(200, s.bot.CQGetVipInfo(uid))
@ -482,6 +486,9 @@ var httpApi = map[string]func(s *httpServer, c *gin.Context){
"_get_vip_info": func(s *httpServer, c *gin.Context) {
s.GetVipInfo(c)
},
"reload_event_filter": func(s *httpServer, c *gin.Context) {
s.ReloadEventFilter(c)
},
".handle_quick_operation": func(s *httpServer, c *gin.Context) {
s.HandleQuickOperation(c)
},

View File

@ -495,6 +495,9 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{
"_get_vip_info": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQGetVipInfo(p.Get("user_id").Int())
},
"reload_event_filter": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQReloadEventFilter()
},
".handle_quick_operation": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQHandleQuickOperation(p.Get("context"), p.Get("operation"))
},