Fix network not reconnect when received ReqMSFOffline

This commit is contained in:
Karlatemp 2021-07-18 23:13:47 +08:00
parent b74b6da8a3
commit 2a641415a7
2 changed files with 23 additions and 9 deletions

View File

@ -42,6 +42,7 @@ import net.mamoe.mirai.internal.network.handler.state.StateObserver
import net.mamoe.mirai.internal.network.handler.state.safe import net.mamoe.mirai.internal.network.handler.state.safe
import net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException import net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException
import net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandlerFactory import net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandlerFactory
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
import net.mamoe.mirai.internal.utils.subLogger import net.mamoe.mirai.internal.utils.subLogger
import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
@ -119,6 +120,9 @@ internal open class QQAndroidBot constructor(
cause is ForceOfflineException -> { cause is ForceOfflineException -> {
eventDispatcher.broadcastAsync(BotOfflineEvent.Force(bot, cause.title, cause.message)) eventDispatcher.broadcastAsync(BotOfflineEvent.Force(bot, cause.title, cause.message))
} }
cause is StatSvc.ReqMSFOffline.MsfOfflineToken -> {
eventDispatcher.broadcastAsync(BotOfflineEvent.MsfOffline(bot, cause))
}
cause is NetworkException && cause.recoverable -> { cause is NetworkException && cause.recoverable -> {
eventDispatcher.broadcastAsync(BotOfflineEvent.Dropped(bot, cause)) eventDispatcher.broadcastAsync(BotOfflineEvent.Dropped(bot, cause))
} }

View File

@ -20,7 +20,6 @@ import net.mamoe.mirai.contact.ClientKind
import net.mamoe.mirai.contact.OtherClientInfo import net.mamoe.mirai.contact.OtherClientInfo
import net.mamoe.mirai.contact.Platform import net.mamoe.mirai.contact.Platform
import net.mamoe.mirai.data.OnlineStatus import net.mamoe.mirai.data.OnlineStatus
import net.mamoe.mirai.event.events.BotOfflineEvent
import net.mamoe.mirai.event.events.OtherClientOfflineEvent import net.mamoe.mirai.event.events.OtherClientOfflineEvent
import net.mamoe.mirai.event.events.OtherClientOnlineEvent import net.mamoe.mirai.event.events.OtherClientOnlineEvent
import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.QQAndroidBot
@ -31,6 +30,7 @@ import net.mamoe.mirai.internal.network.*
import net.mamoe.mirai.internal.network.components.ContactCacheService import net.mamoe.mirai.internal.network.components.ContactCacheService
import net.mamoe.mirai.internal.network.components.ContactUpdater import net.mamoe.mirai.internal.network.components.ContactUpdater
import net.mamoe.mirai.internal.network.components.ServerList import net.mamoe.mirai.internal.network.components.ServerList
import net.mamoe.mirai.internal.network.handler.selector.NetworkException
import net.mamoe.mirai.internal.network.impl.netty.HeartbeatFailedException import net.mamoe.mirai.internal.network.impl.netty.HeartbeatFailedException
import net.mamoe.mirai.internal.network.protocol.data.jce.* import net.mamoe.mirai.internal.network.protocol.data.jce.*
import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0x769 import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0x769
@ -268,24 +268,29 @@ internal class StatSvc {
} }
internal object ReqMSFOffline : internal object ReqMSFOffline :
IncomingPacketFactory<BotOfflineEvent.MsfOffline>("StatSvc.ReqMSFOffline", "StatSvc.RspMSFForceOffline") { IncomingPacketFactory<ReqMSFOffline.MsfOfflinePacket>("StatSvc.ReqMSFOffline", "StatSvc.RspMSFForceOffline") {
internal class MsfOfflinePacket(
val token: MsfOfflineToken,
) : Packet {
override fun toString(): String = "StatSvc.ReqMSFOffline"
}
internal data class MsfOfflineToken( internal data class MsfOfflineToken(
val uin: Long, val uin: Long,
val seq: Long, val seq: Long,
val const: Byte val const: Byte
) : Packet, RuntimeException("dropped by StatSvc.ReqMSFOffline") ) : Packet, NetworkException("dropped by StatSvc.ReqMSFOffline", true)
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): BotOfflineEvent.MsfOffline { override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): MsfOfflinePacket {
val decodeUniPacket = readUniPacket(RequestMSFForceOffline.serializer()) val decodeUniPacket = readUniPacket(RequestMSFForceOffline.serializer())
@Suppress("INVISIBLE_MEMBER") @Suppress("INVISIBLE_MEMBER")
return BotOfflineEvent.MsfOffline(bot, MsfOfflineToken(decodeUniPacket.uin, decodeUniPacket.iSeqno, 0)) return MsfOfflinePacket(MsfOfflineToken(decodeUniPacket.uin, decodeUniPacket.iSeqno, 0))
} }
override suspend fun QQAndroidBot.handle(packet: BotOfflineEvent.MsfOffline, sequenceId: Int): OutgoingPacket { override suspend fun QQAndroidBot.handle(packet: MsfOfflinePacket, sequenceId: Int): OutgoingPacket? {
val cause = packet.cause val cause = packet.token
check(cause is MsfOfflineToken) { "internal error: handling $packet in StatSvc.ReqMSFOffline" } val resp = buildResponseUniPacket(client) {
return buildResponseUniPacket(client) {
writeJceStruct( writeJceStruct(
RequestPacket.serializer(), RequestPacket.serializer(),
RequestPacket( RequestPacket(
@ -304,6 +309,11 @@ internal class StatSvc {
) )
) )
} }
kotlin.runCatching {
bot.network.sendWithoutExpect(resp)
}
bot.network.close(cause)
return null
} }
} }