From 42510d7c1c9463440b37c528402cd6ecfe6dee76 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 13 Nov 2021 13:09:57 +0800 Subject: [PATCH] Fix `UserProfile.sign`, fix #1620 --- .../protocol/data/richstatus/RichStatus.kt | 184 ++++++++++++++++++ .../packet/summarycard/SummaryCard.kt | 17 +- 2 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 mirai-core/src/commonMain/kotlin/network/protocol/data/richstatus/RichStatus.kt diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/data/richstatus/RichStatus.kt b/mirai-core/src/commonMain/kotlin/network/protocol/data/richstatus/RichStatus.kt new file mode 100644 index 000000000..fafbd7b9f --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/protocol/data/richstatus/RichStatus.kt @@ -0,0 +1,184 @@ +/* + * Copyright 2019-2021 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/dev/LICENSE + */ + +package net.mamoe.mirai.internal.network.protocol.data.richstatus + +import net.mamoe.mirai.utils.toIntUnsigned +import java.nio.ByteBuffer +import java.nio.ByteOrder + +internal class RichStatus( + @JvmField var actId: Int = 0, + @JvmField var actionId: Int = 0, + @JvmField var actionText: String? = null, + + @JvmField var dataId: Int = 0, + @JvmField var dataText: String? = null, + + @JvmField var feedsId: String? = null, + + @JvmField var fontId: Int = 0, + @JvmField var fontType: Int = 0, + + + @JvmField var key: ByteArray? = null, + + @JvmField var latitude: Int = 0, + @JvmField var locationPosition: Int = 0, + @JvmField var locationText: String? = null, + @JvmField var lontitude: Int = 0, + + // @JvmField var mStickerInfos: MutableList? = null, + // @JvmField var mUins: MutableList? = null, + @JvmField var plainText: MutableList? = null, + + // public HashMap sigZanInfo, + @JvmField var signType: Int = 0, + @JvmField var time: Long = 0, + + // var topics: MutableList> = mutableListOf(), + // var topicsPos: MutableList> = mutableListOf(), + @JvmField var tplId: Int = 0, + @JvmField var tplType: Int = 0, +) { + + fun addPlainText(var1: String) { + var pts = this.plainText + if (pts == null) { + pts = mutableListOf() + this.plainText = pts + } + pts.add(var1) + } + + companion object { + @Suppress("UsePropertyAccessSyntax") + fun parseStatus(rawData: ByteArray?): RichStatus { + val rsp = RichStatus() + + if (rawData == null || rawData.size <= 2) return rsp + + val byteBuffer = ByteBuffer.wrap(rawData).order(ByteOrder.BIG_ENDIAN) + + var lastPosition = 0 + var lastStringData: String? = null + + while (byteBuffer.remaining() >= 2) { + val dataType = byteBuffer.get().toIntUnsigned() + val dataLength = byteBuffer.get().toIntUnsigned() + + if (byteBuffer.remaining() < dataLength) break + + val dataStartPosition = lastPosition + 2 + + // Origin: dataType > 0 && dataType < 128 + if (dataType in 1..127) { + val dataContent = String(rawData, dataStartPosition, dataLength) + lastPosition = dataStartPosition + dataLength + byteBuffer.position(lastPosition) + + when (dataType) { + 1 -> rsp.actionText = dataContent + 2 -> rsp.dataText = dataContent + 4 -> { + if (lastStringData != null) { + rsp.addPlainText(lastStringData) + lastStringData = null + } + if (rsp.plainText != null) { + rsp.locationPosition = rsp.plainText!!.size + } else { + rsp.locationPosition = 0 + } + rsp.locationText = dataContent + } + else -> { + if (lastStringData == null) { + lastStringData = dataContent + } else { + lastStringData += dataContent + } + } + } + } else { + kotlin.run theSwitch@{ + when (dataType) { + 129 -> { + if (byteBuffer.remaining() >= 8) { + rsp.actionId = byteBuffer.getInt() + rsp.dataId = byteBuffer.getInt() + } + } + 130 -> { + if (byteBuffer.remaining() >= 8) { + rsp.lontitude = byteBuffer.getInt() + rsp.latitude = byteBuffer.getInt() + } + } + 144 -> rsp.feedsId = String(rawData, dataStartPosition, dataLength) + 145 -> rsp.tplId = byteBuffer.getInt() + 146 -> rsp.tplType = byteBuffer.getInt() + 147 -> rsp.actId = byteBuffer.getInt() + 148 -> { + if (byteBuffer.remaining() >= 4) { + lastPosition = byteBuffer.getInt() + /* + if (var1 > 4) { + var19 = String(var0, var5+4, var1-4) + if (var19.isNotEmpty()) { + var9.topics.add(Pair(var2, var19)) + } + } + */ + } + } + 149 -> { + if (byteBuffer.remaining() >= 5) { + lastPosition = dataLength + while (true) { + if (lastPosition < 5) return@theSwitch + + val var6 = byteBuffer.getInt() + var var4 = byteBuffer.get().toIntUnsigned() + + // var9.topicsPos.add(new Pair(var6, var3)); + lastPosition -= 5 + } + } + } + 161 -> { + /* + val var11 = ByteArray(dataLength) + byteBuffer.get(var11) + */ + byteBuffer.position(byteBuffer.position() + dataLength) + // Parse richstatus_sticker$RichStatus_Sticker + } + 162 -> { + rsp.fontId = byteBuffer.getInt() + } + 163 -> { + rsp.fontType = byteBuffer.getInt() + } + + } + } + lastPosition = dataStartPosition + dataLength + byteBuffer.position(lastPosition) + } + } + + if (lastStringData != null) { + rsp.addPlainText(lastStringData) + } + + return rsp + } + } +} diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/summarycard/SummaryCard.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/summarycard/SummaryCard.kt index 49b268d24..9c2815940 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/summarycard/SummaryCard.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/summarycard/SummaryCard.kt @@ -18,6 +18,7 @@ import net.mamoe.mirai.internal.network.QQAndroidClient import net.mamoe.mirai.internal.network.protocol.data.jce.ReqHead import net.mamoe.mirai.internal.network.protocol.data.jce.RequestDataVersion2 import net.mamoe.mirai.internal.network.protocol.data.jce.RequestPacket +import net.mamoe.mirai.internal.network.protocol.data.richstatus.RichStatus import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketFactory import net.mamoe.mirai.internal.network.protocol.packet.buildOutgoingUniPacket import net.mamoe.mirai.internal.utils.io.serialization.jceRequestSBuffer @@ -94,6 +95,20 @@ internal object SummaryCard { discardExact(1) Tars.UTF_8.load(JceRespSummaryCard.serializer(), this) } + + fun parseSignFromRichSign(): String? { + val vsign = response.vRichSign ?: return null + val richStatus = RichStatus.parseStatus(vsign) + val pt = richStatus.plainText + if (pt != null && pt.isNotEmpty()) { + return pt.first() + } + return null + } + + val sign = response.sign?.takeIf { it.isNotEmpty() } + ?: parseSignFromRichSign() + ?: "" return UserProfileImpl( nickname = response.nick ?: "", email = response.email ?: "", @@ -104,7 +119,7 @@ internal object SummaryCard { 1 -> UserProfile.Sex.FEMALE else -> UserProfile.Sex.UNKNOWN }, - sign = response.sign ?: "" + sign = sign ) } }