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.impl.netty.ForceOfflineException
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.utils.BotConfiguration
import net.mamoe.mirai.utils.MiraiLogger
@ -119,6 +120,9 @@ internal open class QQAndroidBot constructor(
cause is ForceOfflineException -> {
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 -> {
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.Platform
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.OtherClientOnlineEvent
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.ContactUpdater
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.protocol.data.jce.*
import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0x769
@ -268,24 +268,29 @@ internal class StatSvc {
}
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(
val uin: Long,
val seq: Long,
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())
@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 {
val cause = packet.cause
check(cause is MsfOfflineToken) { "internal error: handling $packet in StatSvc.ReqMSFOffline" }
return buildResponseUniPacket(client) {
override suspend fun QQAndroidBot.handle(packet: MsfOfflinePacket, sequenceId: Int): OutgoingPacket? {
val cause = packet.token
val resp = buildResponseUniPacket(client) {
writeJceStruct(
RequestPacket.serializer(),
RequestPacket(
@ -304,6 +309,11 @@ internal class StatSvc {
)
)
}
kotlin.runCatching {
bot.network.sendWithoutExpect(resp)
}
bot.network.close(cause)
return null
}
}