Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
G
go-cqhttp
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
go-cqhttp
Commits
382daf48
Commit
382daf48
authored
Aug 22, 2020
by
Mrs4s
Committed by
GitHub
Aug 22, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #162 from wdvxdr1123/master
反向WS添加事件过滤器
parents
2259e7cc
2b92035f
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
273 additions
and
0 deletions
+273
-0
global/filter.go
global/filter.go
+267
-0
server/websocket.go
server/websocket.go
+6
-0
No files found.
global/filter.go
0 → 100644
View file @
382daf48
package
global
import
(
log
"github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"io/ioutil"
"regexp"
"strings"
"sync"
)
type
Filter
interface
{
Eval
(
payload
gjson
.
Result
)
bool
}
type
OperationNode
struct
{
key
string
filter
Filter
}
type
NotOperator
struct
{
operand_
Filter
}
func
notOperatorConstruct
(
argument
gjson
.
Result
)
*
NotOperator
{
if
!
argument
.
IsObject
()
{
log
.
Error
(
"the argument of 'not' operator must be an object"
)
}
op
:=
new
(
NotOperator
)
op
.
operand_
=
GetOperatorFactory
()
.
Generate
(
"and"
,
argument
)
return
op
}
func
(
notOperator
NotOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"not "
+
payload
.
Str
)
return
!
(
notOperator
.
operand_
)
.
Eval
(
payload
)
}
type
AndOperator
struct
{
operands
[]
OperationNode
}
func
andOperatorConstruct
(
argument
gjson
.
Result
)
*
AndOperator
{
if
!
argument
.
IsObject
()
{
log
.
Error
(
"the argument of 'and' operator must be an object"
)
}
op
:=
new
(
AndOperator
)
argument
.
ForEach
(
func
(
key
,
value
gjson
.
Result
)
bool
{
if
key
.
Str
[
0
]
==
'.'
{
// is an operator
// ".foo": {
// "bar": "baz"
// }
opKey
:=
key
.
Str
[
1
:
]
op
.
operands
=
append
(
op
.
operands
,
OperationNode
{
""
,
GetOperatorFactory
()
.
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
)})
}
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
)})
}
return
true
})
return
op
}
func
(
andOperator
*
AndOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"and "
+
payload
.
Str
)
res
:=
true
for
_
,
operand
:=
range
andOperator
.
operands
{
if
len
(
operand
.
key
)
==
0
{
// is an operator
res
=
res
&&
operand
.
filter
.
Eval
(
payload
)
}
else
{
// is an normal key
val
:=
payload
.
Get
(
operand
.
key
)
res
=
res
&&
operand
.
filter
.
Eval
(
val
)
}
if
res
==
false
{
break
}
}
return
res
}
type
OrOperator
struct
{
operands
[]
Filter
}
func
orOperatorConstruct
(
argument
gjson
.
Result
)
*
OrOperator
{
if
!
argument
.
IsArray
()
{
log
.
Error
(
"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
))
return
true
})
return
op
}
func
(
orOperator
OrOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"or "
+
payload
.
Str
)
res
:=
false
for
_
,
operand
:=
range
orOperator
.
operands
{
res
=
res
||
operand
.
Eval
(
payload
)
if
res
==
true
{
break
}
}
return
res
}
type
EqualOperator
struct
{
value
gjson
.
Result
}
func
equalOperatorConstruct
(
argument
gjson
.
Result
)
*
EqualOperator
{
op
:=
new
(
EqualOperator
)
op
.
value
=
argument
return
op
}
func
(
equalOperator
EqualOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"eq "
+
payload
.
Str
+
"=="
+
equalOperator
.
value
.
Str
)
return
payload
.
Str
==
equalOperator
.
value
.
Str
}
type
NotEqualOperator
struct
{
value
gjson
.
Result
}
func
notEqualOperatorConstruct
(
argument
gjson
.
Result
)
*
NotEqualOperator
{
op
:=
new
(
NotEqualOperator
)
op
.
value
=
argument
return
op
}
func
(
notEqualOperator
NotEqualOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"neq "
+
payload
.
Str
)
return
!
(
payload
.
Str
==
notEqualOperator
.
value
.
Str
)
}
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"
)
}
op
:=
new
(
InOperator
)
op
.
operand
=
argument
return
op
}
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
return
true
})
return
res
}
return
strings
.
Contains
(
inOperator
.
operand
.
Str
,
payload
.
Str
)
}
type
ContainsOperator
struct
{
operand
string
}
func
containsOperatorConstruct
(
argument
gjson
.
Result
)
*
ContainsOperator
{
if
argument
.
IsArray
()
||
argument
.
IsObject
()
{
log
.
Error
(
"the argument of 'contains' operator must be a string"
)
}
op
:=
new
(
ContainsOperator
)
op
.
operand
=
argument
.
Str
return
op
}
func
(
containsOperator
ContainsOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"contains "
+
payload
.
Str
)
if
payload
.
IsObject
()
||
payload
.
IsArray
()
{
return
false
}
return
strings
.
Contains
(
payload
.
String
(),
containsOperator
.
operand
)
}
type
RegexOperator
struct
{
regex
string
}
func
regexOperatorConstruct
(
argument
gjson
.
Result
)
*
RegexOperator
{
if
argument
.
IsArray
()
||
argument
.
IsObject
()
{
log
.
Error
(
"the argument of 'regex' operator must be a string"
)
}
op
:=
new
(
RegexOperator
)
op
.
regex
=
argument
.
Str
return
op
}
func
(
containsOperator
RegexOperator
)
Eval
(
payload
gjson
.
Result
)
bool
{
log
.
Debug
(
"regex "
+
payload
.
Str
)
matched
,
_
:=
regexp
.
MatchString
(
containsOperator
.
regex
,
payload
.
Str
)
return
matched
}
// 单例工厂
type
operatorFactory
struct
{
}
var
instance
*
operatorFactory
=
&
operatorFactory
{}
func
GetOperatorFactory
()
*
operatorFactory
{
return
instance
}
func
(
o
operatorFactory
)
Generate
(
opName
string
,
argument
gjson
.
Result
)
Filter
{
switch
opName
{
case
"not"
:
return
notOperatorConstruct
(
argument
)
case
"and"
:
return
andOperatorConstruct
(
argument
)
case
"or"
:
return
orOperatorConstruct
(
argument
)
case
"neq"
:
return
notEqualOperatorConstruct
(
argument
)
case
"eq"
:
return
equalOperatorConstruct
(
argument
)
case
"in"
:
return
inOperatorConstruct
(
argument
)
case
"contains"
:
return
containsOperatorConstruct
(
argument
)
case
"regex"
:
return
regexOperatorConstruct
(
argument
)
default
:
log
.
Warnf
(
"the operator '%s' is not supported"
,
opName
)
return
nil
}
}
var
filter
=
new
(
Filter
)
var
once
sync
.
Once
// 过滤器单例模式
func
GetFilter
()
*
Filter
{
once
.
Do
(
func
()
{
f
,
err
:=
ioutil
.
ReadFile
(
"filter.json"
)
if
err
!=
nil
{
filter
=
nil
}
else
{
*
filter
=
GetOperatorFactory
()
.
Generate
(
"and"
,
gjson
.
ParseBytes
(
f
))
}
})
return
filter
}
\ No newline at end of file
server/websocket.go
View file @
382daf48
...
...
@@ -172,6 +172,12 @@ func (c *websocketClient) listenApi(conn *websocketConn, u bool) {
}
func
(
c
*
websocketClient
)
onBotPushEvent
(
m
coolq
.
MSG
)
{
payload
:=
gjson
.
Parse
(
m
.
ToJson
())
filter
:=
global
.
GetFilter
()
if
filter
!=
nil
&&
(
*
filter
)
.
Eval
(
payload
)
==
false
{
log
.
Debug
(
"Event filtered!"
)
return
}
if
c
.
eventConn
!=
nil
{
log
.
Debugf
(
"向WS服务器 %v 推送Event: %v"
,
c
.
eventConn
.
RemoteAddr
()
.
String
(),
m
.
ToJson
())
c
.
eventConn
.
Lock
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment