mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-05 10:52:26 +08:00
Close bot if first login failed
This commit is contained in:
parent
35a6d12dde
commit
95d634233c
@ -165,6 +165,9 @@ public inline fun <E> MutableList<E>.replaceAllKotlin(operator: (E) -> E) {
|
||||
}
|
||||
}
|
||||
|
||||
public fun systemProp(name: String, default: String): String =
|
||||
System.getProperty(name, default) ?: default
|
||||
|
||||
public fun systemProp(name: String, default: Boolean): Boolean =
|
||||
System.getProperty(name, default.toString())?.toBoolean() ?: default
|
||||
|
||||
|
@ -21,6 +21,7 @@ import net.mamoe.mirai.internal.contact.info.FriendInfoImpl
|
||||
import net.mamoe.mirai.internal.contact.info.StrangerInfoImpl
|
||||
import net.mamoe.mirai.internal.contact.uin
|
||||
import net.mamoe.mirai.internal.network.component.ConcurrentComponentStorage
|
||||
import net.mamoe.mirai.internal.network.components.SsoProcessor
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler
|
||||
import net.mamoe.mirai.internal.network.impl.netty.asCoroutineExceptionHandler
|
||||
import net.mamoe.mirai.supervisorJob
|
||||
@ -110,11 +111,18 @@ internal abstract class AbstractBot constructor(
|
||||
// network
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
val network: NetworkHandler by lazy { createNetworkHandler() }
|
||||
val network: NetworkHandler by lazy { createNetworkHandler() } // the selector handles renewal of [NetworkHandler]
|
||||
|
||||
final override suspend fun login() {
|
||||
if (!isActive) error("Bot is already closed and cannot relogin. Please create a new Bot instance then do login.")
|
||||
network.resumeConnection()
|
||||
try {
|
||||
network.resumeConnection()
|
||||
} catch (e: Throwable) { // failed to init
|
||||
if (!components[SsoProcessor].firstLoginSucceed) {
|
||||
this.close() // failed to do first login.
|
||||
}
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun createNetworkHandler(): NetworkHandler
|
||||
|
@ -51,12 +51,25 @@ internal fun Bot.asQQAndroidBot(): QQAndroidBot {
|
||||
}
|
||||
|
||||
internal class BotDebugConfiguration(
|
||||
var stateObserver: StateObserver? = when {
|
||||
systemProp("mirai.debug.network.state.observer.logging", false) ->
|
||||
var stateObserver: StateObserver? = when (systemProp(
|
||||
"mirai.debug.network.state.observer.logging",
|
||||
"off"
|
||||
).toLowerCase()) {
|
||||
"full" -> {
|
||||
SafeStateObserver(
|
||||
LoggingStateObserver(MiraiLogger.create("States")),
|
||||
LoggingStateObserver(MiraiLogger.create("States"), true),
|
||||
MiraiLogger.create("LoggingStateObserver errors")
|
||||
)
|
||||
}
|
||||
"off", "false" -> {
|
||||
null
|
||||
}
|
||||
"on", "true" -> {
|
||||
SafeStateObserver(
|
||||
LoggingStateObserver(MiraiLogger.create("States"), false),
|
||||
MiraiLogger.create("LoggingStateObserver errors")
|
||||
)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
)
|
||||
@ -69,6 +82,14 @@ internal open class QQAndroidBot constructor(
|
||||
) : AbstractBot(configuration, account.id) {
|
||||
override val bot: QQAndroidBot get() = this
|
||||
|
||||
|
||||
@Deprecated(
|
||||
"",
|
||||
replaceWith = ReplaceWith(
|
||||
"this.components[SsoProcessor].firstLoginSucceed",
|
||||
"net.mamoe.mirai.internal.network.components.SsoProcessor"
|
||||
)
|
||||
)
|
||||
internal var firstLoginSucceed: Boolean = false
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -85,7 +106,7 @@ internal open class QQAndroidBot constructor(
|
||||
StateChangedObserver(to = State.OK) { new ->
|
||||
bot.launch(logger.asCoroutineExceptionHandler()) {
|
||||
BotOnlineEvent(bot).broadcast()
|
||||
if (bot.firstLoginSucceed) { // TODO: 2021/4/21 actually no use
|
||||
if (bot.components[SsoProcessor].firstLoginSucceed) { // TODO: 2021/4/21 actually no use
|
||||
BotReloginEvent(bot, new.getCause()).broadcast()
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ internal class BotInitProcessorImpl(
|
||||
launch { context[ContactUpdater].loadAll(registerResp.origin) }
|
||||
}
|
||||
|
||||
bot.firstLoginSucceed = true
|
||||
bot.components[SsoProcessor].firstLoginSucceed = true
|
||||
}
|
||||
|
||||
private suspend fun registerClientOnline(): StatSvc.Register.Response {
|
||||
|
@ -10,8 +10,10 @@
|
||||
package net.mamoe.mirai.internal.network.components
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.selects.select
|
||||
import kotlinx.coroutines.yield
|
||||
import net.mamoe.mirai.event.ConcurrencyKind
|
||||
import net.mamoe.mirai.event.EventPriority
|
||||
import net.mamoe.mirai.event.events.BotOfflineEvent
|
||||
@ -19,17 +21,27 @@ import net.mamoe.mirai.event.subscribeAlways
|
||||
import net.mamoe.mirai.internal.QQAndroidBot
|
||||
import net.mamoe.mirai.internal.asQQAndroidBot
|
||||
import net.mamoe.mirai.internal.network.component.ComponentKey
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State
|
||||
import net.mamoe.mirai.utils.castOrNull
|
||||
import net.mamoe.mirai.utils.info
|
||||
import net.mamoe.mirai.utils.toHumanReadableString
|
||||
import kotlin.time.measureTime
|
||||
|
||||
/**
|
||||
* Handles [BotOfflineEvent]
|
||||
*/
|
||||
internal interface BotOfflineEventMonitor {
|
||||
companion object : ComponentKey<BotOfflineEventMonitor>
|
||||
|
||||
/**
|
||||
* Attach a listener to the [scope]. [scope] is usually the scope of [NetworkHandler.State.OK].
|
||||
*/
|
||||
fun attachJob(bot: QQAndroidBot, scope: CoroutineScope)
|
||||
}
|
||||
|
||||
private data class BotClosedByEvent(val event: BotOfflineEvent) : RuntimeException("Bot is closed by event '$event'.")
|
||||
|
||||
internal class BotOfflineEventMonitorImpl : BotOfflineEventMonitor {
|
||||
override fun attachJob(bot: QQAndroidBot, scope: CoroutineScope) {
|
||||
bot.eventChannel.parentScope(scope).subscribeAlways(
|
||||
@ -39,38 +51,37 @@ internal class BotOfflineEventMonitorImpl : BotOfflineEventMonitor {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: 2021/4/25 Review BotOfflineEventMonitor
|
||||
private suspend fun onEvent(event: BotOfflineEvent) {
|
||||
private suspend fun onEvent(event: BotOfflineEvent) = coroutineScope {
|
||||
val bot = event.bot.asQQAndroidBot()
|
||||
val network = bot.network
|
||||
if (
|
||||
!event.bot.isActive // bot closed
|
||||
// || _isConnecting // bot 还在登入 // TODO: 2021/4/14 处理还在登入?
|
||||
) {
|
||||
// Close network to avoid endless reconnection while network is ok
|
||||
// https://github.com/mamoe/mirai/issues/894
|
||||
kotlin.runCatching { network.close(null) }
|
||||
return
|
||||
|
||||
fun closeNetwork() {
|
||||
if (network.state == State.CLOSED) return // avoid recursive calls.
|
||||
launch {
|
||||
// suspend until state becomes CLOSED to hang [onEvent] for synchronization.
|
||||
while (select { network.onStateChanged { it != State.CLOSED } }) yield()
|
||||
}
|
||||
bot.launch { network.close(BotClosedByEvent(event)) }
|
||||
}
|
||||
/*
|
||||
if (network.areYouOk() && event !is BotOfflineEvent.Force && event !is BotOfflineEvent.MsfOffline) {
|
||||
// network 运行正常
|
||||
return@subscribeAlways
|
||||
}*/
|
||||
|
||||
when (event) {
|
||||
is BotOfflineEvent.Active -> {
|
||||
// This event might also be broadcast by the network handler by a state observer.
|
||||
// In that case, `network.state` will be `CLOSED` then `closeNetwork` returns immediately.
|
||||
// So there won't be recursive calls.
|
||||
|
||||
val cause = event.cause
|
||||
val msg = if (cause == null) "" else " with exception: $cause"
|
||||
bot.logger.info("Bot is closed manually $msg", cause)
|
||||
network.close(null)
|
||||
|
||||
closeNetwork()
|
||||
}
|
||||
is BotOfflineEvent.Force -> {
|
||||
bot.logger.info { "Connection occupied by another android device: ${event.message}" }
|
||||
closeNetwork()
|
||||
if (event.reconnect) {
|
||||
bot.logger.info { "Reconnecting..." }
|
||||
// delay(3000)
|
||||
} else {
|
||||
network.close(null)
|
||||
}
|
||||
}
|
||||
is BotOfflineEvent.MsfOffline,
|
||||
@ -82,11 +93,6 @@ internal class BotOfflineEventMonitorImpl : BotOfflineEventMonitor {
|
||||
}
|
||||
|
||||
if (event.reconnect) {
|
||||
if (!network.isOk()) {
|
||||
// normally closed
|
||||
return
|
||||
}
|
||||
|
||||
val causeMessage = event.castOrNull<BotOfflineEvent.CauseAware>()?.cause?.toString() ?: event.toString()
|
||||
bot.logger.info { "Connection lost, retrying login ($causeMessage)." }
|
||||
|
||||
@ -94,8 +100,8 @@ internal class BotOfflineEventMonitorImpl : BotOfflineEventMonitor {
|
||||
val success: Boolean
|
||||
val time = measureTime {
|
||||
success = kotlin.runCatching {
|
||||
bot.login()
|
||||
}.isSuccess // resume connection
|
||||
bot.login() // selector will create new NH to replace the old, closed one, with some further comprehensive considerations. For example, limitation for attempts.
|
||||
}.isSuccess
|
||||
}
|
||||
|
||||
if (success) {
|
||||
|
@ -45,6 +45,8 @@ internal interface SsoProcessor {
|
||||
val client: QQAndroidClient
|
||||
val ssoSession: SsoSession
|
||||
|
||||
var firstLoginSucceed: Boolean
|
||||
|
||||
/**
|
||||
* The observers to launch jobs for states.
|
||||
*
|
||||
@ -78,6 +80,8 @@ internal class SsoProcessorImpl(
|
||||
// public
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
override var firstLoginSucceed: Boolean = false
|
||||
|
||||
@Volatile
|
||||
override var client = createClient(ssoContext.bot)
|
||||
|
||||
@ -111,6 +115,7 @@ internal class SsoProcessorImpl(
|
||||
SlowLoginImpl(handler).doLogin()
|
||||
}
|
||||
ssoContext.accountSecretsManager.saveSecrets(ssoContext.account, AccountSecretsImpl(client))
|
||||
ssoContext.bot.logger.info { "Login successful." }
|
||||
}
|
||||
|
||||
override suspend fun logout(handler: NetworkHandler) {
|
||||
|
@ -98,9 +98,10 @@ internal interface NetworkHandler {
|
||||
OK,
|
||||
|
||||
/**
|
||||
* The terminal state. Cannot resume anymore. Both [resumeConnection] and [sendAndExpect] throw a [IllegalStateException].
|
||||
* The terminal state. Both [resumeConnection] and [sendAndExpect] throw a [IllegalStateException].
|
||||
*
|
||||
* When a handler reached [CLOSED] state, it is finalized and cannot be restored to any other states.
|
||||
* **Important nodes**: if [NetworkHandler] is [SelectorNetworkHandler], it might return to a normal state e.g. [INITIALIZED] if new instance of [NetworkHandler] is created.
|
||||
* However callers usually do not need to pay extra attention on this behavior. Everything will just work fine if you consider [CLOSED] as a final, non-recoverable state.
|
||||
*
|
||||
* At this state [resumeConnection] throws the exception caught from underlying socket implementation (i.e netty).
|
||||
* [sendAndExpect] throws [IllegalStateException].
|
||||
|
@ -15,7 +15,8 @@ import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.debug
|
||||
|
||||
internal class LoggingStateObserver(
|
||||
val logger: MiraiLogger
|
||||
val logger: MiraiLogger,
|
||||
private val showStacktrace: Boolean = false
|
||||
) : StateObserver {
|
||||
override fun toString(): String {
|
||||
return "LoggingStateObserver"
|
||||
@ -26,7 +27,10 @@ internal class LoggingStateObserver(
|
||||
previous: NetworkHandlerSupport.BaseStateImpl,
|
||||
new: NetworkHandlerSupport.BaseStateImpl
|
||||
) {
|
||||
logger.debug { "State changed: ${previous.correspondingState} -> ${new.correspondingState}" }
|
||||
logger.debug(
|
||||
{ "State changed: ${previous.correspondingState} -> ${new.correspondingState}" },
|
||||
if (showStacktrace) Exception("Show stacktrace") else null
|
||||
)
|
||||
}
|
||||
|
||||
override fun exceptionOnCreatingNewState(
|
||||
@ -34,7 +38,7 @@ internal class LoggingStateObserver(
|
||||
previousState: NetworkHandlerSupport.BaseStateImpl,
|
||||
exception: Throwable
|
||||
) {
|
||||
logger.debug({ "State changed: ${previousState.correspondingState} -> $exception" }, exception)
|
||||
logger.debug { "State changed: ${previousState.correspondingState} -> $exception" }
|
||||
}
|
||||
|
||||
override fun beforeStateResume(networkHandler: NetworkHandler, state: NetworkHandlerSupport.BaseStateImpl) {
|
||||
|
@ -36,6 +36,7 @@ import net.mamoe.mirai.internal.message.toMessageChainOnline
|
||||
import net.mamoe.mirai.internal.network.MultiPacket
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.internal.network.QQAndroidClient
|
||||
import net.mamoe.mirai.internal.network.components.SsoProcessor
|
||||
import net.mamoe.mirai.internal.network.handler.logger
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.FrdSysMsg
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
|
||||
@ -378,7 +379,7 @@ internal suspend fun MsgComm.Msg.transform(bot: QQAndroidBot, fromSync: Boolean
|
||||
}
|
||||
return null
|
||||
}
|
||||
if (!bot.firstLoginSucceed) {
|
||||
if (!bot.components[SsoProcessor].firstLoginSucceed) {
|
||||
return null
|
||||
}
|
||||
val fromUin = if (fromSync) {
|
||||
@ -483,7 +484,7 @@ internal suspend fun MsgComm.Msg.transform(bot: QQAndroidBot, fromSync: Boolean
|
||||
}
|
||||
141 -> {
|
||||
|
||||
if (!bot.firstLoginSucceed || msgHead.fromUin == bot.id && !fromSync) {
|
||||
if (!bot.components[SsoProcessor].firstLoginSucceed || msgHead.fromUin == bot.id && !fromSync) {
|
||||
return null
|
||||
}
|
||||
val tmpHead = msgHead.c2cTmpMsgHead ?: return null
|
||||
|
@ -26,6 +26,7 @@ import net.mamoe.mirai.internal.contact.info.MemberInfoImpl
|
||||
import net.mamoe.mirai.internal.contact.newAnonymous
|
||||
import net.mamoe.mirai.internal.message.toMessageChainOnline
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.internal.network.components.SsoProcessor
|
||||
import net.mamoe.mirai.internal.network.handler.logger
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
|
||||
@ -70,7 +71,7 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory<Packet?>("Onlin
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): Packet? {
|
||||
// 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00
|
||||
if (!bot.firstLoginSucceed) return null
|
||||
if (!bot.components[SsoProcessor].firstLoginSucceed) return null
|
||||
val pbPushMsg = readProtoBuf(MsgOnlinePush.PbPushMsg.serializer())
|
||||
|
||||
val msgHead = pbPushMsg.msg.msgHead
|
||||
|
@ -71,6 +71,7 @@ internal abstract class AbstractRealNetworkHandlerTest<H : NetworkHandler> : Abs
|
||||
set(SsoProcessor, object : SsoProcessor {
|
||||
override val client: QQAndroidClient get() = bot.client
|
||||
override val ssoSession: SsoSession get() = bot.client
|
||||
override var firstLoginSucceed: Boolean = false
|
||||
override fun createObserverChain(): StateObserver = get(StateObserver)
|
||||
override suspend fun login(handler: NetworkHandler) {
|
||||
nhEvents.add(NHEvent.Login)
|
||||
|
@ -13,7 +13,11 @@ import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.event.events.BotOfflineEvent
|
||||
import net.mamoe.mirai.internal.MockBot
|
||||
import net.mamoe.mirai.internal.network.components.BotOfflineEventMonitor
|
||||
import net.mamoe.mirai.internal.network.components.BotOfflineEventMonitorImpl
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State.*
|
||||
import net.mamoe.mirai.internal.test.runBlockingUnit
|
||||
import net.mamoe.mirai.supervisorJob
|
||||
@ -24,6 +28,29 @@ import kotlin.test.assertTrue
|
||||
|
||||
internal class NettyBotLifecycleTest : AbstractNettyNHTest() {
|
||||
|
||||
@Test
|
||||
fun `closed on Force offline with BotOfflineEventMonitor`() = runBlockingUnit {
|
||||
defaultComponents[BotOfflineEventMonitor] = BotOfflineEventMonitorImpl()
|
||||
bot.login()
|
||||
assertState(OK)
|
||||
BotOfflineEvent.Force(bot, "test", "test").broadcast()
|
||||
assertState(CLOSED)
|
||||
assertFalse { network.isActive }
|
||||
assertTrue { bot.isActive }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `closed on Active offline with BotOfflineEventMonitor`() = runBlockingUnit {
|
||||
defaultComponents[BotOfflineEventMonitor] = BotOfflineEventMonitorImpl()
|
||||
bot.login()
|
||||
assertState(OK)
|
||||
BotOfflineEvent.Active(bot, null).broadcast()
|
||||
assertState(CLOSED)
|
||||
assertFalse { network.isActive }
|
||||
assertTrue { bot.isActive }
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun `send logout on exit`() = runBlockingUnit {
|
||||
assertState(INITIALIZED)
|
||||
|
@ -14,6 +14,7 @@ import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.event.events.BotOfflineEvent
|
||||
import net.mamoe.mirai.event.events.BotOnlineEvent
|
||||
import net.mamoe.mirai.event.events.BotReloginEvent
|
||||
import net.mamoe.mirai.internal.network.components.SsoProcessor
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State.INITIALIZED
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State.OK
|
||||
@ -40,7 +41,7 @@ internal class NettyHandlerEventTest : AbstractNettyNHTest() {
|
||||
assertEventBroadcasts<BotReloginEvent> {
|
||||
assertEquals(INITIALIZED, network.state)
|
||||
bot.login()
|
||||
bot.firstLoginSucceed = true
|
||||
bot.components[SsoProcessor].firstLoginSucceed = true
|
||||
network.setStateConnecting()
|
||||
network.resumeConnection()
|
||||
delay(3.seconds) // `login` launches a job which broadcasts the event
|
||||
@ -52,7 +53,7 @@ internal class NettyHandlerEventTest : AbstractNettyNHTest() {
|
||||
fun `BotOnlineEvent after successful reconnection`() = runBlockingUnit {
|
||||
assertEquals(INITIALIZED, network.state)
|
||||
bot.login()
|
||||
bot.firstLoginSucceed = true
|
||||
bot.components[SsoProcessor].firstLoginSucceed = true
|
||||
assertEquals(OK, network.state)
|
||||
delay(3.seconds) // `login` launches a job which broadcasts the event
|
||||
assertEventBroadcasts<BotOnlineEvent>(1) {
|
||||
@ -67,7 +68,7 @@ internal class NettyHandlerEventTest : AbstractNettyNHTest() {
|
||||
fun `BotOfflineEvent after successful reconnection`() = runBlockingUnit {
|
||||
assertEquals(INITIALIZED, network.state)
|
||||
bot.login()
|
||||
bot.firstLoginSucceed = true
|
||||
bot.components[SsoProcessor].firstLoginSucceed = true
|
||||
assertEquals(OK, network.state)
|
||||
delay(3.seconds) // `login` launches a job which broadcasts the event
|
||||
assertEventBroadcasts<BotOfflineEvent>(1) {
|
||||
@ -81,7 +82,7 @@ internal class NettyHandlerEventTest : AbstractNettyNHTest() {
|
||||
private fun noEventOn(setState: () -> Unit) = runBlockingUnit {
|
||||
assertState(INITIALIZED)
|
||||
bot.login()
|
||||
bot.firstLoginSucceed = true
|
||||
bot.components[SsoProcessor].firstLoginSucceed = true
|
||||
assertState(OK)
|
||||
network.setStateConnecting()
|
||||
delay(3.seconds) // `login` launches a job which broadcasts the event
|
||||
|
Loading…
Reference in New Issue
Block a user