mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-23 22:00:10 +08:00
Rearrange packages
This commit is contained in:
parent
31bdd82bf5
commit
05b2bfe059
@ -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()
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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)")
|
@ -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
|
@ -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(),
|
||||
)
|
@ -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
|
@ -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
|
@ -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()
|
||||
}
|
@ -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 {
|
@ -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
|
@ -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
|
@ -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(),
|
||||
)
|
@ -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)"
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
|
||||
/**
|
@ -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
|
@ -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
|
||||
|
@ -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> {
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
@ -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())
|
||||
}
|
@ -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
|
||||
}
|
@ -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)")
|
@ -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()})"
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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()
|
@ -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()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
@ -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]
|
||||
*/
|
@ -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>,
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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 {
|
||||
|
@ -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.*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user