From 73923d46f6b6e67ddb8ad2311a9d655a34b87a9e Mon Sep 17 00:00:00 2001 From: ryoii Date: Sun, 26 Apr 2020 16:51:28 +0800 Subject: [PATCH] Parse anonymous chat, close #277 --- .../mirai/qqandroid/contact/GroupImpl.kt | 12 ++++++ .../qqandroid/message/incomingSourceImpl.kt | 21 ++++++++--- .../packet/chat/receive/OnlinePush.kt | 37 ++++++++++++------- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt index 90d2ec27b..bacda6a7d 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt @@ -28,10 +28,12 @@ import net.mamoe.mirai.qqandroid.message.MessageSourceToGroupImpl import net.mamoe.mirai.qqandroid.message.ensureSequenceIdAvailable import net.mamoe.mirai.qqandroid.message.firstIsInstanceOrNull import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper +import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService +import net.mamoe.mirai.qqandroid.utils.encodeToString import net.mamoe.mirai.qqandroid.utils.estimateLength import net.mamoe.mirai.utils.* import kotlin.contracts.ExperimentalContracts @@ -252,6 +254,16 @@ internal class GroupImpl( ) } + internal fun newAnonymous(name: String): Member = newMember( + object : MemberInfo { + override val nameCard = name + override val permission = MemberPermission.MEMBER + override val specialTitle = "匿名" + override val muteTimestamp = 0 + override val uin = 80000000L + override val nick = name + } + ) override operator fun get(id: Long): Member { if (id == bot.id) { diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/incomingSourceImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/incomingSourceImpl.kt index 4092b0162..2c54967d4 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/incomingSourceImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/incomingSourceImpl.kt @@ -12,18 +12,23 @@ package net.mamoe.mirai.qqandroid.message import net.mamoe.mirai.Bot +import net.mamoe.mirai.LowLevelAPI import net.mamoe.mirai.contact.Friend import net.mamoe.mirai.contact.Member +import net.mamoe.mirai.contact.MemberPermission +import net.mamoe.mirai.data.MemberInfo import net.mamoe.mirai.event.internal.MiraiAtomicBoolean import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.OnlineMessageSource +import net.mamoe.mirai.qqandroid.contact.GroupImpl import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgComm import net.mamoe.mirai.qqandroid.network.protocol.data.proto.SourceMsg import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY import net.mamoe.mirai.qqandroid.utils._miraiContentToString +import net.mamoe.mirai.qqandroid.utils.encodeToString import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray internal interface MessageSourceInternal { @@ -141,13 +146,19 @@ internal data class MessageSourceFromGroupImpl( override val originalMessage: MessageChain by lazy { msg.toMessageChain(bot, groupIdOrZero = group.id, onlineSource = false) } - override val sender: Member - get() = bot.getGroup( + + override val sender: Member by lazy { + (bot.getGroup( msg.msgHead.groupInfo?.groupCode ?: error("cannot find groupCode for MessageSourceFromGroupImpl. msg=${msg._miraiContentToString()}") - ).getOrNull(msg.msgHead.fromUin) - ?: error("cannot find member for MessageSourceFromGroupImpl. msg=${msg._miraiContentToString()}") - + ) as GroupImpl).run { + getOrNull(msg.msgHead.fromUin) + ?: msg.msgBody.richText.elems.firstOrNull { it.anonGroupMsg != null }?.run { + newAnonymous(anonGroupMsg!!.anonNick.encodeToString()) + } + ?: error("cannot find member for MessageSourceFromGroupImpl. msg=${msg._miraiContentToString()}") + } + } override fun toJceData(): ImMsgBody.SourceMsg { return ImMsgBody.SourceMsg( diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt index a88e9ff90..51fa82b5c 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt @@ -69,9 +69,6 @@ internal class OnlinePush { if (!bot.firstLoginSucceed) return null val pbPushMsg = readProtoBuf(MsgOnlinePush.PbPushMsg.serializer()) - val extraInfo: ImMsgBody.ExtraInfo? = - pbPushMsg.msg.msgBody.richText.elems.firstOrNull { it.extraInfo != null }?.extraInfo - if (pbPushMsg.msg.msgHead.fromUin == bot.id) { return SendGroupMessageReceipt( pbPushMsg.msg.msgBody.richText.attr!!.random, @@ -79,16 +76,30 @@ internal class OnlinePush { ) } - val group = bot.getGroupOrNull(pbPushMsg.msg.msgHead.groupInfo!!.groupCode) ?: return null // 机器人还正在进群 - val sender = group[pbPushMsg.msg.msgHead.fromUin] as MemberImpl - val name = extraInfo?.groupCard?.takeIf { it.isNotEmpty() }?.run { - kotlin.runCatching { - if (this[0] == 0x0A.toByte()) - loadAs(Oidb0x8fc.CommCardNameBuf.serializer()).richCardName?.joinToString("") { it.text.encodeToString() } - else return@runCatching null - }.getOrNull() ?: encodeToString() - } ?: pbPushMsg.msg.msgHead.groupInfo.groupCard.takeIf { it.isNotEmpty() } - ?: sender.nameCardOrNick // 没有 extraInfo 就从 head 里取 + val extraInfo: ImMsgBody.ExtraInfo? = + pbPushMsg.msg.msgBody.richText.elems.firstOrNull { it.extraInfo != null }?.extraInfo + + val anonymous = pbPushMsg.msg.msgBody.richText.elems.firstOrNull { it.anonGroupMsg != null }?.anonGroupMsg + + val group = bot.getGroupOrNull(pbPushMsg.msg.msgHead.groupInfo!!.groupCode) as GroupImpl ?: return null // 机器人还正在进群 + val sender = if (anonymous != null) { + group.newAnonymous(anonymous.anonNick.encodeToString()) + } else { + group[pbPushMsg.msg.msgHead.fromUin] + } as MemberImpl + + val name = if (anonymous != null) { + sender.nameCard + } else { + extraInfo?.groupCard?.takeIf { it.isNotEmpty() }?.run { + kotlin.runCatching { + if (this[0] == 0x0A.toByte()) + loadAs(Oidb0x8fc.CommCardNameBuf.serializer()).richCardName?.joinToString("") { it.text.encodeToString() } + else return@runCatching null + }.getOrNull() ?: encodeToString() + } ?: pbPushMsg.msg.msgHead.groupInfo.groupCard.takeIf { it.isNotEmpty() } + ?: sender.nameCardOrNick // 没有 extraInfo 就从 head 里取 + } val flags = extraInfo?.flags ?: 0 return GroupMessage(