/
cqcode.go
90 lines (81 loc) · 2.21 KB
/
cqcode.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
// Package message
// @Description: 用于message转换和封装的一个包
package message
import (
"reflect"
"unsafe"
"github.com/tidwall/gjson"
)
// Modified from https://github.com/catsworld/qq-bot-api
// ParseMessage parses msg, which might have 2 types, string or array,
// depending on the configuration of cqhttp, to a Message.
// msg is the value of key "message" of the data unmarshalled from the
// API response JSON.
func ParseMessage(msg []byte) Message {
x := gjson.Parse(BytesToString(msg))
if x.IsArray() {
return ParseMessageFromArray(x)
} else {
return ParseMessageFromString(x.String())
}
}
// ParseMessageFromArray parses msg as type array to a Message.
// msg is the value of key "message" of the data unmarshalled from the
// API response JSON.
// ParseMessageFromArray cq字符串转化为json对象
func ParseMessageFromArray(msgs gjson.Result) Message {
message := Message{}
parse2map := func(val gjson.Result) map[string]string {
m := map[string]string{}
val.ForEach(func(key, value gjson.Result) bool {
m[key.String()] = value.String()
return true
})
return m
}
msgs.ForEach(func(_, item gjson.Result) bool {
message = append(message, MessageSegment{
Type: item.Get("type").String(),
Data: parse2map(item.Get("data")),
})
return true
})
return message
}
// CQString returns the CQEncoded string. All media in the message will be converted
// to its CQCode.
// CQString 解码cq字符串
func (m Message) CQString() string {
str := ""
for _, media := range m {
if media.Type != "text" {
str += media.CQCode()
} else {
str += EscapeCQText(media.Data["text"])
}
}
return str
}
// ExtractPlainText 提取消息中的纯文本
func (m Message) ExtractPlainText() string {
msg := ""
for _, val := range m {
if val.Type == "text" {
msg += val.Data["text"]
}
}
return msg
}
// BytesToString 没有内存开销的转换
func BytesToString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
// StringToBytes 没有内存开销的转换
func StringToBytes(s string) (b []byte) {
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sh := *(*reflect.StringHeader)(unsafe.Pointer(&s)) // nolint
bh.Data = sh.Data
bh.Len = sh.Len
bh.Cap = sh.Len
return b
}