diff --git a/mirai-core-utils/src/commonMain/kotlin/StandardUtils.kt b/mirai-core-utils/src/commonMain/kotlin/StandardUtils.kt index f99ba6ff6..854a23d01 100644 --- a/mirai-core-utils/src/commonMain/kotlin/StandardUtils.kt +++ b/mirai-core-utils/src/commonMain/kotlin/StandardUtils.kt @@ -165,6 +165,9 @@ public inline fun MutableList.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 diff --git a/mirai-core/src/commonMain/kotlin/AbstractBot.kt b/mirai-core/src/commonMain/kotlin/AbstractBot.kt index 161f1442f..3d2b654bb 100644 --- a/mirai-core/src/commonMain/kotlin/AbstractBot.kt +++ b/mirai-core/src/commonMain/kotlin/AbstractBot.kt @@ -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 diff --git a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt index bc5771876..78f56f089 100644 --- a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt +++ b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt @@ -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() } } diff --git a/mirai-core/src/commonMain/kotlin/network/components/BotInitProcessor.kt b/mirai-core/src/commonMain/kotlin/network/components/BotInitProcessor.kt index afad57e78..53bbe44ac 100644 --- a/mirai-core/src/commonMain/kotlin/network/components/BotInitProcessor.kt +++ b/mirai-core/src/commonMain/kotlin/network/components/BotInitProcessor.kt @@ -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 { diff --git a/mirai-core/src/commonMain/kotlin/network/components/BotOfflineEventMonitor.kt b/mirai-core/src/commonMain/kotlin/network/components/BotOfflineEventMonitor.kt index 071dc9901..527ae4a06 100644 --- a/mirai-core/src/commonMain/kotlin/network/components/BotOfflineEventMonitor.kt +++ b/mirai-core/src/commonMain/kotlin/network/components/BotOfflineEventMonitor.kt @@ -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 + /** + * 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()?.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) { diff --git a/mirai-core/src/commonMain/kotlin/network/components/SsoProcessor.kt b/mirai-core/src/commonMain/kotlin/network/components/SsoProcessor.kt index 4fa1bb483..f1a76d2d5 100644 --- a/mirai-core/src/commonMain/kotlin/network/components/SsoProcessor.kt +++ b/mirai-core/src/commonMain/kotlin/network/components/SsoProcessor.kt @@ -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) { diff --git a/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt index f80b209ae..0496a1e9a 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt @@ -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]. diff --git a/mirai-core/src/commonMain/kotlin/network/handler/state/LoggingStateObserver.kt b/mirai-core/src/commonMain/kotlin/network/handler/state/LoggingStateObserver.kt index 585e8b4b3..7f4e6927f 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/state/LoggingStateObserver.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/state/LoggingStateObserver.kt @@ -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) { diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt index f0b815a8f..0fc32e77d 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt @@ -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 diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt index 3fa42d353..ebbb2c3b5 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt @@ -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("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 diff --git a/mirai-core/src/commonTest/kotlin/network/framework/AbstractRealNetworkHandlerTest.kt b/mirai-core/src/commonTest/kotlin/network/framework/AbstractRealNetworkHandlerTest.kt index c39031538..e0368e49d 100644 --- a/mirai-core/src/commonTest/kotlin/network/framework/AbstractRealNetworkHandlerTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/framework/AbstractRealNetworkHandlerTest.kt @@ -71,6 +71,7 @@ internal abstract class AbstractRealNetworkHandlerTest : 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) diff --git a/mirai-core/src/commonTest/kotlin/network/impl/netty/NettyBotLifecycleTest.kt b/mirai-core/src/commonTest/kotlin/network/impl/netty/NettyBotLifecycleTest.kt index 962dda102..6b0735dd7 100644 --- a/mirai-core/src/commonTest/kotlin/network/impl/netty/NettyBotLifecycleTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/impl/netty/NettyBotLifecycleTest.kt @@ -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) diff --git a/mirai-core/src/commonTest/kotlin/network/impl/netty/NettyHandlerEventTest.kt b/mirai-core/src/commonTest/kotlin/network/impl/netty/NettyHandlerEventTest.kt index 335c0f4b2..365d0e737 100644 --- a/mirai-core/src/commonTest/kotlin/network/impl/netty/NettyHandlerEventTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/impl/netty/NettyHandlerEventTest.kt @@ -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 { 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(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(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