Skip to content

Commit 8c2b1f9

Browse files
committed
raw message
1 parent 2fd6d57 commit 8c2b1f9

File tree

4 files changed

+128
-27
lines changed

4 files changed

+128
-27
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,7 @@ src/main/java/dto/
4141

4242

4343
### Mac ###
44-
.DS_Store
44+
.DS_Store
45+
46+
47+
device/

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ plugins {
2828
}
2929

3030
group = "net.lz1998"
31-
version = "0.0.10"
31+
version = "0.0.11"
3232
java.sourceCompatibility = JavaVersion.VERSION_1_8
3333

3434
configurations {

src/main/kotlin/net/lz1998/mirai/utils/ApiHandler.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ import net.mamoe.mirai.message.data.asMessageChain
1616

1717
suspend fun handleSendPrivateMsg(bot: Bot, req: BSendPrivateMsgReq): BSendPrivateMsgResp? {
1818
val contact = bot.getFriendOrNull(req.userId) ?: return null
19-
val messageChain = req.messageList.map { it.toMiraiMessage(bot, contact) }.asMessageChain()
19+
val messageChain = protoMessageToMiraiMessage(req.messageList, bot, contact, req.autoEscape).asMessageChain()
2020
val messageSource = contact.sendMessage(messageChain).source
2121
bot.messageSourceLru.put(messageSource.id, messageSource)
2222
return BSendPrivateMsgResp.newBuilder().setMessageId(messageSource.id).build()
2323
}
2424

2525
suspend fun handleSendGroupMsg(bot: Bot, req: BSendGroupMsgReq): BSendGroupMsgResp? {
2626
val contact = bot.getGroupOrNull(req.groupId) ?: return null
27-
val messageChain = req.messageList.map { it.toMiraiMessage(bot, contact) }.asMessageChain()
27+
val messageChain = protoMessageToMiraiMessage(req.messageList, bot, contact, req.autoEscape).asMessageChain()
2828
val messageSource = contact.sendMessage(messageChain).source
2929
bot.messageSourceLru.put(messageSource.id, messageSource)
3030
return BSendGroupMsgResp.newBuilder().setMessageId(messageSource.id).build()
@@ -42,7 +42,7 @@ suspend fun handleSendMsgReq(bot: Bot, req: BSendMsgReq): BSendMsgResp? {
4242
bot.getGroupOrNull(req.groupId) ?: bot.getFriendOrNull(req.userId)
4343
}
4444
} ?: return null
45-
val messageChain = req.messageList.map { it.toMiraiMessage(bot, contact) }.asMessageChain()
45+
val messageChain = protoMessageToMiraiMessage(req.messageList, bot, contact, req.autoEscape).asMessageChain()
4646
val messageSource = contact.sendMessage(messageChain).source
4747
bot.messageSourceLru.put(messageSource.id, messageSource)
4848
return BSendMsgResp.newBuilder().setMessageId(messageSource.id).build()

src/main/kotlin/net/lz1998/mirai/utils/MsgConverter.kt

Lines changed: 120 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,140 @@ import kotlinx.coroutines.withContext
55
import net.lz1998.mirai.alias.BMessage
66
import net.mamoe.mirai.Bot
77
import net.mamoe.mirai.contact.Contact
8+
import net.mamoe.mirai.contact.Group
89
import net.mamoe.mirai.getGroupOrNull
910
import net.mamoe.mirai.message.data.*
11+
import net.mamoe.mirai.message.uploadAsGroupVoice
1012
import net.mamoe.mirai.message.uploadAsImage
1113
import java.net.URL
14+
import javax.xml.parsers.DocumentBuilderFactory
1215

1316
val MSG_EMPTY = PlainText("")
1417

15-
suspend fun BMessage.toMiraiMessage(bot: Bot, contact: Contact): Message {
16-
return when (this.type) {
17-
"text" -> PlainText(dataMap["text"] ?: "")
18-
"face" -> dataMap["id"]?.toInt()?.let { Face(it) } ?: MSG_EMPTY
19-
"image" -> try {
20-
withContext(Dispatchers.IO) {
21-
val img = URL(dataMap["url"] ?: dataMap["file"]
22-
?: "").openConnection().getInputStream().uploadAsImage(contact)
23-
if (dataMap["type"] == "flash") img.flash() else img
18+
19+
suspend fun protoMessageToMiraiMessage(msgList: List<BMessage>, bot: Bot, contact: Contact, notConvert: Boolean): List<Message> {
20+
val messageChain = mutableListOf<Message>()
21+
msgList.forEach {
22+
when (it.type) {
23+
"text" -> {
24+
if (notConvert) {
25+
messageChain.add(protoTextToMiraiText(it.dataMap))
26+
} else {
27+
val text = it.dataMap["text"] ?: return@forEach
28+
messageChain.addAll(rawMessageToMiraiMessage(text, bot, contact))
29+
}
30+
}
31+
"face" -> messageChain.add(protoFaceToMiraiFace(it.dataMap))
32+
"image" -> messageChain.add(protoImageToMiraiImage(it.dataMap, contact))
33+
"at" -> messageChain.add(protoAtToMiraiAt(it.dataMap, bot, contact))
34+
"record" -> messageChain.add(protoVoiceToMiraiVoice(it.dataMap, contact))
35+
"voice" -> messageChain.add(protoVoiceToMiraiVoice(it.dataMap, contact))
36+
else -> MSG_EMPTY
37+
}
38+
}
39+
return messageChain
40+
}
41+
42+
43+
fun protoTextToMiraiText(dataMap: Map<String, String>): Message {
44+
return PlainText(dataMap["text"] ?: "")
45+
}
46+
47+
suspend fun protoImageToMiraiImage(dataMap: Map<String, String>, contact: Contact): Message {
48+
return try {
49+
withContext(Dispatchers.IO) {
50+
val img = URL(dataMap["url"] ?: dataMap["file"]
51+
?: "").openConnection().getInputStream().uploadAsImage(contact)
52+
if (dataMap["type"] == "flash") img.flash() else img
53+
}
54+
} catch (e: Exception) {
55+
MSG_EMPTY
56+
}
57+
}
58+
59+
fun protoAtToMiraiAt(dataMap: Map<String, String>, bot: Bot, contact: Contact): Message {
60+
return if (dataMap["qq"] == "all")
61+
AtAll
62+
else
63+
dataMap["qq"]?.toLong()?.let { userId -> bot.getGroupOrNull(contact.id)?.getOrNull(userId)?.let { At(it) } }
64+
?: MSG_EMPTY
65+
}
66+
67+
fun protoFaceToMiraiFace(dataMap: Map<String, String>): Message {
68+
return dataMap["id"]?.toInt()?.let { Face(it) } ?: MSG_EMPTY
69+
}
70+
71+
suspend fun protoVoiceToMiraiVoice(dataMap: Map<String, String>, contact: Contact): Message {
72+
when (contact) {
73+
is Group -> {
74+
val url = dataMap["url"] ?: return MSG_EMPTY
75+
return try {
76+
withContext(Dispatchers.IO) {
77+
URL(url).openStream().uploadAsGroupVoice(contact)
78+
}
79+
} catch (e: Exception) {
80+
MSG_EMPTY
2481
}
25-
} catch (e: Exception) {
26-
MSG_EMPTY
2782
}
28-
"at" -> {
29-
if (dataMap["qq"] == "all")
30-
AtAll
31-
else
32-
dataMap["qq"]?.toLong()?.let { userId -> bot.getGroupOrNull(contact.id)?.getOrNull(userId)?.let { At(it) } }
33-
?: MSG_EMPTY
83+
else -> return MSG_EMPTY
84+
}
85+
86+
}
87+
88+
suspend fun rawMessageToMiraiMessage(str: String, bot: Bot, contact: Contact): List<Message> {
89+
val messageList = mutableListOf<Message>()
90+
var str = str
91+
val re = Regex("<[\\s\\S]+?/>")
92+
val textList = re.split(str).toMutableList()
93+
val codeList = re.findAll(str).map { it.value }.toMutableList()
94+
while (textList.isNotEmpty() || codeList.isNotEmpty()) {
95+
if (textList.isNotEmpty() && str.startsWith(textList.first())) {
96+
val text = textList.first()
97+
textList.removeFirst()
98+
str = str.substring(text.length)
99+
messageList.add(PlainText(text))
100+
}
101+
if (codeList.isNotEmpty() && str.startsWith(codeList.first())) {
102+
val code = codeList.first()
103+
codeList.removeFirst()
104+
str = str.substring(code.length)
105+
// decode xml
106+
val builderFactory = DocumentBuilderFactory.newInstance()
107+
val docBuilder = builderFactory.newDocumentBuilder()
108+
val node = docBuilder.parse(code.byteInputStream()).firstChild
109+
110+
val dataMap = mutableMapOf<String, String>()
111+
while (node.attributes.length > 0) {
112+
val item = node.attributes.item(0)
113+
dataMap[item.nodeName] = item.nodeValue
114+
node.attributes.removeNamedItem(item.nodeName)
115+
}
116+
when (node.nodeName) {
117+
"at" -> messageList.add(protoAtToMiraiAt(dataMap, bot, contact))
118+
"image" -> messageList.add(protoImageToMiraiImage(dataMap, contact))
119+
"face" -> messageList.add(protoFaceToMiraiFace(dataMap))
120+
"text" -> messageList.add(protoTextToMiraiText(dataMap))
121+
"record" -> messageList.add(protoVoiceToMiraiVoice(dataMap, contact))
122+
"voice" -> messageList.add(protoVoiceToMiraiVoice(dataMap, contact))
123+
}
34124
}
35-
else -> MSG_EMPTY
125+
36126
}
127+
return messageList
37128
}
38129

39130

40-
fun MessageChain.toRawMessage(): String {
41-
var rawMessage = ""
42-
this.forEachContent { rawMessage += it.contentToString() }
43-
return rawMessage
131+
suspend fun MessageChain.toRawMessage(): String {
132+
return this.map {
133+
when (it) {
134+
is PlainText -> it.content
135+
is At -> """<at qq="${it.target}"/>"""
136+
is Image -> """<image url="${it.queryUrl()}"/>"""
137+
is Voice -> """<voice url="${it.url}"/>"""
138+
is Face -> """<face id="${it.id}"/>"""
139+
else -> ""
140+
}
141+
}.joinToString("")
44142
}
45143

46144
suspend fun MessageChain.toOnebotMessage(): List<BMessage> {

0 commit comments

Comments
 (0)