Rearrange packages

This commit is contained in:
Him188 2021-04-17 13:39:59 +08:00
parent 31bdd82bf5
commit 05b2bfe059
42 changed files with 625 additions and 427 deletions

View File

@ -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()

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()
}
}
}

View File

@ -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)")

View File

@ -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

View File

@ -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(),
)

View File

@ -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

View File

@ -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

View File

@ -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()
}

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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(),
)

View File

@ -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)"
}
}

View File

@ -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
}

View File

@ -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
/**

View File

@ -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

View File

@ -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

View File

@ -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> {

View File

@ -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()
}
}
}

View File

@ -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)

View File

@ -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())
}

View File

@ -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
}

View File

@ -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)")

View File

@ -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()})"
}

View File

@ -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)
}
}

View File

@ -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()

View File

@ -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()
)
}
)
}
}

View File

@ -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]
*/

View File

@ -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>,
) {
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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 {

View File

@ -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.*

View File

@ -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

View File

@ -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