mirror of
https://github.com/mamoe/mirai.git
synced 2024-12-31 05:09:15 +08:00
Add BotOfflineEvent.reconnect
, support auto-reconnect control.
AbstractBot.offlineListener is now MONITOR
This commit is contained in:
parent
44053ae85f
commit
95e6ca4c7a
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
* 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.
|
||||
@ -34,6 +34,10 @@ public data class BotOnlineEvent internal constructor(
|
||||
* [Bot] 离线.
|
||||
*/
|
||||
public sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
|
||||
/**
|
||||
* 为 `true` 时会尝试重连. 仅 [BotOfflineEvent.Force] 默认为 `false`, 其他默认为 `true`.
|
||||
*/
|
||||
public open val reconnect: Boolean get() = true
|
||||
|
||||
/**
|
||||
* 主动离线. 主动广播这个事件也可以让 [Bot] 关闭.
|
||||
@ -41,16 +45,20 @@ public sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
|
||||
public data class Active(
|
||||
public override val bot: Bot,
|
||||
public override val cause: Throwable?
|
||||
) : BotOfflineEvent(), BotActiveEvent, CauseAware
|
||||
) : BotOfflineEvent(), BotActiveEvent, CauseAware {
|
||||
override val reconnect: Boolean get() = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 被挤下线
|
||||
* 被挤下线. 默认不会自动重连. 可将 [reconnect] 改为 `true` 以重连.
|
||||
*/
|
||||
public data class Force internal constructor(
|
||||
public override val bot: Bot,
|
||||
public val title: String,
|
||||
public val message: String
|
||||
) : BotOfflineEvent(), Packet, BotPassiveEvent
|
||||
public val message: String,
|
||||
) : BotOfflineEvent(), Packet, BotPassiveEvent {
|
||||
override var reconnect: Boolean = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 被服务器断开
|
||||
@ -59,7 +67,9 @@ public sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
|
||||
public data class MsfOffline internal constructor(
|
||||
public override val bot: Bot,
|
||||
public override val cause: Throwable?
|
||||
) : BotOfflineEvent(), Packet, BotPassiveEvent, CauseAware
|
||||
) : BotOfflineEvent(), Packet, BotPassiveEvent, CauseAware {
|
||||
override var reconnect: Boolean = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 因网络问题而掉线
|
||||
@ -67,7 +77,9 @@ public sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
|
||||
public data class Dropped internal constructor(
|
||||
public override val bot: Bot,
|
||||
public override val cause: Throwable?
|
||||
) : BotOfflineEvent(), Packet, BotPassiveEvent, CauseAware
|
||||
) : BotOfflineEvent(), Packet, BotPassiveEvent, CauseAware {
|
||||
override var reconnect: Boolean = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 因 returnCode = -10008 等原因掉线
|
||||
@ -77,7 +89,9 @@ public sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
|
||||
val returnCode: Int,
|
||||
public override val bot: Bot,
|
||||
public override val cause: Throwable
|
||||
) : BotOfflineEvent(), Packet, BotPassiveEvent, CauseAware
|
||||
) : BotOfflineEvent(), Packet, BotPassiveEvent, CauseAware {
|
||||
override var reconnect: Boolean = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务器主动要求更换另一个服务器
|
||||
@ -85,8 +99,9 @@ public sealed class BotOfflineEvent : BotEvent, AbstractEvent() {
|
||||
@MiraiInternalApi
|
||||
public data class RequireReconnect internal constructor(
|
||||
public override val bot: Bot
|
||||
) : BotOfflineEvent(), Packet,
|
||||
BotPassiveEvent
|
||||
) : BotOfflineEvent(), Packet, BotPassiveEvent {
|
||||
override var reconnect: Boolean = true
|
||||
}
|
||||
|
||||
@MiraiExperimentalApi
|
||||
public interface CauseAware {
|
||||
|
@ -23,6 +23,7 @@ import kotlinx.coroutines.sync.Mutex
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.OtherClientList
|
||||
import net.mamoe.mirai.event.*
|
||||
import net.mamoe.mirai.event.Listener.EventPriority.MONITOR
|
||||
import net.mamoe.mirai.event.events.BotEvent
|
||||
import net.mamoe.mirai.event.events.BotOfflineEvent
|
||||
import net.mamoe.mirai.event.events.BotReloginEvent
|
||||
@ -91,7 +92,10 @@ internal abstract class AbstractBot<N : BotNetworkHandler> constructor(
|
||||
@OptIn(ExperimentalTime::class)
|
||||
@Suppress("unused")
|
||||
private val offlineListener: Listener<BotOfflineEvent> =
|
||||
this@AbstractBot.eventChannel.subscribeAlways(concurrency = Listener.ConcurrencyKind.LOCKED) { event ->
|
||||
this@AbstractBot.eventChannel.subscribeAlways(
|
||||
priority = MONITOR,
|
||||
concurrency = Listener.ConcurrencyKind.LOCKED
|
||||
) { event ->
|
||||
if (!event.bot.isActive) {
|
||||
// bot closed
|
||||
return@subscribeAlways
|
||||
@ -110,30 +114,6 @@ internal abstract class AbstractBot<N : BotNetworkHandler> constructor(
|
||||
return@subscribeAlways
|
||||
}*/
|
||||
when (event) {
|
||||
is BotOfflineEvent.MsfOffline,
|
||||
is BotOfflineEvent.Dropped,
|
||||
is BotOfflineEvent.RequireReconnect,
|
||||
is BotOfflineEvent.PacketFactoryErrorCode
|
||||
-> {
|
||||
if (!_network.isActive) {
|
||||
// normally closed
|
||||
return@subscribeAlways
|
||||
}
|
||||
bot.logger.info { "Connection lost, retrying login" }
|
||||
|
||||
bot.asQQAndroidBot().client.run {
|
||||
if (serverList.isEmpty()) {
|
||||
serverList.addAll(DefaultServerList)
|
||||
} else serverList.removeAt(0)
|
||||
}
|
||||
|
||||
val success: Boolean
|
||||
val time = measureTime { success = Reconnect().reconnect(event) }
|
||||
|
||||
if (success) {
|
||||
logger.info { "Reconnected successfully in ${time.toHumanReadableString()}" }
|
||||
}
|
||||
}
|
||||
is BotOfflineEvent.Active -> {
|
||||
val cause = event.cause
|
||||
val msg = if (cause == null) {
|
||||
@ -146,7 +126,37 @@ internal abstract class AbstractBot<N : BotNetworkHandler> constructor(
|
||||
}
|
||||
is BotOfflineEvent.Force -> {
|
||||
bot.logger.info { "Connection occupied by another android device: ${event.message}" }
|
||||
bot.cancel(ForceOfflineException("Connection occupied by another android device: ${event.message}"))
|
||||
if (!event.reconnect) {
|
||||
bot.cancel(ForceOfflineException("Connection occupied by another android device: ${event.message}"))
|
||||
}
|
||||
}
|
||||
is BotOfflineEvent.MsfOffline,
|
||||
is BotOfflineEvent.Dropped,
|
||||
is BotOfflineEvent.RequireReconnect,
|
||||
is BotOfflineEvent.PacketFactoryErrorCode
|
||||
-> {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
if (event.reconnect) {
|
||||
if (!_network.isActive) {
|
||||
// normally closed
|
||||
return@subscribeAlways
|
||||
}
|
||||
bot.logger.info { "Connection lost, retrying login" }
|
||||
|
||||
bot.asQQAndroidBot().client.run {
|
||||
if (serverList.isEmpty()) {
|
||||
serverList.addAll(DefaultServerList)
|
||||
} else serverList.removeAt(0)
|
||||
}
|
||||
|
||||
val success: Boolean
|
||||
val time = measureTime { success = Reconnect().reconnect(event) }
|
||||
|
||||
if (success) {
|
||||
logger.info { "Reconnected successfully in ${time.toHumanReadableString()}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user