feat: 添加结构化消息json解析逻辑,补充对应的异常捕获

This commit is contained in:
2025-06-16 10:49:26 +08:00
parent a7fa591943
commit 6767077867
36 changed files with 248 additions and 153 deletions

View File

@@ -8,8 +8,8 @@ import (
"sync"
"time"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"github.com/gorilla/websocket"
)
@@ -39,9 +39,9 @@ func (am *actionManager) SendMsg(reply *model.Reply) error {
am.sendMtx.Lock()
defer am.sendMtx.Unlock()
if reply.ReferOriginMsg {
replyMsg := message.ReplyMessage{
replyMsg := qq_message.ReplyMessage{
Type: "reply",
Data: message.ReplyMessageData{
Data: qq_message.ReplyMessageData{
ID: int(reply.FromMsg.OriginMsgId),
},
}

View File

@@ -8,8 +8,8 @@ import (
"git.lxtend.com/lixiangwuxian/qqbot/auth"
"git.lxtend.com/lixiangwuxian/qqbot/constants"
"git.lxtend.com/lixiangwuxian/qqbot/handler"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
)
func init() {
@@ -37,7 +37,7 @@ func setUserLevel(msg model.Message) (reply *model.Reply) {
}
}
userText := tokens[1]
atMsg := message.AtMessage{}
atMsg := qq_message.AtMessage{}
if err := atMsg.ParseMessage(userText); err == nil {
userText = atMsg.Data.QQ
}

View File

@@ -10,8 +10,8 @@ import (
"git.lxtend.com/lixiangwuxian/qqbot/action"
"git.lxtend.com/lixiangwuxian/qqbot/constants"
"git.lxtend.com/lixiangwuxian/qqbot/handler"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"git.lxtend.com/lixiangwuxian/qqbot/service/beatleader"
"git.lxtend.com/lixiangwuxian/qqbot/service/scoresaber"
"git.lxtend.com/lixiangwuxian/qqbot/util"
@@ -219,9 +219,9 @@ func getMyBLPic(msg model.Message) (reply *model.Reply) {
resultStr = data.LastDiffToImage(*data, onlyFirstFrame)
}
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: resultStr,
},
}
@@ -305,15 +305,15 @@ func getMyRecentScore(msg model.Message) (reply *model.Reply) {
}
wg.Wait()
for _, record := range records {
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: coverImageMap[record.SongHash],
},
}
textMsg := message.TextMessage{
textMsg := qq_message.TextMessage{
Type: "text",
Data: message.TextMessageData{
Data: qq_message.TextMessageData{
Text: record.ToString(),
},
}
@@ -332,9 +332,9 @@ func getMyRecentScore(msg model.Message) (reply *model.Reply) {
if len(records) > 5 {
nodeMsg := util.NewSelfNodeMessage(append(
[]any{
&message.TextMessage{
&qq_message.TextMessage{
Type: "text",
Data: message.TextMessageData{
Data: qq_message.TextMessageData{
Text: "玩家 " + userName + " 的" + strconv.Itoa(recordCount) + "条最近记录为:\n",
},
},
@@ -353,9 +353,9 @@ func getMyRecentScore(msg model.Message) (reply *model.Reply) {
return &model.Reply{
ReplyMsg: append(
[]any{
message.TextMessage{
qq_message.TextMessage{
Type: "text",
Data: message.TextMessageData{
Data: qq_message.TextMessageData{
Text: "玩家 " + userName + " 的" + strconv.Itoa(recordCount) + "条最近记录为:\n",
},
},
@@ -368,9 +368,9 @@ func getMyRecentScore(msg model.Message) (reply *model.Reply) {
}
func screenShotBL(msg model.Message) (reply *model.Reply) {
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: "file:///tmp/qqbot/" + beatleader.GetBLPicture(strconv.Itoa(int(msg.UserId))),
},
}

View File

@@ -4,8 +4,8 @@ import (
"git.lxtend.com/lixiangwuxian/qqbot/action"
"git.lxtend.com/lixiangwuxian/qqbot/constants"
"git.lxtend.com/lixiangwuxian/qqbot/handler"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
)
func init() {
@@ -14,7 +14,7 @@ func init() {
}
func drawback(msg model.Message) *model.Reply {
msgIdToDrawback := message.ReplyMessage{}
msgIdToDrawback := qq_message.ReplyMessage{}
if err := msgIdToDrawback.ParseMessage(msg.RawMsg); err != nil {
return &model.Reply{
ReplyMsg: "",

View File

@@ -1,8 +1,8 @@
package getweb
import (
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"git.lxtend.com/lixiangwuxian/qqbot/util"
)
@@ -25,9 +25,9 @@ func getweb(msg model.Message) (reply *model.Reply) {
FromMsg: msg,
}
}
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: "file:///tmp/qqbot/getweb/url.png",
},
}

View File

@@ -1,18 +1,14 @@
package handler
import (
"fmt"
"log"
"regexp"
"runtime/debug"
"strings"
"time"
"git.lxtend.com/lixiangwuxian/qqbot/action"
"git.lxtend.com/lixiangwuxian/qqbot/auth"
"git.lxtend.com/lixiangwuxian/qqbot/config"
"git.lxtend.com/lixiangwuxian/qqbot/constants"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/util"
)
var allGroupHandlers = make(map[string]model.HandlerInfo[model.Handler])
@@ -91,23 +87,7 @@ func RegisterRegexHandler(trigger string, handler model.Handler, level constants
}
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)
action.ActionManager.SendMsg(&model.Reply{
ReplyMsg: "出现了Panic:\n" + errMsg,
ReferOriginMsg: false,
FromMsg: model.Message{
GroupInfo: model.GroupInfo{
GroupId: config.ConfigManager.GetConfig().Management.ReportGroup,
},
},
})
}
}()
defer util.ReportPanicToDev()
if msg.RawMsg != "" {
log.Default().Printf("\033[31m↓\033[0m:%v", msg)
} else {

View File

@@ -7,8 +7,8 @@ import (
"git.lxtend.com/lixiangwuxian/qqbot/action"
"git.lxtend.com/lixiangwuxian/qqbot/constants"
"git.lxtend.com/lixiangwuxian/qqbot/handler"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"git.lxtend.com/lixiangwuxian/qqbot/util"
)
@@ -32,9 +32,9 @@ func help(msg model.Message) *model.Reply {
helpInfo += "\n" + v.Trigger + " : " + v.Inform
}
}
textMsg := message.NewTextMessage()
textMsg := qq_message.NewTextMessage()
textMsg.Data.Text = helpInfo
nodeMsg := message.NewNodeMessage()
nodeMsg := qq_message.NewNodeMessage()
loginAccountInfo, err := action.GetLoginAccountInfo()
if err != nil {
log.Println("GetLoginAccountInfo error:", err)

View File

@@ -13,8 +13,8 @@ import (
"git.lxtend.com/lixiangwuxian/qqbot/config"
"git.lxtend.com/lixiangwuxian/qqbot/constants"
"git.lxtend.com/lixiangwuxian/qqbot/handler"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
)
func init() {
@@ -106,7 +106,7 @@ func sendAlertMessage(alertMsgs []string) {
return
}
nodes := []message.NodeMessage{}
nodes := []qq_message.NodeMessage{}
selfInfo, err := action.GetLoginAccountInfo()
if err != nil {
log.Println("获取登录账号信息失败:", err)
@@ -115,8 +115,8 @@ func sendAlertMessage(alertMsgs []string) {
userId := strconv.FormatInt(int64(selfInfo.Data.UserID), 10)
nickname := selfInfo.Data.Nickname
for _, alertMsg := range alertMsgs {
textMsg := message.NewTextMessage().ParseMessage(alertMsg)
nodes = append(nodes, *message.NewNodeMessage().ParseMessage(userId, nickname, []any{textMsg}))
textMsg := qq_message.NewTextMessage().ParseMessage(alertMsg)
nodes = append(nodes, *qq_message.NewNodeMessage().ParseMessage(userId, nickname, []any{textMsg}))
}
action.ActionManager.SendForward(&model.Reply{
@@ -143,7 +143,7 @@ func RaidHandler(msg model.Message) (reply *model.Reply) {
}
}
nodes := []message.NodeMessage{}
nodes := []qq_message.NodeMessage{}
selfInfo, err := action.GetLoginAccountInfo()
if err != nil {
log.Println("获取登录账号信息失败:", err)
@@ -151,10 +151,10 @@ func RaidHandler(msg model.Message) (reply *model.Reply) {
}
userId := strconv.FormatInt(int64(selfInfo.Data.UserID), 10)
nickname := selfInfo.Data.Nickname
nodes = append(nodes, *message.NewNodeMessage().ParseMessage(userId, nickname, []any{message.NewTextMessage().ParseMessage("阵列信息:")}))
nodes = append(nodes, *qq_message.NewNodeMessage().ParseMessage(userId, nickname, []any{qq_message.NewTextMessage().ParseMessage("阵列信息:")}))
for _, diskInfo := range diskInfoList {
textMsg := message.NewTextMessage().ParseMessage(diskInfo.String())
nodes = append(nodes, *message.NewNodeMessage().ParseMessage(userId, nickname, []any{textMsg}))
textMsg := qq_message.NewTextMessage().ParseMessage(diskInfo.String())
nodes = append(nodes, *qq_message.NewNodeMessage().ParseMessage(userId, nickname, []any{textMsg}))
}
action.ActionManager.SendForward(&model.Reply{

View File

@@ -10,8 +10,8 @@ import (
"git.lxtend.com/lixiangwuxian/qqbot/action"
"git.lxtend.com/lixiangwuxian/qqbot/constants"
"git.lxtend.com/lixiangwuxian/qqbot/handler"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"git.lxtend.com/lixiangwuxian/qqbot/service/scoresaber"
"git.lxtend.com/lixiangwuxian/qqbot/util"
)
@@ -53,9 +53,9 @@ func getBS50(msg model.Message) (reply *model.Reply) {
FromMsg: msg,
}
}
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: util.GenTempFilePath("bs50.png"),
},
}
@@ -246,9 +246,9 @@ func getMySSPic(msg model.Message) (reply *model.Reply) {
resultStr = data.LastDiffToImage(*data, onlyFirstFrame)
}
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: resultStr,
},
}
@@ -332,15 +332,15 @@ func getMyRecentScore(msg model.Message) (reply *model.Reply) {
}
wg.Wait()
for _, record := range records {
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: coverImageMap[record.SongHash],
},
}
textMsg := message.TextMessage{
textMsg := qq_message.TextMessage{
Type: "text",
Data: message.TextMessageData{
Data: qq_message.TextMessageData{
Text: record.ToString(),
},
}
@@ -359,9 +359,9 @@ func getMyRecentScore(msg model.Message) (reply *model.Reply) {
if len(records) > 5 {
nodeMsg := util.NewSelfNodeMessage(append(
[]any{
&message.TextMessage{
&qq_message.TextMessage{
Type: "text",
Data: message.TextMessageData{
Data: qq_message.TextMessageData{
Text: "玩家 " + userName + " 的" + strconv.Itoa(recordCount) + "条最近记录为:\n",
},
},
@@ -380,9 +380,9 @@ func getMyRecentScore(msg model.Message) (reply *model.Reply) {
return &model.Reply{
ReplyMsg: append(
[]any{
message.TextMessage{
qq_message.TextMessage{
Type: "text",
Data: message.TextMessageData{
Data: qq_message.TextMessageData{
Text: "玩家 " + userName + " 的" + strconv.Itoa(recordCount) + "条最近记录为:",
},
},

View File

@@ -6,8 +6,8 @@ import (
"git.lxtend.com/lixiangwuxian/qqbot/constants"
"git.lxtend.com/lixiangwuxian/qqbot/handler"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"git.lxtend.com/lixiangwuxian/qqbot/service/xibao"
"git.lxtend.com/lixiangwuxian/qqbot/util"
"github.com/google/uuid"
@@ -34,9 +34,9 @@ func xiBao(msg model.Message) (reply *model.Reply) {
}
}
xibao.GenerateCongratulationImageNew(tokens[1], "./resource/xibao_background.png", filePath, true)
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: "file://" + filePath,
},
}
@@ -52,9 +52,9 @@ func xiBaoTemp(msg model.Message) (reply *model.Reply, isTrigger bool) {
fileName := uuid.New().String()
filePath := util.GenTempFilePath(fmt.Sprintf("%s.png", fileName))
xibao.GenerateCongratulationImageNew(msg.RawMsg, "./resource/xibao_background.png", filePath, true)
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: "file://" + filePath,
},
}
@@ -79,9 +79,9 @@ func beiBao(msg model.Message) (reply *model.Reply) {
}
}
xibao.GenerateCongratulationImageNew(tokens[1], "./resource/beibao_background.png", filePath, false)
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: "file://" + filePath,
},
}
@@ -97,9 +97,9 @@ func beiBaoTemp(msg model.Message) (reply *model.Reply, isTrigger bool) {
fileName := uuid.New().String()
filePath := util.GenTempFilePath(fmt.Sprintf("%s.png", fileName))
xibao.GenerateCongratulationImageNew(msg.RawMsg, "./resource/beibao_background.png", filePath, false)
imageMsg := message.ImageMessage{
imageMsg := qq_message.ImageMessage{
Type: "image",
Data: message.ImageMessageData{
Data: qq_message.ImageMessageData{
File: "file://" + filePath,
},
}

View File

@@ -1,10 +1,13 @@
package model
import "git.lxtend.com/lixiangwuxian/qqbot/qq_message"
type Message struct {
UserId int64 `json:"userId"`
GroupInfo GroupInfo `json:"groupInfo"`
OriginMsgId int32 `json:"originMsgId"`
RawMsg string `json:"msg"`
StructuredMsg []qq_message.QQMessage `json:"structuredMsg"`
UserNickName string `json:"userNickName"`
}

View File

@@ -71,7 +71,7 @@ type EventMessage struct {
SubType string `json:"sub_type"`
MessageID int32 `json:"message_id"`
UserID int64 `json:"user_id"`
// Message string `json:"message"` //just ignore it
Message string `json:"message"` //just ignore it
RawMessage string `json:"raw_message"`
Font int32 `json:"font"`
Sender Sender `json:"sender"`

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -17,7 +17,7 @@ type AtMessageData struct {
}
func init() {
RegisterMessageType(TypeAt, func() CQMessage {
RegisterMessageType(TypeAt, func() QQMessage {
return NewAtMessage()
})
}
@@ -26,6 +26,10 @@ func NewAtMessage() *AtMessage {
return &AtMessage{Type: TypeAt}
}
func (msg *AtMessage) GetMessageType() string {
return TypeAt
}
func (msg *AtMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
// 消息类型常量定义
const (

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -18,7 +18,7 @@ type ContactMessageData struct {
}
func init() {
RegisterMessageType(TypeContact, func() CQMessage {
RegisterMessageType(TypeContact, func() QQMessage {
return NewContactMessage()
})
}
@@ -27,6 +27,10 @@ func NewContactMessage() *ContactMessage {
return &ContactMessage{Type: TypeContact}
}
func (msg *ContactMessage) GetMessageType() string {
return TypeContact
}
func (msg *ContactMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,15 +1,16 @@
package message
package qq_message
import (
"encoding/json"
"fmt"
"log"
"sync"
)
// CQMessage 接口定义了所有 CQ 消息必须实现的方法
type CQMessage interface {
// QQMessage 接口定义了所有 CQ 消息必须实现的方法
type QQMessage interface {
ToCQString() string
// ParseMessage(data string) error
GetMessageType() string
}
// RawMessage 用于初始解析 JSON 的通用结构
@@ -19,7 +20,7 @@ type RawMessage struct {
}
// messageFactory 用于创建具体的消息实例
type messageFactory func() CQMessage
type messageFactory func() QQMessage
var (
messageFactories = make(map[string]messageFactory)
@@ -34,7 +35,7 @@ func RegisterMessageType(messageType string, factory messageFactory) {
}
// CreateMessage 根据类型创建具体的消息实例
func CreateMessage(messageType string) (CQMessage, error) {
func CreateMessage(messageType string) (QQMessage, error) {
factoryMutex.RLock()
factory, exists := messageFactories[messageType]
factoryMutex.RUnlock()
@@ -47,26 +48,30 @@ func CreateMessage(messageType string) (CQMessage, error) {
}
// ParseCQMessages 解析消息数组
func ParseCQMessages(jsonData []byte) ([]CQMessage, error) {
func ParseCQMessages(jsonData []byte) ([]QQMessage, error) {
var rawMessages []RawMessage
if err := json.Unmarshal(jsonData, &rawMessages); err != nil {
return nil, fmt.Errorf("解析 JSON 数组失败: %v", err)
}
messages := make([]CQMessage, 0, len(rawMessages))
messages := make([]QQMessage, 0, len(rawMessages))
for _, raw := range rawMessages {
msg, err := CreateMessage(raw.Type)
if err != nil {
return nil, err
log.Println("创建消息失败:", err)
continue
}
// 使用类型断言获取具体类型的Data字段
if v, ok := msg.(interface{ SetData(json.RawMessage) error }); ok {
if err := v.SetData(raw.Data); err != nil {
return nil, fmt.Errorf("解析消息数据失败: %v", err)
// return nil, fmt.Errorf("解析消息数据失败: %v", err)
log.Println("解析消息数据失败:", err)
continue
}
} else {
return nil, fmt.Errorf("消息类型 %s 未实现 SetData 方法", raw.Type)
log.Printf("消息类型 %s 未实现 SetData 方法\n", raw.Type)
continue
}
messages = append(messages, msg)

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -17,7 +17,7 @@ type FaceMessageData struct {
}
func init() {
RegisterMessageType(TypeFace, func() CQMessage {
RegisterMessageType(TypeFace, func() QQMessage {
return NewFaceMessage()
})
}
@@ -26,6 +26,10 @@ func NewFaceMessage() *FaceMessage {
return &FaceMessage{Type: TypeFace}
}
func (msg *FaceMessage) GetMessageType() string {
return TypeFace
}
func (msg *FaceMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -23,7 +23,7 @@ type FileMessageData struct {
}
func init() {
RegisterMessageType(TypeFile, func() CQMessage {
RegisterMessageType(TypeFile, func() QQMessage {
return NewFileMessage()
})
}
@@ -32,6 +32,10 @@ func NewFileMessage() *FileMessage {
return &FileMessage{Type: TypeFile}
}
func (msg *FileMessage) GetMessageType() string {
return TypeFile
}
func (msg *FileMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -31,10 +31,10 @@ type NodeMessageData struct {
}
func init() {
RegisterMessageType(TypeForward, func() CQMessage {
RegisterMessageType(TypeForward, func() QQMessage {
return NewForwardMessage()
})
RegisterMessageType(TypeNode, func() CQMessage {
RegisterMessageType(TypeNode, func() QQMessage {
return NewNodeMessage()
})
}
@@ -43,6 +43,10 @@ func NewForwardMessage() *ForwardMessage {
return &ForwardMessage{Type: TypeForward}
}
func (msg *ForwardMessage) GetMessageType() string {
return TypeForward
}
// ForwardMessage methods
func (msg *ForwardMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
@@ -52,6 +56,10 @@ func NewNodeMessage() *NodeMessage {
return &NodeMessage{Type: TypeNode}
}
func (msg *NodeMessage) GetMessageType() string {
return TypeNode
}
func (msg *ForwardMessage) ToCQString() string {
return fmt.Sprintf("[CQ:forward,id=%s]", msg.Data.ID)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -27,7 +27,7 @@ type ImageMessageData struct {
}
func init() {
RegisterMessageType(TypeImage, func() CQMessage {
RegisterMessageType(TypeImage, func() QQMessage {
return NewImageMessage()
})
}
@@ -39,6 +39,10 @@ func NewImageMessage() *ImageMessage {
}
}
func (msg *ImageMessage) GetMessageType() string {
return TypeImage
}
func (msg *ImageMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -17,7 +17,7 @@ type JsonMessageData struct {
}
func init() {
RegisterMessageType(TypeJson, func() CQMessage {
RegisterMessageType(TypeJson, func() QQMessage {
return NewJsonMessage()
})
}
@@ -26,6 +26,10 @@ func NewJsonMessage() *JsonMessage {
return &JsonMessage{Type: TypeJson}
}
func (msg *JsonMessage) GetMessageType() string {
return TypeJson
}
func (msg *JsonMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -17,7 +17,7 @@ type LightappMessageData struct {
}
func init() {
RegisterMessageType(TypeLightapp, func() CQMessage {
RegisterMessageType(TypeLightapp, func() QQMessage {
return NewLightappMessage()
})
}
@@ -26,6 +26,10 @@ func NewLightappMessage() *LightappMessage {
return &LightappMessage{Type: TypeLightapp}
}
func (msg *LightappMessage) GetMessageType() string {
return TypeLightapp
}
func (msg *LightappMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -20,7 +20,7 @@ type LocationMessageData struct {
}
func init() {
RegisterMessageType(TypeLocation, func() CQMessage {
RegisterMessageType(TypeLocation, func() QQMessage {
return NewLocationMessage()
})
}
@@ -29,6 +29,10 @@ func NewLocationMessage() *LocationMessage {
return &LocationMessage{Type: TypeLocation}
}
func (msg *LocationMessage) GetMessageType() string {
return TypeLocation
}
func (msg *LocationMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -20,7 +20,7 @@ type MfaceMessageData struct {
}
func init() {
RegisterMessageType(TypeMface, func() CQMessage {
RegisterMessageType(TypeMface, func() QQMessage {
return NewMfaceMessage()
})
}
@@ -29,6 +29,10 @@ func NewMfaceMessage() *MfaceMessage {
return &MfaceMessage{Type: TypeMface}
}
func (msg *MfaceMessage) GetMessageType() string {
return TypeMface
}
func (msg *MfaceMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -23,7 +23,7 @@ type MusicMessageData struct {
}
func init() {
RegisterMessageType(TypeMusic, func() CQMessage {
RegisterMessageType(TypeMusic, func() QQMessage {
return NewMusicMessage()
})
}
@@ -32,6 +32,10 @@ func NewMusicMessage() *MusicMessage {
return &MusicMessage{Type: TypeMusic}
}
func (msg *MusicMessage) GetMessageType() string {
return TypeMusic
}
func (msg *MusicMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -23,7 +23,7 @@ type RecordMessageData struct {
}
func init() {
RegisterMessageType(TypeRecord, func() CQMessage {
RegisterMessageType(TypeRecord, func() QQMessage {
return NewRecordMessage()
})
}
@@ -32,6 +32,10 @@ func NewRecordMessage() *RecordMessage {
return &RecordMessage{Type: TypeRecord}
}
func (msg *RecordMessage) GetMessageType() string {
return TypeRecord
}
func (msg *RecordMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -17,7 +17,7 @@ type ReplyMessageData struct {
}
func init() {
RegisterMessageType(TypeReply, func() CQMessage {
RegisterMessageType(TypeReply, func() QQMessage {
return NewReplyMessage()
})
}
@@ -26,6 +26,10 @@ func NewReplyMessage() *ReplyMessage {
return &ReplyMessage{Type: TypeReply}
}
func (msg *ReplyMessage) GetMessageType() string {
return TypeReply
}
func (msg *ReplyMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -20,7 +20,7 @@ type ShareMessageData struct {
}
func init() {
RegisterMessageType(TypeShare, func() CQMessage {
RegisterMessageType(TypeShare, func() QQMessage {
return NewShareMessage()
})
}
@@ -29,6 +29,10 @@ func NewShareMessage() *ShareMessage {
return &ShareMessage{Type: TypeShare}
}
func (msg *ShareMessage) GetMessageType() string {
return TypeShare
}
func (msg *ShareMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -15,7 +15,7 @@ type TextMessageData struct {
}
func init() {
RegisterMessageType(TypeText, func() CQMessage {
RegisterMessageType(TypeText, func() QQMessage {
return NewTextMessage()
})
}
@@ -24,6 +24,10 @@ func NewTextMessage() *TextMessage {
return &TextMessage{Type: TypeText}
}
func (msg *TextMessage) GetMessageType() string {
return TypeText
}
func (msg *TextMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -1,4 +1,4 @@
package message
package qq_message
import (
"encoding/json"
@@ -24,7 +24,7 @@ type VideoMessageData struct {
}
func init() {
RegisterMessageType(TypeVideo, func() CQMessage {
RegisterMessageType(TypeVideo, func() QQMessage {
return NewVideoMessage()
})
}
@@ -33,6 +33,10 @@ func NewVideoMessage() *VideoMessage {
return &VideoMessage{Type: TypeVideo}
}
func (msg *VideoMessage) GetMessageType() string {
return TypeVideo
}
func (msg *VideoMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}

View File

@@ -12,7 +12,7 @@ import (
"git.lxtend.com/lixiangwuxian/imagedd/sprite"
"git.lxtend.com/lixiangwuxian/imagedd/text2img"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"git.lxtend.com/lixiangwuxian/qqbot/util"
)
@@ -443,9 +443,9 @@ func (p PlayerDataLite) LastDiffToString(lastQueryData PlayerDataLite) string {
if err != nil {
log.Default().Printf("缩放头像失败url:%s,err:%v", p.Avatar, err)
}
picMsg := message.ImageMessage{
Type: message.TypeImage,
Data: message.ImageMessageData{
picMsg := qq_message.ImageMessage{
Type: qq_message.TypeImage,
Data: qq_message.ImageMessageData{
File: outFile,
},
}

View File

@@ -12,7 +12,7 @@ import (
"git.lxtend.com/lixiangwuxian/imagedd/sprite"
"git.lxtend.com/lixiangwuxian/imagedd/text2img"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"git.lxtend.com/lixiangwuxian/qqbot/util"
)
@@ -239,9 +239,9 @@ func (p PlayerData) ToString() string {
if err != nil {
log.Default().Printf("缩放头像失败url:%s,err:%v", p.ProfilePicture, err)
}
picMsg := message.ImageMessage{
Type: message.TypeImage,
Data: message.ImageMessageData{
picMsg := qq_message.ImageMessage{
Type: qq_message.TypeImage,
Data: qq_message.ImageMessageData{
File: outFile,
},
}
@@ -296,9 +296,9 @@ func (p PlayerData) LastDiffToString(lastDayQueryData PlayerDataLite) string {
if err != nil {
log.Default().Printf("缩放头像失败url:%s,err:%v", p.ProfilePicture, err)
}
picMsg := message.ImageMessage{
Type: message.TypeImage,
Data: message.ImageMessageData{
picMsg := qq_message.ImageMessage{
Type: qq_message.TypeImage,
Data: qq_message.ImageMessageData{
File: outFile,
},
}

View File

@@ -9,7 +9,7 @@ import (
"git.lxtend.com/lixiangwuxian/imagedd/sprite"
"git.lxtend.com/lixiangwuxian/imagedd/text2img"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"git.lxtend.com/lixiangwuxian/qqbot/util"
"github.com/fogleman/gg"
"golang.org/x/image/font/opentype"
@@ -189,7 +189,7 @@ func GenerateCongratulationImageNew(text string, inputFile, outputFile string, i
}
func isImageCQ(text string) (string, bool) {
imgMsg := message.ImageMessage{}
imgMsg := qq_message.ImageMessage{}
if err := imgMsg.ParseMessage(text); err == nil {
return imgMsg.Data.URL, true
}

View File

@@ -5,10 +5,10 @@ import (
"strconv"
"git.lxtend.com/lixiangwuxian/qqbot/action"
"git.lxtend.com/lixiangwuxian/qqbot/message"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
)
func NewSelfNodeMessage(content ...any) *message.NodeMessage {
func NewSelfNodeMessage(content ...any) *qq_message.NodeMessage {
loginAccountInfo, err := action.GetLoginAccountInfo()
if err != nil {
log.Println("GetLoginAccountInfo error:", err)
@@ -17,5 +17,5 @@ func NewSelfNodeMessage(content ...any) *message.NodeMessage {
if loginAccountInfo == nil {
return nil
}
return &message.NodeMessage{Type: message.TypeNode, Data: message.NodeMessageData{UserID: strconv.FormatInt(int64(loginAccountInfo.Data.UserID), 10), Nickname: loginAccountInfo.Data.Nickname, Content: content}}
return &qq_message.NodeMessage{Type: qq_message.TypeNode, Data: qq_message.NodeMessageData{UserID: strconv.FormatInt(int64(loginAccountInfo.Data.UserID), 10), Nickname: loginAccountInfo.Data.Nickname, Content: content}}
}

30
util/panic_report.go Normal file
View File

@@ -0,0 +1,30 @@
package util
import (
"fmt"
"log"
"runtime/debug"
"time"
"git.lxtend.com/lixiangwuxian/qqbot/action"
"git.lxtend.com/lixiangwuxian/qqbot/config"
"git.lxtend.com/lixiangwuxian/qqbot/model"
)
func ReportPanicToDev() {
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)
action.ActionManager.SendMsg(&model.Reply{
ReplyMsg: "出现了Panic:\n" + errMsg,
ReferOriginMsg: false,
FromMsg: model.Message{
GroupInfo: model.GroupInfo{
GroupId: config.ConfigManager.GetConfig().Management.ReportGroup,
},
},
})
}
}

View File

@@ -13,6 +13,8 @@ import (
"git.lxtend.com/lixiangwuxian/qqbot/constants"
"git.lxtend.com/lixiangwuxian/qqbot/handler"
"git.lxtend.com/lixiangwuxian/qqbot/model"
"git.lxtend.com/lixiangwuxian/qqbot/qq_message"
"git.lxtend.com/lixiangwuxian/qqbot/util"
"github.com/gorilla/websocket"
)
@@ -58,6 +60,7 @@ func NewWebSocketClient(scheme, host, path string) (*WebSocketClient, error) {
func (c *WebSocketClient) receiveMessages() {
defer close(c.Done)
defer util.ReportPanicToDev()
for !c.closed {
_, message, err := c.conn.ReadMessage()
if err != nil {
@@ -69,10 +72,16 @@ func (c *WebSocketClient) receiveMessages() {
log.Println("Error unmarshalling message:", err)
return
}
structuredMsg, err := qq_message.ParseCQMessages([]byte(event.RawMessage))
if err != nil {
log.Println("Error parsing message:", err)
return
}
msg := model.Message{
UserId: event.UserID,
OriginMsgId: event.MessageID,
RawMsg: event.RawMessage,
StructuredMsg: structuredMsg,
UserNickName: event.Sender.Nickname,
}