qq_bot/handler/handler.go

159 lines
4.4 KiB
Go

package handler
import (
"fmt"
"log"
"regexp"
"runtime/debug"
"strings"
"time"
"git.lxtend.com/qqbot/auth"
"git.lxtend.com/qqbot/constants"
"git.lxtend.com/qqbot/model"
)
var allGroupHandlers = make(map[string]model.HandlerInfo[model.Handler])
var GroupHandlers = make(map[int64]map[string]model.HandlerInfo[model.Handler])
var frontMatchHandlers = make(map[string]model.HandlerInfo[model.Handler])
var regexHandlers = make(map[string]model.HandlerInfo[model.Handler])
var liveHandlers = make(map[int64]map[int64]model.TryCatchHandler)
var livePrivateHandlers = make(map[int64]model.TryCatchHandler)
var HelpInforms = make(map[string][]model.HelpInform)
var privateAllHandler model.Handler
func RegisterPrivateHandler(handler model.Handler) {
privateAllHandler = handler
}
func RegisterHandler(trigger string, handler model.Handler, level constants.PermissionLevel) {
allGroupHandlers[trigger] = model.HandlerInfo[model.Handler]{
Trigger: trigger,
Handler: handler,
Level: level,
}
}
func RegisterFrontMatchHandler(trigger string, handler model.Handler, level constants.PermissionLevel) {
frontMatchHandlers[trigger] = model.HandlerInfo[model.Handler]{
Trigger: trigger,
Handler: handler,
Level: level,
}
}
func RegisterLiveHandler(groupID int64, userID int64, handler model.TryCatchHandler) { //userID=-1 means for all users in groupID
if groupID == 0 {
livePrivateHandlers[userID] = handler
return
}
if _, ok := liveHandlers[groupID]; !ok {
liveHandlers[groupID] = make(map[int64]model.TryCatchHandler)
}
liveHandlers[groupID][userID] = handler
}
func UnRegisterLiveHandler(groupID int64, userID int64) {
if groupID == 0 {
delete(livePrivateHandlers, userID)
return
}
if _, ok := liveHandlers[groupID]; ok {
delete(liveHandlers[groupID], userID)
}
}
func RegisterGroupHandler(groupID int64, trigger string, handler model.Handler, level constants.PermissionLevel) {
if _, ok := GroupHandlers[groupID]; !ok {
GroupHandlers[groupID] = make(map[string]model.HandlerInfo[model.Handler])
}
GroupHandlers[groupID][trigger] = model.HandlerInfo[model.Handler]{
Trigger: trigger,
Handler: handler,
Level: level,
}
}
func UnRegisterGroupHandler(groupID int64, trigger string) {
if _, ok := GroupHandlers[groupID]; ok {
delete(GroupHandlers[groupID], trigger)
}
}
func RegisterRegexHandler(trigger string, handler model.Handler, level constants.PermissionLevel) {
regexHandlers[trigger] = model.HandlerInfo[model.Handler]{
Trigger: trigger,
Handler: handler,
Level: level,
}
}
func MsgInHandler(msg model.Message) (reply *model.Reply) {
defer func() {
if r := recover(); r != nil {
stack := debug.Stack()
errMsg := fmt.Sprintf("[%s] Panic recovered:\nError: %v\nStack Trace:\n%s\n",
time.Now().Format("2006-01-02 15:04:05"), r, stack)
log.Print(errMsg)
}
}()
if msg.RawMsg != "" {
log.Default().Printf("\033[31m↓\033[0m:%v", msg)
} else {
return nil
}
defer func() {
if reply != nil {
log.Default().Printf("\033[32m↑\033[0m:%v", reply)
}
}()
if handlerUserID, ok := liveHandlers[msg.GroupInfo.GroupId]; ok {
if handler, ok := handlerUserID[msg.UserId]; ok {
reply, catched := handler(msg)
if catched {
return reply
}
}
}
if handler, ok := livePrivateHandlers[msg.UserId]; ok {
reply, catched := handler(msg)
if catched {
return reply
}
}
for trigger, handler := range frontMatchHandlers {
if strings.HasPrefix(msg.RawMsg, trigger) {
return auth.TryExecHandler(msg, handler.Level, handler.Handler)
}
}
msgArray := strings.Split(msg.RawMsg, " ")
if handler, ok := allGroupHandlers[msgArray[0]]; ok {
return auth.TryExecHandler(msg, handler.Level, handler.Handler)
}
if groupHandler, ok := GroupHandlers[msg.GroupInfo.GroupId]; ok {
if handler, ok := groupHandler[msgArray[0]]; ok {
return auth.TryExecHandler(msg, handler.Level, handler.Handler)
}
}
for trigger, handler := range regexHandlers {
exp := regexp.MustCompile(trigger)
if exp.MatchString(msg.RawMsg) {
return auth.TryExecHandler(msg, handler.Level, handler.Handler)
}
}
if !msg.GroupInfo.IsGroupMsg && privateAllHandler != nil {
return privateAllHandler(msg)
}
return nil
}
func RegisterHelpInform(triggerName string, category string, inform string) {
if _, ok := HelpInforms[category]; !ok {
HelpInforms[category] = []model.HelpInform{}
}
HelpInforms[category] = append(HelpInforms[category], model.HelpInform{
Trigger: triggerName,
Inform: inform,
})
}