From 05b2bfe0593442c0acca3cb622dfbf0cbd1b5069 Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Sat, 17 Apr 2021 13:39:59 +0800 Subject: [PATCH] Rearrange packages --- .../src/commonMain/kotlin/AbstractBot.kt | 19 +-- .../src/commonMain/kotlin/QQAndroidBot.kt | 61 ++------ .../commonMain/kotlin/contact/AbstractUser.kt | 2 +- .../commonMain/kotlin/contact/GroupImpl.kt | 2 +- .../kotlin/network/QQAndroidClient.kt | 3 +- .../kotlin/network/handler/NetworkHandler.kt | 33 +---- .../{impl => }/NetworkHandlerSupport.kt | 24 ++-- .../network/handler/SelectorNetworkHandler.kt | 132 ------------------ .../components}/AccountSecretsManager.kt | 4 +- .../{ => components}/BdhSessionSyncer.kt | 62 ++++---- .../components}/ContactUpdater.kt | 4 +- .../components}/PacketDecoder.kt | 3 +- .../handler/{ => components}/ServerList.kt | 6 +- .../components}/SsoProcessor.kt | 44 ++---- .../network/handler/components/package.kt | 13 ++ .../{ => handler/context}/AccountSecrets.kt | 5 +- .../network/handler/context/BdhSession.kt | 21 +++ .../handler/context/NetworkHandlerContext.kt | 41 ++++++ .../handler/context/SsoProcessorContext.kt | 47 +++++++ .../context}/SsoSession.kt | 5 +- .../kotlin/network/handler/context/package.kt | 13 ++ .../handler/impl/netty/NettyNetworkHandler.kt | 10 +- ...ctory.kt => NettyNetworkHandlerFactory.kt} | 2 +- ...AbstractKeepAliveNetworkHandlerSelector.kt | 61 ++++++++ .../ExceptionInSelectorResumeException.kt | 14 ++ .../FactoryKeepAliveNetworkHandlerSelector.kt | 27 ++++ .../selector/NetworkHandlerSelector.kt | 32 +++++ .../selector/NoServerAvailableException.kt | 13 ++ .../selector/SelectorNetworkHandler.kt | 48 +++++++ .../handler/state/CombinedStateObserver.kt | 54 +++++++ .../ExceptionInStateObserverException.kt | 14 ++ .../handler/state/LoggingStateObserver.kt | 57 ++++++++ .../SafeStateObserver.kt} | 88 +----------- .../network/handler/state/StateObserver.kt | 51 +++++++ .../kotlin/network/highway/Highway.kt | 2 +- .../network/protocol/packet/PacketFactory.kt | 4 +- .../network/protocol/packet/chat/MultiMsg.kt | 2 +- .../protocol/packet/login/ConfigPushSvc.kt | 8 +- .../kotlin/network/ServerListTest.kt | 4 +- ...ractKeepAliveNetworkHandlerSelectorTest.kt | 1 + .../kotlin/network/handler/testUtils.kt | 12 +- .../commonTest/kotlin/network/sessionUtils.kt | 4 +- 42 files changed, 625 insertions(+), 427 deletions(-) rename mirai-core/src/commonMain/kotlin/network/handler/{impl => }/NetworkHandlerSupport.kt (91%) delete mode 100644 mirai-core/src/commonMain/kotlin/network/handler/SelectorNetworkHandler.kt rename mirai-core/src/commonMain/kotlin/network/{ => handler/components}/AccountSecretsManager.kt (95%) rename mirai-core/src/commonMain/kotlin/network/handler/{ => components}/BdhSessionSyncer.kt (61%) rename mirai-core/src/commonMain/kotlin/network/{ => handler/components}/ContactUpdater.kt (98%) rename mirai-core/src/commonMain/kotlin/network/{net/protocol => handler/components}/PacketDecoder.kt (98%) rename mirai-core/src/commonMain/kotlin/network/handler/{ => components}/ServerList.kt (94%) rename mirai-core/src/commonMain/kotlin/network/{net/protocol => handler/components}/SsoProcessor.kt (89%) create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/components/package.kt rename mirai-core/src/commonMain/kotlin/network/{ => handler/context}/AccountSecrets.kt (92%) create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/context/BdhSession.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/context/NetworkHandlerContext.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/context/SsoProcessorContext.kt rename mirai-core/src/commonMain/kotlin/network/{net/protocol => handler/context}/SsoSession.kt (81%) create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/context/package.kt rename mirai-core/src/commonMain/kotlin/network/handler/impl/netty/{NetyNetworkHandlerFactory.kt => NettyNetworkHandlerFactory.kt} (91%) create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/selector/AbstractKeepAliveNetworkHandlerSelector.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/selector/ExceptionInSelectorResumeException.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/selector/FactoryKeepAliveNetworkHandlerSelector.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/selector/NetworkHandlerSelector.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/selector/NoServerAvailableException.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/selector/SelectorNetworkHandler.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/state/CombinedStateObserver.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/state/ExceptionInStateObserverException.kt create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/state/LoggingStateObserver.kt rename mirai-core/src/commonMain/kotlin/network/handler/{impl/StateObserver.kt => state/SafeStateObserver.kt} (53%) create mode 100644 mirai-core/src/commonMain/kotlin/network/handler/state/StateObserver.kt diff --git a/mirai-core/src/commonMain/kotlin/AbstractBot.kt b/mirai-core/src/commonMain/kotlin/AbstractBot.kt index 3298eee55..30e169ea7 100644 --- a/mirai-core/src/commonMain/kotlin/AbstractBot.kt +++ b/mirai-core/src/commonMain/kotlin/AbstractBot.kt @@ -22,15 +22,18 @@ import kotlinx.coroutines.sync.Mutex import net.mamoe.mirai.Bot import net.mamoe.mirai.Mirai import net.mamoe.mirai.contact.* -import net.mamoe.mirai.event.* +import net.mamoe.mirai.event.ConcurrencyKind +import net.mamoe.mirai.event.EventChannel import net.mamoe.mirai.event.EventPriority.MONITOR +import net.mamoe.mirai.event.GlobalEventChannel +import net.mamoe.mirai.event.Listener import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.event.events.BotOfflineEvent 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.handler.NetworkHandler -import net.mamoe.mirai.internal.network.handler.ServerList +import net.mamoe.mirai.internal.network.handler.components.ServerList import net.mamoe.mirai.supervisorJob import net.mamoe.mirai.utils.* import kotlin.coroutines.CoroutineContext @@ -169,21 +172,11 @@ internal abstract class AbstractBot constructor( // network /////////////////////////////////////////////////////////////////////////// - internal val serverList: MutableList<Pair<String, Int>> = mutableListOf() // TODO: 2021/4/16 remove old internal val serverListNew = ServerList() // TODO: 2021/4/16 load server list from cache (add a provider) // bot.bdhSyncer.loadServerListFromCache() - // TODO: 2021/4/14 handle serverList + val network: NetworkHandler by lazy { createNetworkHandler(coroutineContext) } - val network: NetworkHandler by lazy { - createNetworkHandler(coroutineContext) - } - - - /** - * **Exposed public API** - * [AbstractBot.relogin] && [BotNetworkHandler.init] - */ 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() diff --git a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt index d4cd5a2f5..d98b361fd 100644 --- a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt +++ b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt @@ -19,22 +19,22 @@ import net.mamoe.mirai.internal.contact.OtherClientImpl import net.mamoe.mirai.internal.contact.checkIsGroupImpl import net.mamoe.mirai.internal.network.* import net.mamoe.mirai.internal.network.handler.* -import net.mamoe.mirai.internal.network.handler.impl.LoggingStateObserver -import net.mamoe.mirai.internal.network.handler.impl.SafeStateObserver -import net.mamoe.mirai.internal.network.handler.impl.StateObserver +import net.mamoe.mirai.internal.network.handler.components.BdhSessionSyncer +import net.mamoe.mirai.internal.network.handler.components.SsoProcessor +import net.mamoe.mirai.internal.network.handler.context.NetworkHandlerContextImpl +import net.mamoe.mirai.internal.network.handler.context.SsoProcessorContextImpl import net.mamoe.mirai.internal.network.handler.impl.netty.NettyNetworkHandlerFactory -import net.mamoe.mirai.internal.network.net.protocol.SsoProcessor -import net.mamoe.mirai.internal.network.net.protocol.SsoProcessorContextImpl +import net.mamoe.mirai.internal.network.handler.selector.FactoryKeepAliveNetworkHandlerSelector +import net.mamoe.mirai.internal.network.handler.selector.SelectorNetworkHandler +import net.mamoe.mirai.internal.network.handler.state.LoggingStateObserver +import net.mamoe.mirai.internal.network.handler.state.SafeStateObserver +import net.mamoe.mirai.internal.network.handler.state.StateObserver import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketWithRespType import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc -import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin import net.mamoe.mirai.internal.utils.ScheduledJob -import net.mamoe.mirai.internal.utils.crypto.TEA import net.mamoe.mirai.internal.utils.friendCacheFile -import net.mamoe.mirai.internal.utils.io.serialization.toByteArray import net.mamoe.mirai.utils.* -import java.io.File import kotlin.contracts.contract import kotlin.coroutines.CoroutineContext @@ -71,7 +71,7 @@ internal class QQAndroidBot constructor( ) : AbstractBot(configuration, account.id) { override val bot: QQAndroidBot get() = this - val bdhSyncer: BdhSessionSyncer = BdhSessionSyncer(this) + val bdhSyncer: BdhSessionSyncer by lazy { BdhSessionSyncer(configuration, serverListNew, network.logger) } internal var firstLoginSucceed: Boolean = false /////////////////////////////////////////////////////////////////////////// @@ -180,45 +180,4 @@ internal class QQAndroidBot constructor( bot.network.context.logger.info { "Saved ${friendListCache.list.size} friends to local cache." } } } - - /////////////////////////////////////////////////////////////////////////// - // Account secrets cache - /////////////////////////////////////////////////////////////////////////// - - // We cannot extract these logics until we rewrite the network framework. - - private val cacheDir: File by lazy { - configuration.workingDir.resolve(bot.configuration.cacheDir).apply { mkdirs() } - } - private val accountSecretsFile: File by lazy { - cacheDir.resolve("account.secrets") - } - - private fun saveSecrets(secrets: AccountSecretsImpl) { - if (secrets.wLoginSigInfoField == null) return - - accountSecretsFile.writeBytes( - TEA.encrypt( - secrets.toByteArray(AccountSecretsImpl.serializer()), - account.passwordMd5 - ) - ) - - network.context.logger.info { "Saved account secrets to local cache for fast login." } - } - - init { - if (configuration.loginCacheEnabled) { - eventChannel.parentScope(this).subscribeAlways<WtLogin.Login.LoginPacketResponse> { event -> - if (event is WtLogin.Login.LoginPacketResponse.Success) { - if (client.wLoginSigInfoInitialized) { - saveSecrets(AccountSecretsImpl(client)) - } - } - } - } - } - - /////////////////////////// accounts secrets end - } diff --git a/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt b/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt index efa03a2a1..eb4b5acfe 100644 --- a/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt +++ b/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt @@ -18,7 +18,7 @@ import net.mamoe.mirai.event.events.* import net.mamoe.mirai.internal.message.OfflineFriendImage import net.mamoe.mirai.internal.message.contextualBugReportException import net.mamoe.mirai.internal.message.getImageType -import net.mamoe.mirai.internal.network.handler.BdhSession +import net.mamoe.mirai.internal.network.handler.context.BdhSession import net.mamoe.mirai.internal.network.highway.ChannelKind import net.mamoe.mirai.internal.network.highway.Highway import net.mamoe.mirai.internal.network.highway.ResourceKind.PRIVATE_IMAGE diff --git a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt index 379549321..f80538ee2 100644 --- a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt @@ -22,8 +22,8 @@ import net.mamoe.mirai.event.events.* import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.contact.info.MemberInfoImpl import net.mamoe.mirai.internal.message.OfflineGroupImage -import net.mamoe.mirai.internal.network.handler.BdhSession import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.context.BdhSession import net.mamoe.mirai.internal.network.highway.ChannelKind import net.mamoe.mirai.internal.network.highway.Highway import net.mamoe.mirai.internal.network.highway.ResourceKind.GROUP_IMAGE diff --git a/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt b/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt index 3ef9d28ce..7d180ff64 100644 --- a/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt +++ b/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt @@ -19,7 +19,8 @@ import kotlinx.io.core.toByteArray import net.mamoe.mirai.data.OnlineStatus import net.mamoe.mirai.internal.BotAccount import net.mamoe.mirai.internal.QQAndroidBot -import net.mamoe.mirai.internal.network.net.protocol.SsoSession +import net.mamoe.mirai.internal.network.handler.context.AccountSecrets +import net.mamoe.mirai.internal.network.handler.context.SsoSession import net.mamoe.mirai.internal.network.protocol.SyncingCacheList import net.mamoe.mirai.internal.network.protocol.data.jce.FileStoragePushFSSvcList import net.mamoe.mirai.internal.network.protocol.packet.Tlv diff --git a/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt index 274063889..fb6a656ac 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandler.kt @@ -9,12 +9,9 @@ package net.mamoe.mirai.internal.network.handler -import net.mamoe.mirai.Bot -import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.handler.NetworkHandler.State -import net.mamoe.mirai.internal.network.handler.impl.StateObserver -import net.mamoe.mirai.internal.network.net.protocol.SsoProcessor +import net.mamoe.mirai.internal.network.handler.context.NetworkHandlerContext import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketWithRespType import net.mamoe.mirai.utils.MiraiLogger @@ -23,34 +20,12 @@ import java.net.InetSocketAddress import java.net.SocketAddress import java.util.concurrent.CancellationException -/** - * Immutable context for [NetworkHandler] - */ -internal interface NetworkHandlerContext { - val bot: QQAndroidBot - // however migration requires a major change. - - val logger: MiraiLogger - val ssoProcessor: SsoProcessor - - val stateObserver: StateObserver? -} - -internal class NetworkHandlerContextImpl( - override val bot: QQAndroidBot, - override val ssoProcessor: SsoProcessor, - override val logger: MiraiLogger, - override val stateObserver: StateObserver?, -) : NetworkHandlerContext { - override fun toString(): String { - return "NetworkHandlerContextImpl(bot=${bot.id}, stateObserver=$stateObserver)" - } -} - /** * Basic interface available to application. Usually wrapped with [SelectorNetworkHandler]. * - * A [NetworkHandler] holds no reference to [Bot]s. + * Implementation is usually subclass of [NetworkHandlerSupport]. + * + * @see NetworkHandlerSupport */ internal interface NetworkHandler { val context: NetworkHandlerContext diff --git a/mirai-core/src/commonMain/kotlin/network/handler/impl/NetworkHandlerSupport.kt b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandlerSupport.kt similarity index 91% rename from mirai-core/src/commonMain/kotlin/network/handler/impl/NetworkHandlerSupport.kt rename to mirai-core/src/commonMain/kotlin/network/handler/NetworkHandlerSupport.kt index 974a4ff62..26db0eaa0 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/impl/NetworkHandlerSupport.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/NetworkHandlerSupport.kt @@ -7,22 +7,22 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network.handler.impl +package net.mamoe.mirai.internal.network.handler import kotlinx.coroutines.* import net.mamoe.mirai.internal.network.Packet -import net.mamoe.mirai.internal.network.handler.NetworkHandler -import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext -import net.mamoe.mirai.internal.network.handler.logger -import net.mamoe.mirai.internal.network.net.protocol.PacketCodec.PACKET_DEBUG -import net.mamoe.mirai.internal.network.net.protocol.RawIncomingPacket +import net.mamoe.mirai.internal.network.handler.components.PacketCodec +import net.mamoe.mirai.internal.network.handler.components.RawIncomingPacket +import net.mamoe.mirai.internal.network.handler.context.NetworkHandlerContext import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacket import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket import net.mamoe.mirai.utils.* import java.util.concurrent.ConcurrentLinkedQueue import kotlin.coroutines.CoroutineContext - +/** + * Implements basic logics of [NetworkHandler] + */ internal abstract class NetworkHandlerSupport( override val context: NetworkHandlerContext, final override val coroutineContext: CoroutineContext = SupervisorJob(), @@ -95,7 +95,7 @@ internal abstract class NetworkHandlerSupport( } protected val packetLogger: MiraiLogger by lazy { - MiraiLogger.create(context.logger.identity + ".debug").withSwitch(PACKET_DEBUG) + MiraiLogger.create(context.logger.identity + ".debug").withSwitch(PacketCodec.PACKET_DEBUG) } /////////////////////////////////////////////////////////////////////////// @@ -173,9 +173,9 @@ internal abstract class NetworkHandlerSupport( } /** - * You may need to call [BaseStateImpl.resumeConnection] since state is lazy. + * Calculate [new state][new] and set it as the current. * - * Do not check for instances of [BaseStateImpl]. Instances may be decorated by [StateObserver] for extended functionality. + * You may need to call [BaseStateImpl.resumeConnection] to activate the new state, as states are lazy. */ protected inline fun <S : BaseStateImpl> setState(crossinline new: () -> S): S = synchronized(this) { // we can add hooks here for debug. @@ -200,6 +200,4 @@ internal abstract class NetworkHandlerSupport( final override suspend fun resumeConnection() { _state.resumeConnection() } -} - - +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/SelectorNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/handler/SelectorNetworkHandler.kt deleted file mode 100644 index 1d0d812e6..000000000 --- a/mirai-core/src/commonMain/kotlin/network/handler/SelectorNetworkHandler.kt +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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. - * - * https://github.com/mamoe/mirai/blob/master/LICENSE - */ - -package net.mamoe.mirai.internal.network.handler - -import kotlinx.atomicfu.atomic -import net.mamoe.mirai.internal.network.handler.NetworkHandler.State -import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket -import org.jetbrains.annotations.TestOnly - -/** - * A proxy to [NetworkHandler] that delegates calls to instance returned by [NetworkHandlerSelector.awaitResumeInstance]. - * - * [NetworkHandlerSelector.awaitResumeInstance] is called everytime when an operation in [NetworkHandler] is called. - * - * This is useful to implement a delegation of [NetworkHandler]. The functionality of *selection* is provided by the strategy [selector][NetworkHandlerSelector]. - * @see NetworkHandlerSelector - */ -internal class SelectorNetworkHandler( - override val context: NetworkHandlerContext, // impl notes: may consider to move into function member. - private val selector: NetworkHandlerSelector<*>, -) : NetworkHandler { - private suspend inline fun instance(): NetworkHandler = selector.awaitResumeInstance() - - override val state: State - get() = selector.getResumedInstance()?.state ?: State.INITIALIZED - - override suspend fun resumeConnection() { - instance() // the selector will resume connection for us. - } - - override suspend fun sendAndExpect(packet: OutgoingPacket, timeout: Long, attempts: Int) = - instance().sendAndExpect(packet, timeout, attempts) - - override suspend fun sendWithoutExpect(packet: OutgoingPacket) = instance().sendWithoutExpect(packet) - override fun close(cause: Throwable?) { - selector.getResumedInstance()?.close(cause) - } - - override fun toString(): String = "SelectorNetworkHandler(currentInstance=${selector.getResumedInstance()})" -} - -internal class ExceptionInSelectorResumeException( - cause: Throwable -) : RuntimeException(cause) - -/** - * A lazy stateful selector of [NetworkHandler]. This is used as a director([selector][SelectorNetworkHandler.selector]) to [SelectorNetworkHandler]. - */ -internal interface NetworkHandlerSelector<H : NetworkHandler> { - /** - * Returns an instance immediately without suspension, or `null` if instance not ready. - * - * This function should not throw any exception. - * @see awaitResumeInstance - */ - fun getResumedInstance(): H? - - /** - * Returns an alive [NetworkHandler], or suspends the coroutine until the connection has been made again. - * - * This function may throw exceptions, which would be propagated to the original caller of [SelectorNetworkHandler.resumeConnection]. - */ - suspend fun awaitResumeInstance(): H -} - -/** - * A lazy stateful implementation of [NetworkHandlerSelector]. - * - * - Calls [factory.create][NetworkHandlerFactory.create] to create [NetworkHandler]s. - * - Re-initialize [NetworkHandler] instances if the old one is dead. - * - Suspends requests when connection is not available. - * - * No connection is created until first invocation of [getResumedInstance], - * and new connections are created only when calling [getResumedInstance] if the old connection was dead. - */ -// may be replaced with a better name. -internal abstract class AbstractKeepAliveNetworkHandlerSelector<H : NetworkHandler> : NetworkHandlerSelector<H> { - private val current = atomic<H?>(null) - - @TestOnly - internal fun setCurrent(h: H) { - current.value = h - } - - protected abstract fun createInstance(): H - - final override fun getResumedInstance(): H? = current.value - - final override tailrec suspend fun awaitResumeInstance(): H { - val current = getResumedInstance() - return if (current != null) { - when (current.state) { - State.CLOSED -> { - this.current.compareAndSet(current, null) // invalidate the instance and try again. - awaitResumeInstance() // will create new instance. - } - State.CONNECTING, - State.CONNECTION_LOST, - State.INITIALIZED, - State.OK -> { - current.resumeConnection() - return current - } - } - } else { - this.current.compareAndSet(current, createInstance()) - awaitResumeInstance() - } - } -} - -/** - * [AbstractKeepAliveNetworkHandlerSelector] implementation delegating [createInstance] to [factory] - */ -internal class FactoryKeepAliveNetworkHandlerSelector<H : NetworkHandler>( - private val factory: NetworkHandlerFactory<H>, - private val serverList: ServerList, - private val context: NetworkHandlerContext, -) : AbstractKeepAliveNetworkHandlerSelector<H>() { - override fun createInstance(): H = - factory.create(context, serverList.pollCurrent()?.toSocketAddress() ?: throw NoServerAvailableException()) -} - -internal class NoServerAvailableException : - NoSuchElementException("No server available. (Failed to connect to any of the servers)") \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/AccountSecretsManager.kt b/mirai-core/src/commonMain/kotlin/network/handler/components/AccountSecretsManager.kt similarity index 95% rename from mirai-core/src/commonMain/kotlin/network/AccountSecretsManager.kt rename to mirai-core/src/commonMain/kotlin/network/handler/components/AccountSecretsManager.kt index 3d4765b97..0603d0fad 100644 --- a/mirai-core/src/commonMain/kotlin/network/AccountSecretsManager.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/components/AccountSecretsManager.kt @@ -7,10 +7,12 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network +package net.mamoe.mirai.internal.network.handler.components import net.mamoe.mirai.Bot import net.mamoe.mirai.internal.BotAccount +import net.mamoe.mirai.internal.network.handler.context.AccountSecrets +import net.mamoe.mirai.internal.network.handler.context.AccountSecretsImpl import net.mamoe.mirai.internal.utils.actualCacheDir import net.mamoe.mirai.internal.utils.crypto.TEA import net.mamoe.mirai.internal.utils.io.serialization.loadAs diff --git a/mirai-core/src/commonMain/kotlin/network/handler/BdhSessionSyncer.kt b/mirai-core/src/commonMain/kotlin/network/handler/components/BdhSessionSyncer.kt similarity index 61% rename from mirai-core/src/commonMain/kotlin/network/handler/BdhSessionSyncer.kt rename to mirai-core/src/commonMain/kotlin/network/handler/components/BdhSessionSyncer.kt index 229e68c85..c78d16c63 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/BdhSessionSyncer.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/components/BdhSessionSyncer.kt @@ -7,32 +7,28 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network.handler +package net.mamoe.mirai.internal.network.handler.components import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.builtins.ListSerializer -import net.mamoe.mirai.internal.QQAndroidBot +import kotlinx.serialization.builtins.SetSerializer import net.mamoe.mirai.internal.network.JsonForCache import net.mamoe.mirai.internal.network.ProtoBufForCache +import net.mamoe.mirai.internal.network.handler.context.BdhSession import net.mamoe.mirai.internal.utils.actualCacheDir +import net.mamoe.mirai.utils.BotConfiguration +import net.mamoe.mirai.utils.MiraiLogger import java.io.File -import java.util.concurrent.CopyOnWriteArraySet -@Serializable -private data class ServerHostAndPort( - val host: String, - val port: Int, -) - -private val ServerListSerializer: KSerializer<List<ServerHostAndPort>> = - ListSerializer(ServerHostAndPort.serializer()) +private val ServerListSerializer: KSerializer<Set<ServerAddress>> = + SetSerializer(ServerAddress.serializer()) @OptIn(ExperimentalCoroutinesApi::class) internal class BdhSessionSyncer( - private val bot: QQAndroidBot + private val configuration: BotConfiguration, + private val serverList: ServerList, + private val logger: MiraiLogger, ) { var bdhSession: CompletableDeferred<BdhSession> = CompletableDeferred() val hasSession: Boolean @@ -50,30 +46,29 @@ internal class BdhSessionSyncer( } private val sessionCacheFile: File - get() = bot.configuration.actualCacheDir().resolve("session.bin") + get() = configuration.actualCacheDir().resolve("session.bin") private val serverListCacheFile: File - get() = bot.configuration.actualCacheDir().resolve("servers.json") + get() = configuration.actualCacheDir().resolve("servers.json") fun loadServerListFromCache() { val serverListCacheFile = this.serverListCacheFile if (serverListCacheFile.isFile) { - bot.network.logger.verbose("Loading server list from cache.") + logger.verbose("Loading server list from cache.") kotlin.runCatching { val list = JsonForCache.decodeFromString(ServerListSerializer, serverListCacheFile.readText()) - bot.serverList.clear() - bot.serverList.addAll(list.map { it.host to it.port }) + serverList.setPreferred(list.map { ServerAddress(it.host, it.port) }) }.onFailure { - bot.network.logger.warning("Error in loading server list from cache", it) + logger.warning("Error in loading server list from cache", it) } } else { - bot.network.logger.verbose("No server list cached.") + logger.verbose("No server list cached.") } } fun loadFromCache() { val sessionCacheFile = this.sessionCacheFile if (sessionCacheFile.isFile) { - bot.network.logger.verbose("Loading BdhSession from cache file") + logger.verbose("Loading BdhSession from cache file") kotlin.runCatching { overrideSession( ProtoBufForCache.decodeFromByteArray(BdhSession.serializer(), sessionCacheFile.readBytes()), @@ -81,10 +76,10 @@ internal class BdhSessionSyncer( ) }.onFailure { kotlin.runCatching { sessionCacheFile.delete() } - bot.network.logger.warning("Error in loading BdhSession from cache", it) + logger.warning("Error in loading BdhSession from cache", it) } } else { - bot.network.logger.verbose("No BdhSession cache") + logger.verbose("No BdhSession cache") } } @@ -92,16 +87,16 @@ internal class BdhSessionSyncer( val serverListCacheFile = this.serverListCacheFile serverListCacheFile.parentFile?.mkdirs() - bot.network.logger.verbose("Saving server list to cache") + logger.verbose("Saving server list to cache") kotlin.runCatching { serverListCacheFile.writeText( JsonForCache.encodeToString( ServerListSerializer, - bot.serverList.map { ServerHostAndPort(it.first, it.second) } + serverList.getPreferred() ) ) }.onFailure { - bot.network.logger.warning("Error in saving ServerList to cache.", it) + logger.warning("Error in saving ServerList to cache.", it) } } @@ -109,7 +104,7 @@ internal class BdhSessionSyncer( val sessionCacheFile = this.sessionCacheFile sessionCacheFile.parentFile?.mkdirs() if (bdhSession.isCompleted) { - bot.network.logger.verbose("Saving bdh session to cache") + logger.verbose("Saving bdh session to cache") kotlin.runCatching { sessionCacheFile.writeBytes( ProtoBufForCache.encodeToByteArray( @@ -118,20 +113,13 @@ internal class BdhSessionSyncer( ) ) }.onFailure { - bot.network.logger.warning("Error in saving BdhSession to cache.", it) + logger.warning("Error in saving BdhSession to cache.", it) } } else { sessionCacheFile.delete() - bot.network.logger.verbose("No BdhSession to save to cache") + logger.verbose("No BdhSession to save to cache") } } } -@Serializable -internal class BdhSession( - val sigSession: ByteArray, - val sessionKey: ByteArray, - var ssoAddresses: MutableSet<Pair<Int, Int>> = CopyOnWriteArraySet(), - var otherAddresses: MutableSet<Pair<Int, Int>> = CopyOnWriteArraySet(), -) \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/ContactUpdater.kt b/mirai-core/src/commonMain/kotlin/network/handler/components/ContactUpdater.kt similarity index 98% rename from mirai-core/src/commonMain/kotlin/network/ContactUpdater.kt rename to mirai-core/src/commonMain/kotlin/network/handler/components/ContactUpdater.kt index 961d162d6..28d0bd686 100644 --- a/mirai-core/src/commonMain/kotlin/network/ContactUpdater.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/components/ContactUpdater.kt @@ -7,7 +7,7 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network +package net.mamoe.mirai.internal.network.handler.components import kotlinx.coroutines.CancellationException import kotlinx.coroutines.cancel @@ -27,7 +27,9 @@ import net.mamoe.mirai.internal.contact.info.GroupInfoImpl import net.mamoe.mirai.internal.contact.info.MemberInfoImpl import net.mamoe.mirai.internal.contact.info.StrangerInfoImpl import net.mamoe.mirai.internal.contact.toMiraiFriendInfo +import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.handler.logger +import net.mamoe.mirai.internal.network.isValid import net.mamoe.mirai.internal.network.protocol.data.jce.StTroopNum import net.mamoe.mirai.internal.network.protocol.data.jce.SvcRespRegister import net.mamoe.mirai.internal.network.protocol.data.jce.isValid diff --git a/mirai-core/src/commonMain/kotlin/network/net/protocol/PacketDecoder.kt b/mirai-core/src/commonMain/kotlin/network/handler/components/PacketDecoder.kt similarity index 98% rename from mirai-core/src/commonMain/kotlin/network/net/protocol/PacketDecoder.kt rename to mirai-core/src/commonMain/kotlin/network/handler/components/PacketDecoder.kt index 8389fdc8b..2e03e8b2a 100644 --- a/mirai-core/src/commonMain/kotlin/network/net/protocol/PacketDecoder.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/components/PacketDecoder.kt @@ -7,10 +7,11 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network.net.protocol +package net.mamoe.mirai.internal.network.handler.components import kotlinx.io.core.* import net.mamoe.mirai.internal.QQAndroidBot +import net.mamoe.mirai.internal.network.handler.context.SsoSession import net.mamoe.mirai.internal.network.protocol.packet.* import net.mamoe.mirai.internal.utils.crypto.TEA import net.mamoe.mirai.internal.utils.crypto.adjustToPublicKey diff --git a/mirai-core/src/commonMain/kotlin/network/handler/ServerList.kt b/mirai-core/src/commonMain/kotlin/network/handler/components/ServerList.kt similarity index 94% rename from mirai-core/src/commonMain/kotlin/network/handler/ServerList.kt rename to mirai-core/src/commonMain/kotlin/network/handler/components/ServerList.kt index b78757616..c1a3566a8 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/ServerList.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/components/ServerList.kt @@ -7,11 +7,13 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network.handler +package net.mamoe.mirai.internal.network.handler.components +import kotlinx.serialization.Serializable import java.net.InetSocketAddress import java.util.* +@Serializable internal data class ServerAddress( val host: String, val port: Int @@ -42,6 +44,8 @@ internal class ServerList( preferred = list.toSet() } + fun getPreferred() = preferred + init { refresh() } diff --git a/mirai-core/src/commonMain/kotlin/network/net/protocol/SsoProcessor.kt b/mirai-core/src/commonMain/kotlin/network/handler/components/SsoProcessor.kt similarity index 89% rename from mirai-core/src/commonMain/kotlin/network/net/protocol/SsoProcessor.kt rename to mirai-core/src/commonMain/kotlin/network/handler/components/SsoProcessor.kt index 0e2827123..97392f45c 100644 --- a/mirai-core/src/commonMain/kotlin/network/net/protocol/SsoProcessor.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/components/SsoProcessor.kt @@ -7,12 +7,15 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network.net.protocol +package net.mamoe.mirai.internal.network.handler.components -import net.mamoe.mirai.internal.BotAccount import net.mamoe.mirai.internal.QQAndroidBot -import net.mamoe.mirai.internal.network.* +import net.mamoe.mirai.internal.network.Packet +import net.mamoe.mirai.internal.network.QQAndroidClient import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.context.AccountSecretsImpl +import net.mamoe.mirai.internal.network.handler.context.SsoProcessorContext +import net.mamoe.mirai.internal.network.handler.context.SsoSession import net.mamoe.mirai.internal.network.handler.impl.netty.NettyNetworkHandler import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketWithRespType import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin.Login.LoginPacketResponse @@ -23,34 +26,10 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin20 import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.WtLogin9 import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect import net.mamoe.mirai.network.* -import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.BotConfiguration.MiraiProtocol - -/** - * Provides the information needed by the [SsoProcessor]. - */ -internal interface SsoProcessorContext { - val bot: QQAndroidBot - - val account: BotAccount - val device: DeviceInfo - - val protocol: MiraiProtocol - - val accountSecretsManager: AccountSecretsManager - - val configuration: BotConfiguration -} - -internal class SsoProcessorContextImpl( - override val bot: QQAndroidBot -) : SsoProcessorContext { - override val account: BotAccount get() = bot.account - override val device: DeviceInfo = configuration.deviceInfo?.invoke(bot) ?: DeviceInfo.random() - override val protocol: MiraiProtocol get() = configuration.protocol - override val accountSecretsManager: AccountSecretsManager get() = configuration.createAccountsSecretsManager(bot.logger) - override val configuration: BotConfiguration get() = bot.configuration -} +import net.mamoe.mirai.utils.LoginSolver +import net.mamoe.mirai.utils.info +import net.mamoe.mirai.utils.withExceptionCollector /** * Strategy that performs the process of single sing-on (SSO). (login) @@ -60,7 +39,7 @@ internal class SsoProcessorContextImpl( * Used by [NettyNetworkHandler.StateConnecting]. */ internal class SsoProcessor( - private val ssoContext: SsoProcessorContext, + internal val ssoContext: SsoProcessorContext, ) { @Volatile internal var client = createClient(ssoContext.bot) @@ -71,7 +50,7 @@ internal class SsoProcessor( * Do login. Throws [LoginFailedException] if failed */ @Throws(LoginFailedException::class) - suspend fun login(handler: NetworkHandler) = withExceptionCollector<Unit> { + suspend fun login(handler: NetworkHandler) = withExceptionCollector { if (client.wLoginSigInfoInitialized) { kotlin.runCatching { FastLoginImpl(handler).doLogin() @@ -83,6 +62,7 @@ internal class SsoProcessor( client = createClient(ssoContext.bot) SlowLoginImpl(handler).doLogin() } + ssoContext.accountSecretsManager.saveSecrets(ssoContext.account, AccountSecretsImpl(client)) } private fun createClient(bot: QQAndroidBot): QQAndroidClient { diff --git a/mirai-core/src/commonMain/kotlin/network/handler/components/package.kt b/mirai-core/src/commonMain/kotlin/network/handler/components/package.kt new file mode 100644 index 000000000..531bef7db --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/components/package.kt @@ -0,0 +1,13 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +/** + * 放置一些小组件 + */ +package net.mamoe.mirai.internal.network.handler.components \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/AccountSecrets.kt b/mirai-core/src/commonMain/kotlin/network/handler/context/AccountSecrets.kt similarity index 92% rename from mirai-core/src/commonMain/kotlin/network/AccountSecrets.kt rename to mirai-core/src/commonMain/kotlin/network/handler/context/AccountSecrets.kt index a2d4adc4f..1afa04f83 100644 --- a/mirai-core/src/commonMain/kotlin/network/AccountSecrets.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/context/AccountSecrets.kt @@ -7,11 +7,14 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network +package net.mamoe.mirai.internal.network.handler.context import kotlinx.io.core.toByteArray import kotlinx.serialization.Serializable import net.mamoe.mirai.internal.BotAccount +import net.mamoe.mirai.internal.network.LoginExtraData +import net.mamoe.mirai.internal.network.WLoginSigInfo +import net.mamoe.mirai.internal.network.getRandomByteArray import net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin.get_mpasswd import net.mamoe.mirai.internal.utils.io.ProtoBuf import net.mamoe.mirai.utils.DeviceInfo diff --git a/mirai-core/src/commonMain/kotlin/network/handler/context/BdhSession.kt b/mirai-core/src/commonMain/kotlin/network/handler/context/BdhSession.kt new file mode 100644 index 000000000..e811afb91 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/context/BdhSession.kt @@ -0,0 +1,21 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.context + +import kotlinx.serialization.Serializable +import java.util.concurrent.CopyOnWriteArraySet + +@Serializable +internal class BdhSession( + val sigSession: ByteArray, + val sessionKey: ByteArray, + var ssoAddresses: MutableSet<Pair<Int, Int>> = CopyOnWriteArraySet(), + var otherAddresses: MutableSet<Pair<Int, Int>> = CopyOnWriteArraySet(), +) \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/context/NetworkHandlerContext.kt b/mirai-core/src/commonMain/kotlin/network/handler/context/NetworkHandlerContext.kt new file mode 100644 index 000000000..4595faa10 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/context/NetworkHandlerContext.kt @@ -0,0 +1,41 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.context + +import net.mamoe.mirai.internal.QQAndroidBot +import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.components.SsoProcessor +import net.mamoe.mirai.internal.network.handler.state.StateObserver +import net.mamoe.mirai.utils.MiraiLogger + +/** + * Immutable context for [NetworkHandler] + * @see NetworkHandlerContextImpl + */ +internal interface NetworkHandlerContext { + val bot: QQAndroidBot + // however migration requires a major change. + + val logger: MiraiLogger + val ssoProcessor: SsoProcessor + + val stateObserver: StateObserver? +} + +internal class NetworkHandlerContextImpl( + override val bot: QQAndroidBot, + override val ssoProcessor: SsoProcessor, + override val logger: MiraiLogger, + override val stateObserver: StateObserver?, +) : NetworkHandlerContext { + override fun toString(): String { + return "NetworkHandlerContextImpl(bot=${bot.id}, stateObserver=$stateObserver)" + } +} diff --git a/mirai-core/src/commonMain/kotlin/network/handler/context/SsoProcessorContext.kt b/mirai-core/src/commonMain/kotlin/network/handler/context/SsoProcessorContext.kt new file mode 100644 index 000000000..df80e0d7e --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/context/SsoProcessorContext.kt @@ -0,0 +1,47 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.context + +import net.mamoe.mirai.internal.BotAccount +import net.mamoe.mirai.internal.QQAndroidBot +import net.mamoe.mirai.internal.network.handler.components.AccountSecretsManager +import net.mamoe.mirai.internal.network.handler.components.SsoProcessor +import net.mamoe.mirai.internal.network.handler.components.createAccountsSecretsManager +import net.mamoe.mirai.utils.BotConfiguration +import net.mamoe.mirai.utils.DeviceInfo + +/** + * Provides the information needed by the [SsoProcessor]. + */ +internal interface SsoProcessorContext { + /** + * Use other properties instead. Use [bot] only when you cannot find other properties. + */ + val bot: QQAndroidBot + + val account: BotAccount + val device: DeviceInfo + + val protocol: BotConfiguration.MiraiProtocol + + val accountSecretsManager: AccountSecretsManager + + val configuration: BotConfiguration +} + +internal class SsoProcessorContextImpl( + override val bot: QQAndroidBot +) : SsoProcessorContext { + override val account: BotAccount get() = bot.account + override val device: DeviceInfo = configuration.deviceInfo?.invoke(bot) ?: DeviceInfo.random() + override val protocol: BotConfiguration.MiraiProtocol get() = configuration.protocol + override val accountSecretsManager: AccountSecretsManager get() = configuration.createAccountsSecretsManager(bot.logger) + override val configuration: BotConfiguration get() = bot.configuration +} diff --git a/mirai-core/src/commonMain/kotlin/network/net/protocol/SsoSession.kt b/mirai-core/src/commonMain/kotlin/network/handler/context/SsoSession.kt similarity index 81% rename from mirai-core/src/commonMain/kotlin/network/net/protocol/SsoSession.kt rename to mirai-core/src/commonMain/kotlin/network/handler/context/SsoSession.kt index f3e4748fb..458549f50 100644 --- a/mirai-core/src/commonMain/kotlin/network/net/protocol/SsoSession.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/context/SsoSession.kt @@ -7,10 +7,11 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network.net.protocol +package net.mamoe.mirai.internal.network.handler.context -import net.mamoe.mirai.internal.network.AccountSecrets import net.mamoe.mirai.internal.network.WLoginSigInfo +import net.mamoe.mirai.internal.network.handler.components.PacketCodec +import net.mamoe.mirai.internal.network.handler.components.SsoProcessor import net.mamoe.mirai.internal.utils.crypto.ECDH /** diff --git a/mirai-core/src/commonMain/kotlin/network/handler/context/package.kt b/mirai-core/src/commonMain/kotlin/network/handler/context/package.kt new file mode 100644 index 000000000..617a3a925 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/context/package.kt @@ -0,0 +1,13 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +/** + * 放各种 context + */ +package net.mamoe.mirai.internal.network.handler.context \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NettyNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NettyNetworkHandler.kt index b097ba053..997e5c497 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NettyNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NettyNetworkHandler.kt @@ -23,12 +23,12 @@ import kotlinx.coroutines.channels.sendBlocking import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.consumeAsFlow import net.mamoe.mirai.internal.network.handler.NetworkHandler -import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext -import net.mamoe.mirai.internal.network.handler.impl.NetworkHandlerSupport +import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport +import net.mamoe.mirai.internal.network.handler.components.PacketCodec +import net.mamoe.mirai.internal.network.handler.components.RawIncomingPacket +import net.mamoe.mirai.internal.network.handler.components.SsoProcessor +import net.mamoe.mirai.internal.network.handler.context.NetworkHandlerContext import net.mamoe.mirai.internal.network.handler.logger -import net.mamoe.mirai.internal.network.net.protocol.PacketCodec -import net.mamoe.mirai.internal.network.net.protocol.RawIncomingPacket -import net.mamoe.mirai.internal.network.net.protocol.SsoProcessor import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket import net.mamoe.mirai.utils.childScope import net.mamoe.mirai.utils.debug diff --git a/mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NetyNetworkHandlerFactory.kt b/mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NettyNetworkHandlerFactory.kt similarity index 91% rename from mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NetyNetworkHandlerFactory.kt rename to mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NettyNetworkHandlerFactory.kt index 0cb2806c9..5914000c5 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NetyNetworkHandlerFactory.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/impl/netty/NettyNetworkHandlerFactory.kt @@ -9,8 +9,8 @@ package net.mamoe.mirai.internal.network.handler.impl.netty -import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory +import net.mamoe.mirai.internal.network.handler.context.NetworkHandlerContext import java.net.SocketAddress internal object NettyNetworkHandlerFactory : NetworkHandlerFactory<NettyNetworkHandler> { diff --git a/mirai-core/src/commonMain/kotlin/network/handler/selector/AbstractKeepAliveNetworkHandlerSelector.kt b/mirai-core/src/commonMain/kotlin/network/handler/selector/AbstractKeepAliveNetworkHandlerSelector.kt new file mode 100644 index 000000000..4f872dc8b --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/selector/AbstractKeepAliveNetworkHandlerSelector.kt @@ -0,0 +1,61 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.selector + +import kotlinx.atomicfu.atomic +import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory +import org.jetbrains.annotations.TestOnly + +/** + * A lazy stateful implementation of [NetworkHandlerSelector]. + * + * - Calls [factory.create][NetworkHandlerFactory.create] to create [NetworkHandler]s. + * - Re-initialize [NetworkHandler] instances if the old one is dead. + * - Suspends requests when connection is not available. + * + * No connection is created until first invocation of [getResumedInstance], + * and new connections are created only when calling [getResumedInstance] if the old connection was dead. + */ +// may be replaced with a better name. +internal abstract class AbstractKeepAliveNetworkHandlerSelector<H : NetworkHandler> : NetworkHandlerSelector<H> { + private val current = atomic<H?>(null) + + @TestOnly + internal fun setCurrent(h: H) { + current.value = h + } + + protected abstract fun createInstance(): H + + final override fun getResumedInstance(): H? = current.value + + final override tailrec suspend fun awaitResumeInstance(): H { + val current = getResumedInstance() + return if (current != null) { + when (current.state) { + NetworkHandler.State.CLOSED -> { + this.current.compareAndSet(current, null) // invalidate the instance and try again. + awaitResumeInstance() // will create new instance. + } + NetworkHandler.State.CONNECTING, + NetworkHandler.State.CONNECTION_LOST, + NetworkHandler.State.INITIALIZED, + NetworkHandler.State.OK -> { + current.resumeConnection() + return current + } + } + } else { + this.current.compareAndSet(current, createInstance()) + awaitResumeInstance() + } + } +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/selector/ExceptionInSelectorResumeException.kt b/mirai-core/src/commonMain/kotlin/network/handler/selector/ExceptionInSelectorResumeException.kt new file mode 100644 index 000000000..c82cd959a --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/selector/ExceptionInSelectorResumeException.kt @@ -0,0 +1,14 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.selector + +internal class ExceptionInSelectorResumeException( + cause: Throwable +) : RuntimeException(cause) \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/selector/FactoryKeepAliveNetworkHandlerSelector.kt b/mirai-core/src/commonMain/kotlin/network/handler/selector/FactoryKeepAliveNetworkHandlerSelector.kt new file mode 100644 index 000000000..a033a2e98 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/selector/FactoryKeepAliveNetworkHandlerSelector.kt @@ -0,0 +1,27 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.selector + +import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory +import net.mamoe.mirai.internal.network.handler.components.ServerList +import net.mamoe.mirai.internal.network.handler.context.NetworkHandlerContext + +/** + * [AbstractKeepAliveNetworkHandlerSelector] implementation delegating [createInstance] to [factory] + */ +internal class FactoryKeepAliveNetworkHandlerSelector<H : NetworkHandler>( + private val factory: NetworkHandlerFactory<H>, + private val serverList: ServerList, + private val context: NetworkHandlerContext, +) : AbstractKeepAliveNetworkHandlerSelector<H>() { + override fun createInstance(): H = + factory.create(context, serverList.pollCurrent()?.toSocketAddress() ?: throw NoServerAvailableException()) +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/selector/NetworkHandlerSelector.kt b/mirai-core/src/commonMain/kotlin/network/handler/selector/NetworkHandlerSelector.kt new file mode 100644 index 000000000..fb3274b08 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/selector/NetworkHandlerSelector.kt @@ -0,0 +1,32 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.selector + +import net.mamoe.mirai.internal.network.handler.NetworkHandler + +/** + * A lazy stateful selector of [NetworkHandler]. This is used as a director([selector][SelectorNetworkHandler.selector]) to [SelectorNetworkHandler]. + */ +internal interface NetworkHandlerSelector<H : NetworkHandler> { + /** + * Returns an instance immediately without suspension, or `null` if instance not ready. + * + * This function should not throw any exception. + * @see awaitResumeInstance + */ + fun getResumedInstance(): H? + + /** + * Returns an alive [NetworkHandler], or suspends the coroutine until the connection has been made again. + * + * This function may throw exceptions, which would be propagated to the original caller of [SelectorNetworkHandler.resumeConnection]. + */ + suspend fun awaitResumeInstance(): H +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/selector/NoServerAvailableException.kt b/mirai-core/src/commonMain/kotlin/network/handler/selector/NoServerAvailableException.kt new file mode 100644 index 000000000..166eed6f5 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/selector/NoServerAvailableException.kt @@ -0,0 +1,13 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.selector + +internal class NoServerAvailableException : + NoSuchElementException("No server available. (Failed to connect to any of the servers)") \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/selector/SelectorNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/handler/selector/SelectorNetworkHandler.kt new file mode 100644 index 000000000..3df20abca --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/selector/SelectorNetworkHandler.kt @@ -0,0 +1,48 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.selector + +import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.NetworkHandler.State +import net.mamoe.mirai.internal.network.handler.context.NetworkHandlerContext +import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket + +/** + * A proxy to [NetworkHandler] that delegates calls to instance returned by [NetworkHandlerSelector.awaitResumeInstance]. + * + * [NetworkHandlerSelector.awaitResumeInstance] is called everytime when an operation in [NetworkHandler] is called. + * + * This is useful to implement a delegation of [NetworkHandler]. The functionality of *selection* is provided by the strategy [selector][NetworkHandlerSelector]. + * @see NetworkHandlerSelector + */ +internal class SelectorNetworkHandler( + override val context: NetworkHandlerContext, // impl notes: may consider to move into function member. + private val selector: NetworkHandlerSelector<*>, +) : NetworkHandler { + private suspend inline fun instance(): NetworkHandler = selector.awaitResumeInstance() + + override val state: State + get() = selector.getResumedInstance()?.state ?: State.INITIALIZED + + override suspend fun resumeConnection() { + instance() // the selector will resume connection for us. + } + + override suspend fun sendAndExpect(packet: OutgoingPacket, timeout: Long, attempts: Int) = + instance().sendAndExpect(packet, timeout, attempts) + + override suspend fun sendWithoutExpect(packet: OutgoingPacket) = instance().sendWithoutExpect(packet) + override fun close(cause: Throwable?) { + selector.getResumedInstance()?.close(cause) + } + + override fun toString(): String = "SelectorNetworkHandler(currentInstance=${selector.getResumedInstance()})" +} + diff --git a/mirai-core/src/commonMain/kotlin/network/handler/state/CombinedStateObserver.kt b/mirai-core/src/commonMain/kotlin/network/handler/state/CombinedStateObserver.kt new file mode 100644 index 000000000..0afe52161 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/state/CombinedStateObserver.kt @@ -0,0 +1,54 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.state + +import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport + +internal class CombinedStateObserver( + private val first: StateObserver, + private val last: StateObserver, +) : StateObserver { + override fun stateChanged( + networkHandler: NetworkHandlerSupport, + previous: NetworkHandlerSupport.BaseStateImpl, + new: NetworkHandlerSupport.BaseStateImpl + ) { + first.stateChanged(networkHandler, previous, new) + last.stateChanged(networkHandler, previous, new) + } + + override fun exceptionOnCreatingNewState( + networkHandler: NetworkHandlerSupport, + previousState: NetworkHandlerSupport.BaseStateImpl, + exception: Throwable + ) { + first.exceptionOnCreatingNewState(networkHandler, previousState, exception) + last.exceptionOnCreatingNewState(networkHandler, previousState, exception) + } + + override fun beforeStateResume(networkHandler: NetworkHandler, state: NetworkHandlerSupport.BaseStateImpl) { + first.beforeStateResume(networkHandler, state) + last.beforeStateResume(networkHandler, state) + } + + override fun afterStateResume( + networkHandler: NetworkHandler, + state: NetworkHandlerSupport.BaseStateImpl, + result: Result<Unit> + ) { + first.afterStateResume(networkHandler, state, result) + last.afterStateResume(networkHandler, state, result) + } + + companion object { + operator fun StateObserver.plus(last: StateObserver): StateObserver = CombinedStateObserver(this, last) + } +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/state/ExceptionInStateObserverException.kt b/mirai-core/src/commonMain/kotlin/network/handler/state/ExceptionInStateObserverException.kt new file mode 100644 index 000000000..d701d7d01 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/state/ExceptionInStateObserverException.kt @@ -0,0 +1,14 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.state + +internal class ExceptionInStateObserverException( + override val cause: Throwable +) : RuntimeException() \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/state/LoggingStateObserver.kt b/mirai-core/src/commonMain/kotlin/network/handler/state/LoggingStateObserver.kt new file mode 100644 index 000000000..9e6f8375d --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/state/LoggingStateObserver.kt @@ -0,0 +1,57 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.state + +import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport +import net.mamoe.mirai.utils.MiraiLogger +import net.mamoe.mirai.utils.debug + +internal class LoggingStateObserver( + val logger: MiraiLogger +) : StateObserver { + override fun toString(): String { + return "LoggingStateObserver(logger=$logger)" + } + + override fun stateChanged( + networkHandler: NetworkHandlerSupport, + previous: NetworkHandlerSupport.BaseStateImpl, + new: NetworkHandlerSupport.BaseStateImpl + ) { + logger.debug { "State changed: ${previous.correspondingState} -> ${new.correspondingState}" } + } + + override fun exceptionOnCreatingNewState( + networkHandler: NetworkHandlerSupport, + previousState: NetworkHandlerSupport.BaseStateImpl, + exception: Throwable + ) { + logger.debug({ "State changed: ${previousState.correspondingState} -> $exception" }, exception) + } + + override fun afterStateResume( + networkHandler: NetworkHandler, + state: NetworkHandlerSupport.BaseStateImpl, + result: Result<Unit> + ) { + result.fold( + onSuccess = { + logger.debug { "State resumed: ${state.correspondingState}." } + }, + onFailure = { + logger.debug( + { "State resumed: ${state.correspondingState} ${result.exceptionOrNull()}" }, + result.exceptionOrNull() + ) + } + ) + } +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/handler/impl/StateObserver.kt b/mirai-core/src/commonMain/kotlin/network/handler/state/SafeStateObserver.kt similarity index 53% rename from mirai-core/src/commonMain/kotlin/network/handler/impl/StateObserver.kt rename to mirai-core/src/commonMain/kotlin/network/handler/state/SafeStateObserver.kt index 4de51ea10..1c66832c5 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/impl/StateObserver.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/state/SafeStateObserver.kt @@ -7,97 +7,13 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -package net.mamoe.mirai.internal.network.handler.impl +package net.mamoe.mirai.internal.network.handler.state import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport import net.mamoe.mirai.utils.MiraiLogger -import net.mamoe.mirai.utils.debug import net.mamoe.mirai.utils.error -/** - * Stateless observer of state changes. - * - * @see SafeStateObserver - * @see LoggingStateObserver - */ -internal interface StateObserver { - - fun stateChanged( - networkHandler: NetworkHandlerSupport, - previous: NetworkHandlerSupport.BaseStateImpl, - new: NetworkHandlerSupport.BaseStateImpl - ) { - } - - fun exceptionOnCreatingNewState( - networkHandler: NetworkHandlerSupport, - previousState: NetworkHandlerSupport.BaseStateImpl, - exception: Throwable, - ) { - } - - fun beforeStateResume( - networkHandler: NetworkHandler, - state: NetworkHandlerSupport.BaseStateImpl, - ) { - - } - - fun afterStateResume( - networkHandler: NetworkHandler, - state: NetworkHandlerSupport.BaseStateImpl, - result: Result<Unit>, - ) { - - } -} - -internal class LoggingStateObserver( - val logger: MiraiLogger -) : StateObserver { - override fun toString(): String { - return "LoggingStateObserver(logger=$logger)" - } - - override fun stateChanged( - networkHandler: NetworkHandlerSupport, - previous: NetworkHandlerSupport.BaseStateImpl, - new: NetworkHandlerSupport.BaseStateImpl - ) { - logger.debug { "State changed: ${previous.correspondingState} -> ${new.correspondingState}" } - } - - override fun exceptionOnCreatingNewState( - networkHandler: NetworkHandlerSupport, - previousState: NetworkHandlerSupport.BaseStateImpl, - exception: Throwable - ) { - logger.debug({ "State changed: ${previousState.correspondingState} -> $exception" }, exception) - } - - override fun afterStateResume( - networkHandler: NetworkHandler, - state: NetworkHandlerSupport.BaseStateImpl, - result: Result<Unit> - ) { - result.fold( - onSuccess = { - logger.debug { "State resumed: ${state.correspondingState}." } - }, - onFailure = { - logger.debug( - { "State resumed: ${state.correspondingState} ${result.exceptionOrNull()}" }, - result.exceptionOrNull() - ) - } - ) - } -} - -internal class ExceptionInStateObserverException( - override val cause: Throwable -) : RuntimeException() - /** * Catches exception then log by [logger] */ diff --git a/mirai-core/src/commonMain/kotlin/network/handler/state/StateObserver.kt b/mirai-core/src/commonMain/kotlin/network/handler/state/StateObserver.kt new file mode 100644 index 000000000..e3e232a76 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/handler/state/StateObserver.kt @@ -0,0 +1,51 @@ +/* + * 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. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.internal.network.handler.state + +import net.mamoe.mirai.internal.network.handler.NetworkHandler +import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport + +/** + * Stateless observer of state changes. + * + * @see SafeStateObserver + * @see LoggingStateObserver + */ +internal interface StateObserver { + + fun stateChanged( + networkHandler: NetworkHandlerSupport, + previous: NetworkHandlerSupport.BaseStateImpl, + new: NetworkHandlerSupport.BaseStateImpl + ) { + } + + fun exceptionOnCreatingNewState( + networkHandler: NetworkHandlerSupport, + previousState: NetworkHandlerSupport.BaseStateImpl, + exception: Throwable, + ) { + } + + fun beforeStateResume( + networkHandler: NetworkHandler, + state: NetworkHandlerSupport.BaseStateImpl, + ) { + + } + + fun afterStateResume( + networkHandler: NetworkHandler, + state: NetworkHandlerSupport.BaseStateImpl, + result: Result<Unit>, + ) { + + } +} diff --git a/mirai-core/src/commonMain/kotlin/network/highway/Highway.kt b/mirai-core/src/commonMain/kotlin/network/highway/Highway.kt index 28c65543c..e3d285032 100644 --- a/mirai-core/src/commonMain/kotlin/network/highway/Highway.kt +++ b/mirai-core/src/commonMain/kotlin/network/highway/Highway.kt @@ -22,7 +22,7 @@ import kotlinx.io.core.discardExact import kotlinx.io.core.writeFully import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.network.QQAndroidClient -import net.mamoe.mirai.internal.network.handler.BdhSession +import net.mamoe.mirai.internal.network.handler.context.BdhSession import net.mamoe.mirai.internal.network.handler.logger import net.mamoe.mirai.internal.network.protocol.data.proto.CSDataHighwayHead import net.mamoe.mirai.internal.network.subAppId diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt index 1d29af0f2..c2d1e5593 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/PacketFactory.kt @@ -13,7 +13,7 @@ import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.event.Event import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.network.Packet -import net.mamoe.mirai.internal.network.net.protocol.PacketCodec +import net.mamoe.mirai.internal.network.handler.components.PacketCodec import net.mamoe.mirai.internal.network.protocol.packet.chat.* import net.mamoe.mirai.internal.network.protocol.packet.chat.image.ImgStore import net.mamoe.mirai.internal.network.protocol.packet.chat.image.LongConn @@ -113,7 +113,7 @@ internal suspend inline fun <P : Packet?> IncomingPacketFactory<P>.decode( */ @Deprecated( "Kept for binary compatibility.", - ReplaceWith("PacketCodec.PacketLogger", "net.mamoe.mirai.internal.network.net.protocol.PacketCodec"), + ReplaceWith("PacketCodec.PacketLogger", "net.mamoe.mirai.internal.network.handler.components.PacketCodec"), level = DeprecationLevel.ERROR, ) @PublishedApi diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/MultiMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/MultiMsg.kt index 51151dd01..e93faa489 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/MultiMsg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/MultiMsg.kt @@ -19,7 +19,7 @@ import net.mamoe.mirai.internal.message.contextualBugReportException import net.mamoe.mirai.internal.message.toRichTextElems import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.network.QQAndroidClient -import net.mamoe.mirai.internal.network.net.protocol.PacketCodec +import net.mamoe.mirai.internal.network.handler.components.PacketCodec import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm import net.mamoe.mirai.internal.network.protocol.data.proto.MsgTransmit diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/ConfigPushSvc.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/ConfigPushSvc.kt index 64a68d8aa..9c0e5520c 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/ConfigPushSvc.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/ConfigPushSvc.kt @@ -19,7 +19,8 @@ import net.mamoe.mirai.event.events.BotOfflineEvent import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.message.contextualBugReportException import net.mamoe.mirai.internal.network.Packet -import net.mamoe.mirai.internal.network.handler.BdhSession +import net.mamoe.mirai.internal.network.handler.components.ServerAddress +import net.mamoe.mirai.internal.network.handler.context.BdhSession import net.mamoe.mirai.internal.network.handler.logger import net.mamoe.mirai.internal.network.networkType import net.mamoe.mirai.internal.network.protocol.data.jce.FileStoragePushFSSvcList @@ -148,10 +149,7 @@ internal class ConfigPushSvc { bot.network.logger.info { "Server list: ${pushServerList.joinToString()}." } if (pushServerList.isNotEmpty()) { - bot.serverList.clear() - pushServerList.shuffled().forEach { - bot.serverList.add(it.host to it.port) - } + bot.serverListNew.setPreferred(pushServerList.shuffled().map { ServerAddress(it.host, it.port) }) } bot.bdhSyncer.saveToCache() bot.bdhSyncer.saveServerListToCache() diff --git a/mirai-core/src/commonTest/kotlin/network/ServerListTest.kt b/mirai-core/src/commonTest/kotlin/network/ServerListTest.kt index 1b1217925..663a40b96 100644 --- a/mirai-core/src/commonTest/kotlin/network/ServerListTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/ServerListTest.kt @@ -9,8 +9,8 @@ package net.mamoe.mirai.internal.network -import net.mamoe.mirai.internal.network.handler.ServerAddress -import net.mamoe.mirai.internal.network.handler.ServerList +import net.mamoe.mirai.internal.network.handler.components.ServerAddress +import net.mamoe.mirai.internal.network.handler.components.ServerList import kotlin.test.* internal class ServerListTest { diff --git a/mirai-core/src/commonTest/kotlin/network/handler/AbstractKeepAliveNetworkHandlerSelectorTest.kt b/mirai-core/src/commonTest/kotlin/network/handler/AbstractKeepAliveNetworkHandlerSelectorTest.kt index f288b0409..67cf1352f 100644 --- a/mirai-core/src/commonTest/kotlin/network/handler/AbstractKeepAliveNetworkHandlerSelectorTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/handler/AbstractKeepAliveNetworkHandlerSelectorTest.kt @@ -10,6 +10,7 @@ package net.mamoe.mirai.internal.network.handler import net.mamoe.mirai.internal.network.handler.NetworkHandler.State +import net.mamoe.mirai.internal.network.handler.selector.AbstractKeepAliveNetworkHandlerSelector import net.mamoe.mirai.internal.test.runBlockingUnit import java.util.concurrent.atomic.AtomicInteger import kotlin.test.* diff --git a/mirai-core/src/commonTest/kotlin/network/handler/testUtils.kt b/mirai-core/src/commonTest/kotlin/network/handler/testUtils.kt index 676f204b9..d51d3f8e7 100644 --- a/mirai-core/src/commonTest/kotlin/network/handler/testUtils.kt +++ b/mirai-core/src/commonTest/kotlin/network/handler/testUtils.kt @@ -12,12 +12,12 @@ package net.mamoe.mirai.internal.network.handler import kotlinx.coroutines.CompletableDeferred import net.mamoe.mirai.internal.MockBot import net.mamoe.mirai.internal.QQAndroidBot -import net.mamoe.mirai.internal.network.handler.impl.LoggingStateObserver -import net.mamoe.mirai.internal.network.handler.impl.NetworkHandlerSupport -import net.mamoe.mirai.internal.network.handler.impl.SafeStateObserver -import net.mamoe.mirai.internal.network.handler.impl.StateObserver -import net.mamoe.mirai.internal.network.net.protocol.SsoProcessor -import net.mamoe.mirai.internal.network.net.protocol.SsoProcessorContextImpl +import net.mamoe.mirai.internal.network.handler.components.SsoProcessor +import net.mamoe.mirai.internal.network.handler.context.NetworkHandlerContext +import net.mamoe.mirai.internal.network.handler.context.SsoProcessorContextImpl +import net.mamoe.mirai.internal.network.handler.state.LoggingStateObserver +import net.mamoe.mirai.internal.network.handler.state.SafeStateObserver +import net.mamoe.mirai.internal.network.handler.state.StateObserver import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket import net.mamoe.mirai.utils.MiraiLogger import java.util.concurrent.ConcurrentLinkedQueue diff --git a/mirai-core/src/commonTest/kotlin/network/sessionUtils.kt b/mirai-core/src/commonTest/kotlin/network/sessionUtils.kt index 3a4e36138..31b753df0 100644 --- a/mirai-core/src/commonTest/kotlin/network/sessionUtils.kt +++ b/mirai-core/src/commonTest/kotlin/network/sessionUtils.kt @@ -11,7 +11,9 @@ package net.mamoe.mirai.internal.network import net.mamoe.mirai.event.events.BotOnlineEvent import net.mamoe.mirai.internal.QQAndroidBot -import net.mamoe.mirai.internal.network.net.protocol.SsoSession +import net.mamoe.mirai.internal.network.handler.context.AccountSecrets +import net.mamoe.mirai.internal.network.handler.context.AccountSecretsImpl +import net.mamoe.mirai.internal.network.handler.context.SsoSession import net.mamoe.mirai.internal.utils.crypto.ECDH import net.mamoe.mirai.internal.utils.io.serialization.loadAs import net.mamoe.mirai.internal.utils.io.serialization.toByteArray