package qq_message import ( "encoding/json" "fmt" "log" "sync" ) // QQMessage 接口定义了所有 CQ 消息必须实现的方法 type QQMessage interface { ToCQString() string GetMessageType() string } // RawMessage 用于初始解析 JSON 的通用结构 type RawMessage struct { Type string `json:"type"` Data json.RawMessage `json:"data"` } // messageFactory 用于创建具体的消息实例 type messageFactory func() QQMessage var ( messageFactories = make(map[string]messageFactory) factoryMutex sync.RWMutex ) // RegisterMessageType 注册消息类型和对应的工厂函数 func RegisterMessageType(messageType string, factory messageFactory) { factoryMutex.Lock() defer factoryMutex.Unlock() messageFactories[messageType] = factory } // CreateMessage 根据类型创建具体的消息实例 func CreateMessage(messageType string) (QQMessage, error) { factoryMutex.RLock() factory, exists := messageFactories[messageType] factoryMutex.RUnlock() if !exists { return nil, fmt.Errorf("未知的消息类型: %s", messageType) } return factory(), nil } // [map[data:map[chainCount: id:267 raw:map[chainCount: doubleHit: faceBubbleCount: faceIndex:267 faceText:/头秃 faceType:2 imageType: msgType: oldVersionStr: packId: pokeFlag: pokeStrength: pokeType: randomType: resultId: sourceType: spokeSummary: stickerId: stickerType: surpriseId: vaspokeId: vaspokeMinver: vaspokeName:] resultId:] type:face]] // ParseStructMessages 解析消息数组 func ParseStructMessages(msgData any) []QQMessage { log.Println("解析消息数组:", msgData) switch msgData.(type) { case []map[string]any: msgArray := msgData.([]map[string]any) messages := make([]QQMessage, 0, len(msgArray)) for _, raw := range msgArray { msg, err := CreateMessage(raw["type"].(string)) if err != nil { log.Println("创建消息失败:", err) continue } dataByte, _ := json.Marshal(raw["data"]) // 使用类型断言获取具体类型的Data字段 if v, ok := msg.(interface{ SetData(json.RawMessage) error }); ok { if err := v.SetData(dataByte); err != nil { // return nil, fmt.Errorf("解析消息数据失败: %v", err) log.Println("解析消息数据失败:", err) continue } } else { log.Printf("消息类型 %s 未实现 SetData 方法\n", raw["type"]) continue } messages = append(messages, msg) } log.Println("解析出的QQ消息数组:", messages) return messages case string: return []QQMessage{NewTextMessage().ParseMessage(msgData.(string))} } return nil }