From 028bfa483cbcbba753a3852e0a6e033b367bc91a Mon Sep 17 00:00:00 2001 From: sandtechnology <20417547+sandtechnology@users.noreply.github.com> Date: Thu, 6 May 2021 17:54:52 +0800 Subject: [PATCH] Introduce MemberNick class and correct nameCard decoding, Fix #1151 (#1231) * Introduce MemberNick class and correct nameCard decoding, Fix #1151 * Update comment for better understanding Co-authored-by: Him188 * Change var name in method for better understanding Co-authored-by: Him188 * Fix build Co-authored-by: Him188 --- .../chat/receive/OnlinePush.PbPushGroupMsg.kt | 53 ++++++++++++++----- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt index d84b49418..96d4a9347 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt @@ -13,7 +13,6 @@ package net.mamoe.mirai.internal.network.protocol.packet.chat.receive import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.contact.Member -import net.mamoe.mirai.contact.nameCardOrNick import net.mamoe.mirai.event.AbstractEvent import net.mamoe.mirai.event.Event import net.mamoe.mirai.event.events.GroupMessageEvent @@ -29,6 +28,7 @@ import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm import net.mamoe.mirai.internal.network.protocol.data.proto.MsgOnlinePush import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0x8fc import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacketFactory +import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.OnlinePushPbPushGroupMsg.MemberNick.Companion.generateMemberNickFromMember import net.mamoe.mirai.internal.utils.broadcastWithBot import net.mamoe.mirai.internal.utils.io.serialization.loadAs import net.mamoe.mirai.internal.utils.io.serialization.readProtoBuf @@ -53,6 +53,16 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory("Onlin } } + internal data class MemberNick(val nick: String, val isNameCard: Boolean = false) { + companion object { + fun Member.generateMemberNickFromMember(): MemberNick { + return nameCard.takeIf { nameCard.isNotEmpty() }?.let { + MemberNick(nameCard, true) + } ?: MemberNick(nick, false) + } + } + } + @OptIn(ExperimentalStdlibApi::class) override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): Packet? { // 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00 @@ -101,17 +111,17 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory("Onlin val sender: Member // null if sync from other client - val name: String + val nameCard: MemberNick if (anonymous != null) { // anonymous member sender = group.newAnonymous(anonymous.anonNick.encodeToString(), anonymous.anonId.encodeBase64()) - name = sender.nameCard + nameCard = sender.generateMemberNickFromMember() } else { // normal member chat sender = group[msgHead.fromUin] as NormalMemberImpl? ?: kotlin.run { bot.network.logger.warning { "Failed to find member ${msgHead.fromUin} in group ${group.id}" } return null } - name = findSenderName(extraInfo, msgHead.groupInfo) ?: sender.nameCardOrNick + nameCard = findSenderName(extraInfo, msgHead.groupInfo) ?: sender.generateMemberNickFromMember() } sender.info?.castOrNull()?.run { @@ -124,14 +134,14 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory("Onlin time = msgHead.msgTime, group = group, sender = sender, - senderName = name, + senderName = nameCard.nick, ) } else { - broadcastNameCardChangedEventIfNecessary(sender, name) + broadcastNameCardChangedEventIfNecessary(sender, nameCard) return GroupMessageEvent( - senderName = name, + senderName = nameCard.nick, sender = sender, message = msgs.map { it.msg }.toMessageChainOnline(bot, group.id, GROUP), permission = sender.permission, @@ -140,19 +150,34 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory("Onlin } } - private suspend inline fun broadcastNameCardChangedEventIfNecessary(sender: Member, name: String) { - val currentNameCard = sender.nameCard - if (sender is NormalMemberImpl && name != currentNameCard) { - sender._nameCard = name - MemberCardChangeEvent(currentNameCard, name, sender).broadcastWithBot(sender.bot) + private suspend inline fun broadcastNameCardChangedEventIfNecessary(sender: Member, new: MemberNick) { + if (sender is NormalMemberImpl) { + val currentNameCard = sender.nameCard + if (new.isNameCard) { + new.nick.let { name -> + if (currentNameCard != name) { + sender._nameCard = name + MemberCardChangeEvent(currentNameCard, name, sender).broadcastWithBot(sender.bot) + } + } + } else { + // 说明删除了群名片 + if (currentNameCard.isNotEmpty()) { + sender._nameCard = "" + MemberCardChangeEvent(currentNameCard, "", sender).broadcastWithBot(sender.bot) + } + } } } private fun findSenderName( extraInfo: ImMsgBody.ExtraInfo?, groupInfo: MsgComm.GroupInfo - ) = extraInfo?.groupCard?.takeIf { it.isNotEmpty() }?.decodeCommCardNameBuf() - ?: groupInfo.groupCard.takeIf { it.isNotEmpty() } + ): MemberNick? = extraInfo?.groupCard?.takeIf { it.isNotEmpty() }?.decodeCommCardNameBuf()?.let { + MemberNick(it, true) + } ?: groupInfo.takeIf { it.groupCard.isNotEmpty() }?.let { + MemberNick(it.groupCard, it.groupCardType != 2) + } private fun ByteArray.decodeCommCardNameBuf() = kotlin.runCatching { if (this[0] == 0x0A.toByte()) {