1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-04-15 07:37:08 +08:00

UserProfile query ()

* UserProfile query

* zip vReq0x5ebFieldId

* Move UserProfile to `net.mamoe.mirai.data`

* Move `queryProfile` to high-level api

* Add doc

* Update UserProfile.kt

* Make UserProfile experimental

* Convert UserProfile.sex to enum

* Remove debugging code

* Dump apis

Co-authored-by: Him188 <Him188@mamoe.net>
This commit is contained in:
Karlatemp 2021-01-22 07:47:57 +08:00 committed by GitHub
parent baa7eae6e7
commit c77f94cd52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 455 additions and 1 deletions
binary-compatibility-validator/api
mirai-core-api/src/commonMain/kotlin
mirai-core/src/commonMain/kotlin

View File

@ -36,6 +36,8 @@ public abstract interface class net/mamoe/mirai/Bot : kotlinx/coroutines/Corouti
public abstract fun login (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun nudge ()Lnet/mamoe/mirai/message/action/BotNudge;
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/Nudge;
public fun queryProfile (J)Lnet/mamoe/mirai/data/UserProfile;
public abstract fun queryProfile (JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
}
public final class net/mamoe/mirai/Bot$Companion {
@ -1416,6 +1418,23 @@ public abstract interface class net/mamoe/mirai/data/UserInfo {
public abstract fun getUin ()J
}
public abstract interface class net/mamoe/mirai/data/UserProfile {
public abstract fun getAge ()I
public abstract fun getEmail ()Ljava/lang/String;
public abstract fun getNickname ()Ljava/lang/String;
public abstract fun getQLevel ()I
public abstract fun getSex ()Lnet/mamoe/mirai/data/UserProfile$Sex;
public abstract fun getSign ()Ljava/lang/String;
}
public final class net/mamoe/mirai/data/UserProfile$Sex : java/lang/Enum {
public static final field FEMALE Lnet/mamoe/mirai/data/UserProfile$Sex;
public static final field MALE Lnet/mamoe/mirai/data/UserProfile$Sex;
public static final field UNKNOWN Lnet/mamoe/mirai/data/UserProfile$Sex;
public static fun valueOf (Ljava/lang/String;)Lnet/mamoe/mirai/data/UserProfile$Sex;
public static fun values ()[Lnet/mamoe/mirai/data/UserProfile$Sex;
}
public abstract class net/mamoe/mirai/event/AbstractEvent : net/mamoe/mirai/event/Event {
public fun <init> ()V
public final fun cancel ()V

View File

@ -17,12 +17,14 @@ package net.mamoe.mirai
import kotlinx.coroutines.*
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.UserProfile
import net.mamoe.mirai.event.EventChannel
import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.message.action.BotNudge
import net.mamoe.mirai.message.action.MemberNudge
import net.mamoe.mirai.network.LoginFailedException
import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiLogger
import java.util.concurrent.ConcurrentHashMap
@ -171,6 +173,16 @@ public interface Bot : CoroutineScope, ContactOrBot, UserOrBot {
*/
public override fun nudge(): BotNudge = BotNudge(this)
/**
* 查询某个用户的信息
*
* @since 2.1.0
*/
@MiraiExperimentalApi
@JvmBlockingBridge
public suspend fun queryProfile(targetId: Long): UserProfile
/**
* 关闭这个 [Bot], 立即取消 [Bot] [SupervisorJob], 取消与这个 [Bot] 相关的所有有协程联系的任务.
*

View File

@ -270,4 +270,5 @@ public interface LowLevelApiAccessor {
groupId: Long,
seconds: Int,
)
}

View File

@ -0,0 +1,33 @@
/*
* 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/master/LICENSE
*/
package net.mamoe.mirai.data
import net.mamoe.mirai.utils.MiraiExperimentalApi
@MiraiExperimentalApi
public interface UserProfile {
public val nickname: String
public val email: String
public val age: Int
public val qLevel: Int
public val sex: Sex
/**
* 个性签名
*/
public val sign: String
public enum class Sex {
MALE,
FEMALE,
/** 保密 */
UNKNOWN;
}
}

View File

@ -26,6 +26,7 @@ import net.mamoe.mirai.internal.message.*
import net.mamoe.mirai.internal.network.QQAndroidBotNetworkHandler
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.protocol.packet.chat.*
import net.mamoe.mirai.internal.network.protocol.packet.summarycard.SummaryCard
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.network.LoginFailedException
import net.mamoe.mirai.utils.*
@ -110,6 +111,13 @@ internal class QQAndroidBot constructor(
return groups.firstOrNull { it.checkIsGroupImpl(); it.uin == uin }
}
override suspend fun queryProfile(targetId: Long): UserProfile {
network.apply {
return SummaryCard.ReqSummaryCard(client, targetId)
.sendAndExpect<SummaryCard.ReqSummaryCard.RespSummaryCard>()
}
}
/**
* 获取 获取群公告 所需的 bkn 参数
* */

View File

@ -0,0 +1,265 @@
/*
* 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/master/LICENSE
*/
package net.mamoe.mirai.internal.network.protocol.data.jce
import kotlinx.serialization.Serializable
import net.mamoe.mirai.internal.utils.io.JceStruct
import net.mamoe.mirai.internal.utils.io.serialization.tars.TarsId
@Serializable
internal class ReqHead(
@JvmField @TarsId(0) val iVersion: Int = 1
) : JceStruct
@Serializable
internal class ReqSummaryCard(
@JvmField @TarsId(0) val uin: Long,
@JvmField @TarsId(1) val eComeFrom: Int = 65535,
@JvmField @TarsId(2) val uQzoneFeedTimestamp: Long? = null,
@JvmField @TarsId(3) val isFriend: Byte? = null,
@JvmField @TarsId(4) val groupCode: Long? = null,
@JvmField @TarsId(5) val groupUin: Long? = null,
//@JvmField @TarsId(6) val vSeed: ByteArray? = null,
//@JvmField @TarsId(7) val searchName: String? = "",
@JvmField @TarsId(8) val getControl: Long? = null,
@JvmField @TarsId(9) val eAddFriendSource: Int? = null,
@JvmField @TarsId(10) val vSecureSig: ByteArray? = null,
//@JvmField @TarsId(11) val vReqLastGameInfo: ByteArray? = null,
//@JvmField @TarsId(12) val vReqTemplateInfo: ByteArray? = null,
//@JvmField @TarsId(13) val vReqStarInfo: ByteArray? = null,
//@JvmField @TarsId(14) val vvReqServices: List<ByteArray>? = null,
@JvmField @TarsId(15) val tinyId: Long? = null,
@JvmField @TarsId(16) val uLikeSource: Long? = null,
//@JvmField @TarsId(17) val stLocaleInfo: UserLocaleInfo? = null,
@JvmField @TarsId(18) val reqMedalWallInfo: Byte? = null,
@JvmField @TarsId(19) val vReq0x5ebFieldId: List<Int>? = null,
@JvmField @TarsId(20) val reqNearbyGodInfo: Byte? = null,
//@JvmField @TarsId(21) val reqCommLabel: Byte? = null,
@JvmField @TarsId(22) val reqExtendCard: Byte? = null,
//@JvmField @TarsId(23) val vReqKandianInfo: ByteArray? = null,
//@JvmField @TarsId(24) val uRichCardNameVer: Long? = null
) : JceStruct
@Serializable
internal class RespHead(
@JvmField @TarsId(0) val iVersion: Int,
@JvmField @TarsId(1) val iResult: Int,
@JvmField @TarsId(2) val errorMsg: String = "",
@JvmField @TarsId(3) val vCookies: ByteArray? = null
) : JceStruct
@Serializable
internal class RespSearch(
@JvmField @TarsId(0) val vRecords: List<SearchInfo>,
@JvmField @TarsId(1) val vSecureSig: ByteArray? = null,
@JvmField @TarsId(2) val vvRespServices: List<ByteArray>? = null
) : JceStruct
@Serializable
internal class RespSummaryCard(
// @JvmField @TarsId(0) val iFace: Int? = null,
@JvmField @TarsId(1) val sex: Byte? = null,
@JvmField @TarsId(2) val age: Byte? = null,
@JvmField @TarsId(3) val nick: String? = "",
@JvmField @TarsId(4) val remark: String? = "",
@JvmField @TarsId(5) val iLevel: Int? = null,
@JvmField @TarsId(6) val province: String? = "",
@JvmField @TarsId(7) val city: String? = "",
@JvmField @TarsId(8) val sign: String? = "",
@JvmField @TarsId(9) val groupName: String? = "",
@JvmField @TarsId(10) val groupNick: String? = "",
@JvmField @TarsId(11) val mobile: String? = "",
@JvmField @TarsId(12) val contactName: String? = "",
@JvmField @TarsId(13) val ulShowControl: Long? = null,
@JvmField @TarsId(14) val qzoneFeedsDesc: String? = "",
// @JvmField @TarsId(15) val oLatestPhotos:AlbumInfo? = null,
@JvmField @TarsId(16) val iVoteCount: Int? = null,
@JvmField @TarsId(17) val iLastestVoteCount: Int? = null,
@JvmField @TarsId(18) val valid4Vote: Byte? = null,
@JvmField @TarsId(19) val country: String? = "",
@JvmField @TarsId(20) val status: String? = "",
@JvmField @TarsId(21) val autoRemark: String? = "",
@JvmField @TarsId(22) val cacheControl: Long? = null,
@JvmField @TarsId(23) val uin: Long? = null,
@JvmField @TarsId(24) val iPhotoCount: Int? = null,
@JvmField @TarsId(25) val eAddOption: Int? = 101,
@JvmField @TarsId(26) val vAddQuestion: List<String>? = null,
@JvmField @TarsId(27) val vSeed: ByteArray? = null,
@JvmField @TarsId(28) val discussName: String? = "",
@JvmField @TarsId(29) val stVipInfo: VipBaseInfo? = null,
@JvmField @TarsId(30) val showName: String? = "",
@JvmField @TarsId(31) val stVoiceInfo: VoiceInfo? = null,
@JvmField @TarsId(32) val vRichSign: ByteArray? = null,
@JvmField @TarsId(33) val uSignModifyTime: Long? = null,
@JvmField @TarsId(34) val vRespLastGameInfo: ByteArray? = null,
@JvmField @TarsId(35) val userFlag: Long? = null,
@JvmField @TarsId(36) val uLoginDays: Long? = null,
@JvmField @TarsId(37) val loginDesc: String? = "",
@JvmField @TarsId(38) val uTemplateId: Long? = null,
@JvmField @TarsId(39) val uQQMasterLoginDays: Long? = 20L,
@JvmField @TarsId(40) val ulFaceAddonId: Long? = null,
@JvmField @TarsId(41) val vRespTemplateInfo: ByteArray? = null,
@JvmField @TarsId(42) val respMusicInfo: String? = "",
@JvmField @TarsId(43) val vRespStarInfo: ByteArray? = null,
@JvmField @TarsId(44) val stDiamonds: VipBaseInfo? = null,
@JvmField @TarsId(45) val uAccelerateMultiple: Long? = null,
@JvmField @TarsId(46) val vvRespServices: List<ByteArray>? = null,
@JvmField @TarsId(47) val spaceName: String? = "",
// @JvmField @TarsId(48) val stDateCard:DateCard? = null,
@JvmField @TarsId(49) val iBirthday: Int? = null,
// @JvmField @TarsId(50) val stQCallInfo:QCallInfo? = null,
// @JvmField @TarsId(51) val stGiftInfo:GiftInfo? = null,
// @JvmField @TarsId(52) val stPanSocialInfo:PanSocialInfo? = null,
// @JvmField @TarsId(53) val stVideoInfo:QQVideoInfo? = null,
@JvmField @TarsId(54) val vTempChatSig: ByteArray? = null,
// @JvmField @TarsId(55) val stInterestTag:InterestTagInfo? = null,
// @JvmField @TarsId(56) val stUserFeed: UserFeed? = null,
// @JvmField @TarsId(57) val stQiqiVideoInfo:QiqiVideoInfo? = null,
// @JvmField @TarsId(58) val stPrivInfo:PrivilegeBaseInfo? = null,
// @JvmField @TarsId(59) val stApollo:QQApolloInfo? = null,
// @JvmField @TarsId(60) val stAddFrdSrcInfo:AddFrdSrcInfo? = null,
// @JvmField @TarsId(61) val stBindPhoneInfo:BindPhoneInfo? = null,
@JvmField @TarsId(62) val vVisitingCardInfo: ByteArray? = null,
@JvmField @TarsId(63) val voteLimitedNotice: String? = "",
@JvmField @TarsId(64) val haveVotedCnt: Short? = null,
@JvmField @TarsId(65) val availVoteCnt: Short? = null,
@JvmField @TarsId(66) val eIMBindPhoneNum: String? = "",
@JvmField @TarsId(67) val eIMId: String? = "",
@JvmField @TarsId(68) val email: String? = "",
@JvmField @TarsId(69) val uCareer: Long? = null,
@JvmField @TarsId(70) val personal: String? = "",
@JvmField @TarsId(71) val vHotChatInfo: ByteArray? = null,
// @JvmField @TarsId(72) val stOlympicInfo:OlympicInfo? = null,
@JvmField @TarsId(73) val stCoverInfo: TCoverInfo? = null,
@JvmField @TarsId(74) val stNowBroadcastInfo: TNowBroadcastInfo? = null,
// @JvmField @TarsId(75) val stEimInfo:TEIMInfo? = null,
@JvmField @TarsId(78) val stVideoHeadInfo: TVideoHeadInfo? = null,
@JvmField @TarsId(79) val iContactNotBindQQ: Int? = null,
// @JvmField @TarsId(80) val stMedalWallInfo:TMedalWallInfo? = null,
@JvmField @TarsId(81) val vvRespServicesBigOrder: List<ByteArray>? = null,
@JvmField @TarsId(82) val vResp0x5ebInfo: ByteArray? = null,
@JvmField @TarsId(83) val stNearbyGodInfo: TNearbyGodInfo? = null,
@JvmField @TarsId(84) val vRespQQStoryInfo: ByteArray? = null,
@JvmField @TarsId(85) val vRespCustomLabelInfo: ByteArray? = null,
@JvmField @TarsId(86) val vPraiseList: List<TPraiseInfo>? = null,
@JvmField @TarsId(87) val stCampusCircleInfo: TCampusCircleInfo? = null,
@JvmField @TarsId(88) val stTimInfo: TTimInfo? = null,
@JvmField @TarsId(89) val stQimInfo: TQimInfo? = null,
// @JvmField @TarsId(90) val stHeartInfo:HeartInfo? = null,
@JvmField @TarsId(91) val vQzoneCoverInfo: ByteArray? = null,
@JvmField @TarsId(92) val vNearbyTaskInfo: ByteArray? = null,
@JvmField @TarsId(93) val vNowInfo: ByteArray? = null,
@JvmField @TarsId(94) val uFriendGroupId: Long? = null,
@JvmField @TarsId(95) val vCommLabel: ByteArray? = null,
@JvmField @TarsId(96) val vExtendCard: ByteArray? = null,
@JvmField @TarsId(97) val qzoneHeader: String? = "",
@JvmField @TarsId(98) val mapQzoneEx: Map<String, String>? = null,
@JvmField @TarsId(99) val vRespKandianInfo: ByteArray? = null,
// @JvmField @TarsId(100) val stWeishiInfo:WeishiInfo? = null,
@JvmField @TarsId(101) val uRichCardNameVer: Long? = null,
@JvmField @TarsId(102) val uCurMulType: Long? = null,
@JvmField @TarsId(103) val vLongNickTopicInfo: ByteArray? = null
) : JceStruct
@Serializable
internal class RespVoiceManage(
@JvmField @TarsId(0) val eOpType: Int
) : JceStruct
@Serializable
internal class SearchInfo(
@JvmField @TarsId(0) val uIN: Long,
@JvmField @TarsId(1) val eSource: Int,
@JvmField @TarsId(2) val nick: String? = "",
@JvmField @TarsId(3) val mobile: String? = "",
@JvmField @TarsId(4) val isFriend: Byte? = null,
@JvmField @TarsId(5) val inContact: Byte? = null,
@JvmField @TarsId(6) val isEnterpriseQQ: Byte? = null
) : JceStruct
@Serializable
internal class TCampusCircleInfo(
@JvmField @TarsId(0) val iIsSigned: Int? = null,
@JvmField @TarsId(1) val name: String? = "",
@JvmField @TarsId(2) val academy: String? = "",
@JvmField @TarsId(3) val eStatus: Int? = null,
@JvmField @TarsId(4) val stSchoolInfo: TCampusSchoolInfo? = null
) : JceStruct
@Serializable
internal class TCampusSchoolInfo(
@JvmField @TarsId(0) val uTimestamp: Long? = null,
@JvmField @TarsId(1) val uSchoolId: Long? = null,
@JvmField @TarsId(2) val iIsValidForCertified: Int? = null
) : JceStruct
@Serializable
internal class TCoverInfo(
@JvmField @TarsId(0) val vTagInfo: ByteArray? = null
) : JceStruct
@Serializable
internal class TNearbyGodInfo(
@JvmField @TarsId(0) val iIsGodFlag: Int? = null,
@JvmField @TarsId(1) val jumpUrl: String? = ""
) : JceStruct
@Serializable
internal class TNowBroadcastInfo(
@JvmField @TarsId(0) val iFlag: Int? = null,
@JvmField @TarsId(1) val iconURL: String? = "",
@JvmField @TarsId(2) val hrefURL: String? = "",
@JvmField @TarsId(3) val vAnchorDataRsp: ByteArray? = null
) : JceStruct
@Serializable
internal class TPraiseInfo(
@JvmField @TarsId(0) val uCustomId: Long? = null,
@JvmField @TarsId(1) val iIsPayed: Int? = null
) : JceStruct
@Serializable
internal class TQimInfo(
@JvmField @TarsId(0) val iIsOnline: Int? = null
) : JceStruct
@Serializable
internal class TTimInfo(
@JvmField @TarsId(0) val iIsOnline: Int? = null
) : JceStruct
@Serializable
internal class TVideoHeadInfo(
@JvmField @TarsId(0) val iNearbyFlag: Int? = null,
@JvmField @TarsId(1) val iBasicFlag: Int? = null,
@JvmField @TarsId(2) val vMsg: ByteArray? = null
) : JceStruct
@Serializable
internal class UserFeed(
@JvmField @TarsId(0) val uFlag: Long? = null,
@JvmField @TarsId(1) val vFeedInfo: ByteArray? = null
) : JceStruct
@Serializable
internal class UserLocaleInfo(
@JvmField @TarsId(1) val longitude: Long? = null,
@JvmField @TarsId(2) val latitude: Long? = null
) : JceStruct
@Serializable
internal class VoiceInfo(
@JvmField @TarsId(0) val vVoiceId: ByteArray? = null,
@JvmField @TarsId(1) val shDuration: Short? = null,
@JvmField @TarsId(2) val read: Byte? = 2,
@JvmField @TarsId(3) val url: String? = ""
) : JceStruct

View File

@ -24,6 +24,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.ConfigPushSvc
import net.mamoe.mirai.internal.network.protocol.packet.login.Heartbeat
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.internal.network.protocol.packet.summarycard.SummaryCard
import net.mamoe.mirai.internal.network.readUShortLVByteArray
import net.mamoe.mirai.internal.utils.crypto.TEA
import net.mamoe.mirai.internal.utils.crypto.adjustToPublicKey
@ -154,7 +155,8 @@ internal object KnownPacketFactories {
NewContact.SystemMsgNewGroup,
ProfileService.GroupMngReq,
StrangerList.GetStrangerList,
StrangerList.DelStranger
StrangerList.DelStranger,
SummaryCard.ReqSummaryCard,
)
object IncomingFactories : List<IncomingPacketFactory<*>> by mutableListOf(

View File

@ -0,0 +1,114 @@
/*
* 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/master/LICENSE
*/
package net.mamoe.mirai.internal.network.protocol.packet.summarycard
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact
import net.mamoe.mirai.data.UserProfile
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.Packet
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.packet.OutgoingPacket
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketFactory
import net.mamoe.mirai.internal.network.protocol.packet.buildOutgoingUniPacket
import net.mamoe.mirai.internal.utils._miraiContentToString
import net.mamoe.mirai.internal.utils.io.serialization.jceRequestSBuffer
import net.mamoe.mirai.internal.utils.io.serialization.readJceStruct
import net.mamoe.mirai.internal.utils.io.serialization.tars.Tars
import net.mamoe.mirai.internal.utils.io.serialization.writeJceStruct
import net.mamoe.mirai.internal.utils.soutv
import net.mamoe.mirai.utils.read
import net.mamoe.mirai.internal.network.protocol.data.jce.ReqSummaryCard as JceReqSummaryCard
import net.mamoe.mirai.internal.network.protocol.data.jce.RespSummaryCard as JceRespSummaryCard
internal object SummaryCard {
internal object ReqSummaryCard : OutgoingPacketFactory<ReqSummaryCard.RespSummaryCard>(
"SummaryCard.ReqSummaryCard"
) {
internal class RespSummaryCard(
override val nickname: String,
override val email: String,
override val age: Int,
override val qLevel: Int,
override val sex: UserProfile.Sex,
override val sign: String,
) : Packet, UserProfile {
override fun toString(): String {
return "SummaryCard.RespSummaryCard(nickname=$nickname, email=$email, age=$age, qLevel=$qLevel, sex=$sex, sign=$sign)"
}
}
operator fun invoke(
client: QQAndroidClient,
uin: Long,
): OutgoingPacket = buildOutgoingUniPacket(client) {
writeJceStruct(
RequestPacket.serializer(),
RequestPacket(
funcName = "ReqSummaryCard",
servantName = "SummaryCardServantObj",
version = 3,
sBuffer = jceRequestSBuffer {
"ReqHead"(ReqHead.serializer(), ReqHead(2))
"ReqSummaryCard"(
JceReqSummaryCard.serializer(), JceReqSummaryCard(
uin = uin,
eComeFrom = 31,
getControl = 69181,
eAddFriendSource = 3001,
vSecureSig = byteArrayOf(0x00),
reqMedalWallInfo = 0,
vReq0x5ebFieldId = listOf(
27225, 27224, 42122, 42121, 27236,
27238, 42167, 42172, 40324, 42284,
42326, 42325, 42356, 42363, 42361,
42367, 42377, 42425, 42505, 42488
),
reqNearbyGodInfo = 1,
reqExtendCard = 1,
)
)
}
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): RespSummaryCard {
val fullMap = readJceStruct(
RequestPacket.serializer()
).sBuffer.read {
readJceStruct(RequestDataVersion2.serializer())
}.map
val map = fullMap["RespSummaryCard"] ?: error("Missing RespSummaryCard in response")
val pck = map["SummaryCard.RespSummaryCard"]
?: map["SummaryCard_Old.RespSummaryCard"]
?: error("No Response found")
val response = pck.read {
discardExact(1)
Tars.UTF_8.load(JceRespSummaryCard.serializer(), this)
}
return RespSummaryCard(
nickname = response.nick ?: "",
email = response.email ?: "",
age = response.age?.let { it.toInt() and 0xFF } ?: -1,
qLevel = response.iLevel ?: -1,
sex = when (response.sex?.let { it.toInt() and 0xFF }) {
0 -> UserProfile.Sex.MALE
1 -> UserProfile.Sex.FEMALE
else -> UserProfile.Sex.UNKNOWN
},
sign = response.sign ?: ""
)
}
}
}