From 3e6c7bc6919d9bbe7f38ec234a9d617b3b11a066 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 21 Mar 2020 14:01:00 +0800 Subject: [PATCH] Handle `StatSvc.ReqMSFOffline`, fix #150 --- .../data/jce/RequestMSFForceOffline.kt | 25 +++++++++ .../network/protocol/packet/PacketFactory.kt | 4 +- .../network/protocol/packet/login/StatSvc.kt | 55 ++++++++++++++++--- 3 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/RequestMSFForceOffline.kt diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/RequestMSFForceOffline.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/RequestMSFForceOffline.kt new file mode 100644 index 000000000..06b58ff5e --- /dev/null +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/jce/RequestMSFForceOffline.kt @@ -0,0 +1,25 @@ +package net.mamoe.mirai.qqandroid.network.protocol.data.jce + +import kotlinx.serialization.Serializable +import net.mamoe.mirai.qqandroid.io.JceStruct +import net.mamoe.mirai.qqandroid.io.serialization.jce.JceId + +@Serializable +internal class RequestMSFForceOffline( + @JceId(0) val uin: Long = 0L, + @JceId(1) val iSeqno: Long = 0L, + @JceId(2) val kickType: Byte = 0, + @JceId(3) val info: String = "", + @JceId(4) val title: String? = "", + @JceId(5) val sigKick: Byte? = 0, + @JceId(6) val vecSigKickData: ByteArray? = null, + @JceId(7) val sameDevice: Byte? = 0 +) : JceStruct + + +@Serializable +internal class RspMSFForceOffline( + @JceId(0) val uin: Long, + @JceId(1) val seq: Long, + @JceId(2) val const: Byte = 0 +) : JceStruct \ No newline at end of file diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt index dfb85b6b3..12b84dc49 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt @@ -152,8 +152,8 @@ internal object KnownPacketFactories { OnlinePush.ReqPush, OnlinePush.PbPushTransMsg, MessageSvc.PushNotify, - ConfigPushSvc.PushReq - + ConfigPushSvc.PushReq, + StatSvc.ReqMSFOffline ) // SvcReqMSFLoginNotify 自己的其他设备上限 // MessageSvc.PushReaded 电脑阅读了别人的消息, 告知手机 diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt index d4f65ae25..f142c1d9a 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt @@ -11,17 +11,17 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.login import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.event.events.BotOfflineEvent import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.io.serialization.* import net.mamoe.mirai.qqandroid.network.QQAndroidClient +import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestMSFForceOffline import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket +import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RspMSFForceOffline import net.mamoe.mirai.qqandroid.network.protocol.data.jce.SvcReqRegister import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Oidb0x769 import net.mamoe.mirai.qqandroid.network.protocol.data.proto.StatSvcGetOnline -import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket -import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory -import net.mamoe.mirai.qqandroid.network.protocol.packet.buildLoginOutgoingPacket -import net.mamoe.mirai.qqandroid.network.protocol.packet.writeSsoPacket +import net.mamoe.mirai.qqandroid.network.protocol.packet.* import net.mamoe.mirai.qqandroid.utils.NetworkType import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiPlatformUtils @@ -81,7 +81,6 @@ internal class StatSvc { } } - internal object Register : OutgoingPacketFactory("StatSvc.register") { internal object Response : Packet { @@ -140,9 +139,10 @@ internal class StatSvc { strOSVer = client.device.version.release.encodeToString(), uOldSSOIp = 0, - uNewSSOIp = MiraiPlatformUtils.localIpAddress().split(".").foldIndexed(0L) { index: Int, acc: Long, s: String -> - acc or ((s.toLong() shl (index * 16))) - }, + uNewSSOIp = MiraiPlatformUtils.localIpAddress().split(".") + .foldIndexed(0L) { index: Int, acc: Long, s: String -> + acc or ((s.toLong() shl (index * 16))) + }, strVendorName = "MIUI", strVendorOSName = "?ONEPLUS A5000_23_17", // register 时还需要 @@ -178,4 +178,43 @@ internal class StatSvc { return Response } } + + internal object ReqMSFOffline : + IncomingPacketFactory("StatSvc.ReqMSFOffline", "StatSvc.RspMSFForceOffline") { + + internal data class MsfOfflineToken( + val uin: Long, + val seq: Long, + val const: Byte + ) : Packet, RuntimeException("dropped by StatSvc.ReqMSFOffline") + + override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): BotOfflineEvent.Dropped { + val decodeUniPacket = decodeUniPacket(RequestMSFForceOffline.serializer()) + return BotOfflineEvent.Dropped(bot, MsfOfflineToken(decodeUniPacket.uin, decodeUniPacket.iSeqno, 0)) + } + + override suspend fun QQAndroidBot.handle(packet: BotOfflineEvent.Dropped, sequenceId: Int): OutgoingPacket? { + val cause = packet.cause + check(cause is MsfOfflineToken) { "internal error: handling $packet in StatSvc.ReqMSFOffline" } + return buildResponseUniPacket(client) { + writeJceStruct( + RequestPacket.serializer(), + RequestPacket( + sServantName = "StatSvc", + sFuncName = "RspMSFForceOffline", + iRequestId = 0, + sBuffer = jceRequestSBuffer( + "RspMSFForceOffline", + RspMSFForceOffline.serializer(), + RspMSFForceOffline( + cause.uin, + cause.seq, + cause.const + ) + ) + ) + ) + } + } + } }