Commit 1dbeb44f authored by ryoii's avatar ryoii

Support Group VoiceMessage receiving

parent 9924d37e
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
package net.mamoe.mirai.qqandroid.message package net.mamoe.mirai.qqandroid.message
import kotlinx.io.core.String
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readUInt import kotlinx.io.core.readUInt
import kotlinx.io.core.toByteArray import kotlinx.io.core.toByteArray
...@@ -156,6 +157,7 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B ...@@ -156,6 +157,7 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B
is VipFace -> { is VipFace -> {
transformOneMessage(PlainText(it.contentToString())) transformOneMessage(PlainText(it.contentToString()))
} }
is PttMessage,
is ForwardMessage, is ForwardMessage,
is MessageSource, // mirai metadata only is MessageSource, // mirai metadata only
is RichMessage // already transformed above is RichMessage // already transformed above
...@@ -187,6 +189,9 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B ...@@ -187,6 +189,9 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B
this.anyIsInstance<FlashImage>() -> { this.anyIsInstance<FlashImage>() -> {
elements.add(ImMsgBody.Elem(generalFlags = ImMsgBody.GeneralFlags(pbReserve = PB_RESERVE_FOR_DOUTU))) 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))) 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 ...@@ -197,6 +202,9 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B
private val PB_RESERVE_FOR_RICH_MESSAGE = 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() "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") @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_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() private val PB_RESERVE_FOR_ELSE = "78 00 F8 01 00 C8 02 00".hexToBytes()
...@@ -209,8 +217,16 @@ internal fun MsgComm.Msg.toMessageChain( ...@@ -209,8 +217,16 @@ internal fun MsgComm.Msg.toMessageChain(
isTemp: Boolean = false isTemp: Boolean = false
): MessageChain { ): MessageChain {
val elements = this.msgBody.richText.elems 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) { if (onlineSource) {
when { when {
isTemp -> +MessageSourceFromTempImpl(bot, this@toMessageChain) isTemp -> +MessageSourceFromTempImpl(bot, this@toMessageChain)
...@@ -221,6 +237,7 @@ internal fun MsgComm.Msg.toMessageChain( ...@@ -221,6 +237,7 @@ internal fun MsgComm.Msg.toMessageChain(
+OfflineMessageSourceImplByMsg(this@toMessageChain, bot) +OfflineMessageSourceImplByMsg(this@toMessageChain, bot)
} }
elements.joinToMessageChain(groupIdOrZero, bot, this) elements.joinToMessageChain(groupIdOrZero, bot, this)
pptMsg?.let(::add)
}.cleanupRubbishMessageElements() }.cleanupRubbishMessageElements()
} }
......
...@@ -17,6 +17,7 @@ import kotlinx.coroutines.FlowPreview ...@@ -17,6 +17,7 @@ import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.toByteArray
import net.mamoe.mirai.LowLevelAPI import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.Friend import net.mamoe.mirai.contact.Friend
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
...@@ -32,6 +33,9 @@ import net.mamoe.mirai.getFriendOrNull ...@@ -32,6 +33,9 @@ import net.mamoe.mirai.getFriendOrNull
import net.mamoe.mirai.message.FriendMessage import net.mamoe.mirai.message.FriendMessage
import net.mamoe.mirai.message.TempMessage import net.mamoe.mirai.message.TempMessage
import net.mamoe.mirai.message.data.MessageChain 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.QQAndroidBot
import net.mamoe.mirai.qqandroid.contact.GroupImpl import net.mamoe.mirai.qqandroid.contact.GroupImpl
import net.mamoe.mirai.qqandroid.contact.checkIsFriendImpl import net.mamoe.mirai.qqandroid.contact.checkIsFriendImpl
...@@ -51,6 +55,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.* ...@@ -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.GroupInfoImpl
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.NewContact 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.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.readProtoBuf
import net.mamoe.mirai.qqandroid.utils.io.serialization.readUniPacket import net.mamoe.mirai.qqandroid.utils.io.serialization.readUniPacket
import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
...@@ -280,6 +285,10 @@ internal class MessageSvc { ...@@ -280,6 +285,10 @@ internal class MessageSvc {
} else return@mapNotNull null } else return@mapNotNull null
} }
} }
208 -> {
// friend ptt
return@mapNotNull null
}
141 -> { 141 -> {
val tmpHead = msg.msgHead.c2cTmpMsgHead ?: return@mapNotNull null val tmpHead = msg.msgHead.c2cTmpMsgHead ?: return@mapNotNull null
val member = bot.getGroupByUinOrNull(tmpHead.groupUin)?.getOrNull(msg.msgHead.fromUin) val member = bot.getGroupByUinOrNull(tmpHead.groupUin)?.getOrNull(msg.msgHead.fromUin)
...@@ -521,7 +530,10 @@ internal class MessageSvc { ...@@ -521,7 +530,10 @@ internal class MessageSvc {
contentHead = MsgComm.ContentHead(pkgNum = 1), contentHead = MsgComm.ContentHead(pkgNum = 1),
msgBody = ImMsgBody.MsgBody( msgBody = ImMsgBody.MsgBody(
richText = ImMsgBody.RichText( 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(), msgSeq = client.atomicNextMessageSequenceId(),
......
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 = "[语音]"
}
\ No newline at end of file
...@@ -233,6 +233,8 @@ internal fun <M : Message> MessageChain.firstOrNullImpl(key: Message.Key<M>): M? ...@@ -233,6 +233,8 @@ internal fun <M : Message> MessageChain.firstOrNullImpl(key: Message.Key<M>): M?
CustomMessage -> firstIsInstanceOrNull() CustomMessage -> firstIsInstanceOrNull()
CustomMessageMetadata -> firstIsInstanceOrNull() CustomMessageMetadata -> firstIsInstanceOrNull()
ForwardMessage -> firstIsInstanceOrNull() ForwardMessage -> firstIsInstanceOrNull()
PttMessage -> firstIsInstanceOrNull<PttMessage>()
Voice -> firstIsInstanceOrNull<Voice>()
else -> { else -> {
this.forEach { message -> this.forEach { message ->
if (message is CustomMessage) { if (message is CustomMessage) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment