-
Notifications
You must be signed in to change notification settings - Fork 5
/
matcher.go
150 lines (132 loc) · 3.4 KB
/
matcher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package nano
import (
"sort"
"sync"
"github.com/wdvxdr1123/ZeroBot/extension/rate"
)
type (
// Rule filter the event
Rule func(ctx *Ctx) bool
// Process 事件处理函数
Process func(ctx *Ctx)
)
// Matcher 是 ZeroBot 匹配和处理事件的最小单元
type Matcher struct {
// Temp 是否为临时Matcher,临时 Matcher 匹配一次后就会删除当前 Matcher
Temp bool
// Block 是否阻断后续 Matcher,为 true 时当前Matcher匹配成功后,后续Matcher不参与匹配
Block bool
// Break 是否退出后续匹配流程, 只有 rule 返回 false 且此值为真才会退出, 且不对 mid handler 以下的 rule 生效
Break bool
// priority 优先级,越小优先级越高
priority int
// Event 当前匹配到的事件
Event *Event
// Type 匹配的事件类型
Type string
// Rules 匹配规则
Rules []Rule
// Process 处理事件的函数
Process Process
// Engine 注册 Matcher 的 Engine,Engine可为一系列 Matcher 添加通用 Rule 和 其他钩子
Engine *Engine
}
var (
// 所有主匹配器列表
matcherMap = make(map[string][]*Matcher, 0)
// Matcher 修改读写锁
matcherLock = sync.RWMutex{}
)
// State store the context of a matcher.
type State map[string]any
func sortMatcher(typ string) {
sort.Slice(matcherMap[typ], func(i, j int) bool { // 按优先级排序
return matcherMap[typ][i].priority < matcherMap[typ][j].priority
})
}
// SetBlock 设置是否阻断后面的 Matcher 触发
func (m *Matcher) SetBlock(block bool) *Matcher {
m.Block = block
return m
}
// setPriority 设置当前 Matcher 优先级
func (m *Matcher) setPriority(priority int) *Matcher {
matcherLock.Lock()
defer matcherLock.Unlock()
m.priority = priority
sortMatcher(m.Type)
return m
}
/*
// firstPriority 设置当前 Matcher 优先级 - 0
func (m *Matcher) firstPriority() *Matcher {
return m.setPriority(0)
}
*/
// secondPriority 设置当前 Matcher 优先级 - 1
func (m *Matcher) secondPriority() *Matcher {
return m.setPriority(1)
}
/*
// thirdPriority 设置当前 Matcher 优先级 - 2
func (m *Matcher) thirdPriority() *Matcher {
return m.setPriority(2)
}
*/
// Limit 限速器
//
// postfn 当请求被拒绝时的操作
func (m *Matcher) Limit(limiterfn func(*Ctx) *rate.Limiter, postfn ...func(*Ctx)) *Matcher {
m.Rules = append(m.Rules, func(ctx *Ctx) bool {
if limiterfn(ctx).Acquire() {
return true
}
if len(postfn) > 0 {
for _, fn := range postfn {
fn(ctx)
}
}
return false
})
return m
}
// StoreMatcher store a matcher to matcher list.
func StoreMatcher(m *Matcher) *Matcher {
matcherLock.Lock()
defer matcherLock.Unlock()
matcherMap[m.Type] = append(matcherMap[m.Type], m)
sortMatcher(m.Type)
return m
}
// StoreTempMatcher store a matcher only triggered once.
func StoreTempMatcher(m *Matcher) *Matcher {
m.Temp = true
StoreMatcher(m)
return m
}
// Delete remove the matcher from list
func (m *Matcher) Delete() {
matcherLock.Lock()
defer matcherLock.Unlock()
for i, matcher := range matcherMap[m.Type] {
if m == matcher {
matcherMap[m.Type] = append(matcherMap[m.Type][:i], matcherMap[m.Type][i+1:]...)
}
}
}
func (m *Matcher) copy() *Matcher {
return &Matcher{
Type: m.Type,
Rules: m.Rules,
Block: m.Block,
priority: m.priority,
Process: m.Process,
Temp: m.Temp,
Engine: m.Engine,
}
}
// Handle 直接处理事件
func (m *Matcher) Handle(handler Process) *Matcher {
m.Process = handler
return m
}