mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-13 06:30:13 +08:00
Support Group VoiceMessage receiving
This commit is contained in:
parent
9924d37e54
commit
1dbeb44f5b
@ -11,6 +11,7 @@
|
||||
|
||||
package net.mamoe.mirai.qqandroid.message
|
||||
|
||||
import kotlinx.io.core.String
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readUInt
|
||||
import kotlinx.io.core.toByteArray
|
||||
@ -156,6 +157,7 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B
|
||||
is VipFace -> {
|
||||
transformOneMessage(PlainText(it.contentToString()))
|
||||
}
|
||||
is PttMessage,
|
||||
is ForwardMessage,
|
||||
is MessageSource, // mirai metadata only
|
||||
is RichMessage // already transformed above
|
||||
@ -187,6 +189,9 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B
|
||||
this.anyIsInstance<FlashImage>() -> {
|
||||
elements.add(ImMsgBody.Elem(generalFlags = ImMsgBody.GeneralFlags(pbReserve = PB_RESERVE_FOR_DOUTU)))
|
||||
}
|
||||
this.anyIsInstance<PttMessage>() -> {
|
||||
elements.add(ImMsgBody.Elem(generalFlags = ImMsgBody.GeneralFlags(pbReserve = PB_RESERVE_FOR_PTT)))
|
||||
}
|
||||
else -> elements.add(ImMsgBody.Elem(generalFlags = ImMsgBody.GeneralFlags(pbReserve = PB_RESERVE_FOR_ELSE)))
|
||||
}
|
||||
}
|
||||
@ -197,6 +202,9 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B
|
||||
private val PB_RESERVE_FOR_RICH_MESSAGE =
|
||||
"08 09 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 02 08 03 90 04 80 80 80 10 B8 04 00 C0 04 00".hexToBytes()
|
||||
|
||||
private val PB_RESERVE_FOR_PTT =
|
||||
"78 00 F8 01 00 C8 02 00 AA 03 26 08 22 12 22 41 20 41 3B 25 3E 16 45 3F 43 2F 29 3E 44 24 14 18 46 3D 2B 4A 44 3A 18 2E 19 29 1B 26 32 31 31 29 43".hexToBytes()
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private val PB_RESERVE_FOR_DOUTU = "78 00 90 01 01 F8 01 00 A0 02 00 C8 02 00".hexToBytes()
|
||||
private val PB_RESERVE_FOR_ELSE = "78 00 F8 01 00 C8 02 00".hexToBytes()
|
||||
@ -209,8 +217,16 @@ internal fun MsgComm.Msg.toMessageChain(
|
||||
isTemp: Boolean = false
|
||||
): MessageChain {
|
||||
val elements = this.msgBody.richText.elems
|
||||
val ptt = this.msgBody.richText.ptt
|
||||
|
||||
return buildMessageChain(elements.size + 1) {
|
||||
val pptMsg = ptt?.run {
|
||||
when(fileType) {
|
||||
4 -> Voice(String(fileName), fileMd5, String(downPara))
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
return buildMessageChain(elements.size + 1 + if (pptMsg == null) 0 else 1) {
|
||||
if (onlineSource) {
|
||||
when {
|
||||
isTemp -> +MessageSourceFromTempImpl(bot, this@toMessageChain)
|
||||
@ -221,6 +237,7 @@ internal fun MsgComm.Msg.toMessageChain(
|
||||
+OfflineMessageSourceImplByMsg(this@toMessageChain, bot)
|
||||
}
|
||||
elements.joinToMessageChain(groupIdOrZero, bot, this)
|
||||
pptMsg?.let(::add)
|
||||
}.cleanupRubbishMessageElements()
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.toByteArray
|
||||
import net.mamoe.mirai.LowLevelAPI
|
||||
import net.mamoe.mirai.contact.Friend
|
||||
import net.mamoe.mirai.contact.Group
|
||||
@ -32,6 +33,9 @@ import net.mamoe.mirai.getFriendOrNull
|
||||
import net.mamoe.mirai.message.FriendMessage
|
||||
import net.mamoe.mirai.message.TempMessage
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.PttMessage
|
||||
import net.mamoe.mirai.message.data.Voice
|
||||
import net.mamoe.mirai.message.data.firstOrNull
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.contact.GroupImpl
|
||||
import net.mamoe.mirai.qqandroid.contact.checkIsFriendImpl
|
||||
@ -51,6 +55,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.*
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NewContact
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
|
||||
import net.mamoe.mirai.qqandroid.utils._miraiContentToString
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.readUniPacket
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
|
||||
@ -280,6 +285,10 @@ internal class MessageSvc {
|
||||
} else return@mapNotNull null
|
||||
}
|
||||
}
|
||||
208 -> {
|
||||
// friend ptt
|
||||
return@mapNotNull null
|
||||
}
|
||||
141 -> {
|
||||
val tmpHead = msg.msgHead.c2cTmpMsgHead ?: return@mapNotNull null
|
||||
val member = bot.getGroupByUinOrNull(tmpHead.groupUin)?.getOrNull(msg.msgHead.fromUin)
|
||||
@ -521,7 +530,10 @@ internal class MessageSvc {
|
||||
contentHead = MsgComm.ContentHead(pkgNum = 1),
|
||||
msgBody = ImMsgBody.MsgBody(
|
||||
richText = ImMsgBody.RichText(
|
||||
elems = message.toRichTextElems(forGroup = true, withGeneralFlags = true)
|
||||
elems = message.toRichTextElems(forGroup = true, withGeneralFlags = true),
|
||||
ptt = message.firstOrNull(PttMessage)?.run {
|
||||
ImMsgBody.Ptt(fileName = fileName.toByteArray(), fileMd5 = md5)
|
||||
}
|
||||
)
|
||||
),
|
||||
msgSeq = client.atomicNextMessageSequenceId(),
|
||||
|
@ -0,0 +1,45 @@
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
/**
|
||||
* 需要通过上传到服务器的消息,如语音、文件
|
||||
*/
|
||||
abstract class PttMessage : MessageContent {
|
||||
|
||||
companion object Key : Message.Key<PttMessage> {
|
||||
override val typeName: String
|
||||
get() = "PttMessage"
|
||||
}
|
||||
|
||||
abstract val fileName: String
|
||||
abstract val md5: ByteArray
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 语音消息, 目前只支持接收和转发
|
||||
*/
|
||||
class Voice(
|
||||
override val fileName: String,
|
||||
override val md5: ByteArray,
|
||||
private val _url: String
|
||||
) : PttMessage() {
|
||||
|
||||
companion object Key : Message.Key<Voice> {
|
||||
override val typeName: String
|
||||
get() = "Voice"
|
||||
}
|
||||
|
||||
val url: String
|
||||
get() = if (_url.startsWith("http")) _url
|
||||
else "http://grouptalk.c2c.qq.com$_url"
|
||||
|
||||
private var _stringValue: String? = null
|
||||
get() = field ?: kotlin.run {
|
||||
field = "[mirai:voice:$fileName]"
|
||||
field
|
||||
}
|
||||
|
||||
override fun toString(): String = _stringValue!!
|
||||
|
||||
override fun contentToString(): String = "[语音]"
|
||||
}
|
@ -233,6 +233,8 @@ internal fun <M : Message> MessageChain.firstOrNullImpl(key: Message.Key<M>): M?
|
||||
CustomMessage -> firstIsInstanceOrNull()
|
||||
CustomMessageMetadata -> firstIsInstanceOrNull()
|
||||
ForwardMessage -> firstIsInstanceOrNull()
|
||||
PttMessage -> firstIsInstanceOrNull<PttMessage>()
|
||||
Voice -> firstIsInstanceOrNull<Voice>()
|
||||
else -> {
|
||||
this.forEach { message ->
|
||||
if (message is CustomMessage) {
|
||||
|
Loading…
Reference in New Issue
Block a user