Commit dcfe934a authored by Him188's avatar Him188

Fix missed BotOfflineEvent.Dropped. Close #376

parent 0741d484
...@@ -74,11 +74,13 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -74,11 +74,13 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
// bot 还未登录就被 close // bot 还未登录就被 close
return@subscribeAlways return@subscribeAlways
} }
if (network.areYouOk() && event !is BotOfflineEvent.Force) { /*
if (network.areYouOk() && event !is BotOfflineEvent.Force && event !is BotOfflineEvent.MsfOffline) {
// network 运行正常 // network 运行正常
return@subscribeAlways return@subscribeAlways
} }*/
when (event) { when (event) {
is BotOfflineEvent.MsfOffline,
is BotOfflineEvent.Dropped, is BotOfflineEvent.Dropped,
is BotOfflineEvent.RequireReconnect is BotOfflineEvent.RequireReconnect
-> { -> {
...@@ -105,7 +107,12 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -105,7 +107,12 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
@OptIn(ThisApiMustBeUsedInWithConnectionLockBlock::class) @OptIn(ThisApiMustBeUsedInWithConnectionLockBlock::class)
relogin((event as? BotOfflineEvent.Dropped)?.cause) relogin((event as? BotOfflineEvent.Dropped)?.cause)
} }
launch { BotReloginEvent(bot, (event as? BotOfflineEvent.Dropped)?.cause).broadcast() } launch {
BotReloginEvent(
bot,
(event as? BotOfflineEvent.CauseAware)?.cause
).broadcast()
}
return return
}.getOrElse { }.getOrElse {
if (it is LoginFailedException && !it.killBot) { if (it is LoginFailedException && !it.killBot) {
......
...@@ -96,14 +96,17 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo ...@@ -96,14 +96,17 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
private fun startHeartbeatJobOrKill(cancelCause: CancellationException? = null): Job { private fun startHeartbeatJobOrKill(cancelCause: CancellationException? = null): Job {
heartbeatJob?.cancel(cancelCause) heartbeatJob?.cancel(cancelCause)
return this@QQAndroidBotNetworkHandler.launch(CoroutineName("Heartbeat")) { return this@QQAndroidBotNetworkHandler.launch(CoroutineName("Heartbeat")) heartBeatJob@{
while (this.isActive) { while (this.isActive) {
delay(bot.configuration.heartbeatPeriodMillis) delay(bot.configuration.heartbeatPeriodMillis)
val failException = doHeartBeat() val failException = doHeartBeat()
if (failException != null) { if (failException != null) {
delay(bot.configuration.firstReconnectDelayMillis) delay(bot.configuration.firstReconnectDelayMillis)
bot.launch { BotOfflineEvent.Dropped(bot, failException).broadcast() }
return@launch bot.launch {
BotOfflineEvent.Dropped(bot, failException).broadcast()
}
return@heartBeatJob
} }
} }
}.also { heartbeatJob = it } }.also { heartbeatJob = it }
......
...@@ -182,7 +182,7 @@ internal class StatSvc { ...@@ -182,7 +182,7 @@ internal class StatSvc {
} }
internal object ReqMSFOffline : internal object ReqMSFOffline :
IncomingPacketFactory<BotOfflineEvent.Dropped>("StatSvc.ReqMSFOffline", "StatSvc.RspMSFForceOffline") { IncomingPacketFactory<BotOfflineEvent.MsfOffline>("StatSvc.ReqMSFOffline", "StatSvc.RspMSFForceOffline") {
internal data class MsfOfflineToken( internal data class MsfOfflineToken(
val uin: Long, val uin: Long,
...@@ -190,13 +190,13 @@ internal class StatSvc { ...@@ -190,13 +190,13 @@ internal class StatSvc {
val const: Byte val const: Byte
) : Packet, RuntimeException("dropped by StatSvc.ReqMSFOffline") ) : Packet, RuntimeException("dropped by StatSvc.ReqMSFOffline")
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): BotOfflineEvent.Dropped { override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): BotOfflineEvent.MsfOffline {
val decodeUniPacket = readUniPacket(RequestMSFForceOffline.serializer()) val decodeUniPacket = readUniPacket(RequestMSFForceOffline.serializer())
@Suppress("INVISIBLE_MEMBER") @Suppress("INVISIBLE_MEMBER")
return BotOfflineEvent.Dropped(bot, MsfOfflineToken(decodeUniPacket.uin, decodeUniPacket.iSeqno, 0)) return BotOfflineEvent.MsfOffline(bot, MsfOfflineToken(decodeUniPacket.uin, decodeUniPacket.iSeqno, 0))
} }
override suspend fun QQAndroidBot.handle(packet: BotOfflineEvent.Dropped, sequenceId: Int): OutgoingPacket? { override suspend fun QQAndroidBot.handle(packet: BotOfflineEvent.MsfOffline, sequenceId: Int): OutgoingPacket? {
val cause = packet.cause val cause = packet.cause
check(cause is MsfOfflineToken) { "internal error: handling $packet in StatSvc.ReqMSFOffline" } check(cause is MsfOfflineToken) { "internal error: handling $packet in StatSvc.ReqMSFOffline" }
return buildResponseUniPacket(client) { return buildResponseUniPacket(client) {
......
...@@ -16,6 +16,9 @@ package net.mamoe.mirai.event.events ...@@ -16,6 +16,9 @@ package net.mamoe.mirai.event.events
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.AbstractEvent import net.mamoe.mirai.event.AbstractEvent
import net.mamoe.mirai.qqandroid.network.Packet import net.mamoe.mirai.qqandroid.network.Packet
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.SinceMirai
import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
...@@ -35,7 +38,8 @@ sealed class BotOfflineEvent : BotEvent, AbstractEvent() { ...@@ -35,7 +38,8 @@ sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
/** /**
* 主动离线. 主动广播这个事件也可以让 [Bot] 关闭. * 主动离线. 主动广播这个事件也可以让 [Bot] 关闭.
*/ */
data class Active(override val bot: Bot, val cause: Throwable?) : BotOfflineEvent(), BotActiveEvent data class Active(override val bot: Bot, override val cause: Throwable?) : BotOfflineEvent(), BotActiveEvent,
CauseAware
/** /**
* 被挤下线 * 被挤下线
...@@ -45,15 +49,31 @@ sealed class BotOfflineEvent : BotEvent, AbstractEvent() { ...@@ -45,15 +49,31 @@ sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
BotPassiveEvent BotPassiveEvent
/** /**
* 被服务器断开或因网络问题而掉线 * 被服务器断开
*/ */
data class Dropped internal constructor(override val bot: Bot, val cause: Throwable?) : BotOfflineEvent(), Packet, @SinceMirai("1.1.0")
BotPassiveEvent @MiraiInternalAPI("This is very experimental and might be changed")
data class MsfOffline internal constructor(override val bot: Bot, override val cause: Throwable?) :
BotOfflineEvent(), Packet,
BotPassiveEvent, CauseAware
/**
* 因网络问题而掉线
*/
data class Dropped internal constructor(override val bot: Bot, override val cause: Throwable?) : BotOfflineEvent(),
Packet,
BotPassiveEvent, CauseAware
/** /**
* 服务器主动要求更换另一个服务器 * 服务器主动要求更换另一个服务器
*/ */
@MiraiInternalAPI
data class RequireReconnect internal constructor(override val bot: Bot) : BotOfflineEvent(), Packet, BotPassiveEvent data class RequireReconnect internal constructor(override val bot: Bot) : BotOfflineEvent(), Packet, BotPassiveEvent
@MiraiExperimentalAPI
interface CauseAware {
val cause: Throwable?
}
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment