-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaction.go
141 lines (130 loc) · 3.75 KB
/
action.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
package go_libonebot
import (
"errors"
"github.com/FishZe/go-libonebot/protocol"
"github.com/FishZe/go-libonebot/util"
"reflect"
"regexp"
"sync"
)
var (
// ErrorActionExist action已存在
ErrorActionExist = errors.New("action already exist")
// ErrorActionEmpty action为空
ErrorActionEmpty = errors.New("action is empty")
)
// ActionMux 请求处理接口
type ActionMux struct {
actionHandleFunc sync.Map
regexHandleFunc sync.Map
}
// regexActionMux 正则请求处理接口
type regexActionMux struct {
Re *regexp.Regexp
F protocol.RequestInterface
}
// NewActionMux 获取一个ActionMux
func NewActionMux() (a *ActionMux) {
a = new(ActionMux)
return
}
func (a *ActionMux) checkRequestInterface(f protocol.RequestInterface) (*protocol.Request, error) {
// 检查是否是指针 且 指向的是一个结构体
if f != nil && reflect.TypeOf(f).Kind() != reflect.Ptr || reflect.TypeOf(f).Elem().Kind() != reflect.Struct {
util.Logger.Warning("request mux: arg not a onebot request struct")
return nil, protocol.ErrorInvalidRequest
}
// 查找*request头
requestID := -1
t := reflect.TypeOf(f).Elem()
v := reflect.ValueOf(f).Elem()
for i := 0; i < t.NumField(); i++ {
if t.Field(i).Type == protocol.RequestType {
requestID = i
break
}
}
// *request不存在
if requestID == -1 {
util.Logger.Warning("request mux: arg not a onebot request struct")
return nil, protocol.ErrorInvalidRequest
}
// 获取*request
request := v.Field(requestID).Interface().(*protocol.Request)
if request == nil {
util.Logger.Warning("request mux: arg not a onebot request struct")
return nil, protocol.ErrorInvalidRequest
}
// 没有action
if request.Action == "" {
util.Logger.Warning("request mux: request action is empty")
return nil, ErrorActionEmpty
}
return request, nil
}
// AddRequestInterface 添加一个请求处理接口
//
// action: 请求的action名称
//
// f: 请求处理接口 protocol.RequestInterface 的实现
func (a *ActionMux) AddRequestInterface(f protocol.RequestInterface) error {
request, err := a.checkRequestInterface(f)
if err != nil {
return err
}
// action已存在
if _, ok := a.actionHandleFunc.Load(request.Action); ok {
util.Logger.Warning("request mux: request action already exist")
return ErrorActionExist
}
a.actionHandleFunc.Store(request.Action, f)
return nil
}
// AddRegexRequestInterface 添加一个正则匹配动作请求接口
func (a *ActionMux) AddRegexRequestInterface(actionRegex string, f protocol.RequestInterface) error {
_, err := a.checkRequestInterface(f)
if err != nil {
return err
}
re, err := regexp.Compile(actionRegex)
if err != nil {
return err
}
if _, ok := a.regexHandleFunc.Load(actionRegex); ok {
util.Logger.Warning("request mux: request action regex already exist")
return ErrorActionExist
}
newMux := new(regexActionMux)
newMux.Re = re
newMux.F = f
a.regexHandleFunc.Store(actionRegex, newMux)
return nil
}
// DeleteRequestInterface 删除一个请求处理接口
func (a *ActionMux) DeleteRequestInterface(action string) {
a.actionHandleFunc.Delete(action)
}
func (a *ActionMux) DeleteRegexRequestInterface(actionRegex string) {
a.regexHandleFunc.Delete(actionRegex)
}
// GetRequestInterface 获取一个请求处理接口
func (a *ActionMux) GetRequestInterface(action string) (f protocol.RequestInterface) {
util.Logger.Debug("mux action request: " + action)
ff, ok := a.actionHandleFunc.Load(action)
if !ok {
a.regexHandleFunc.Range(
func(key, value interface{}) bool {
if value.(*regexActionMux).Re.MatchString(action) {
ff = value.(*regexActionMux).F
ok = true
return false
}
return true
})
if !ok {
util.Logger.Warning("request mux: request action not exist")
return nil
}
}
return ff.(protocol.RequestInterface)
}