mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-22 13:46:13 +08:00
Components misc implementations including (ABI changes):
- ComponentStorage and its impls - ContactCacheService - ContactUpdater - HeartbeatProcessor - SsoProcessor - QQABot
This commit is contained in:
parent
7f2f1e9759
commit
4f77abca87
@ -105,7 +105,7 @@ internal class QQAndroidBot constructor(
|
||||
val components = this // avoid mistakes
|
||||
set(SsoProcessorContext, SsoProcessorContextImpl(bot))
|
||||
set(SsoProcessor, SsoProcessorImpl(get(SsoProcessorContext)))
|
||||
set(HeartbeatProcessor, HeartbeatProcessor())
|
||||
set(HeartbeatProcessor, HeartbeatProcessorImpl())
|
||||
set(KeyRefreshProcessor, KeyRefreshProcessorImpl(networkLogger))
|
||||
set(ConfigPushProcessor, ConfigPushProcessorImpl(networkLogger))
|
||||
|
||||
|
@ -12,9 +12,13 @@ package net.mamoe.mirai.internal.network.component
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
|
||||
/**
|
||||
* Facade for [component][ComponentKey]s. Implementation must be thread-safe.
|
||||
* Mediator for [component][ComponentKey]s accessing each other.
|
||||
*
|
||||
* Implementation must be thread-safe.
|
||||
*
|
||||
* @see MutableComponentStorage
|
||||
* @see ConcurrentComponentStorage
|
||||
* @see plus
|
||||
*/
|
||||
internal interface ComponentStorage {
|
||||
@get:TestOnly
|
||||
@ -24,6 +28,39 @@ internal interface ComponentStorage {
|
||||
operator fun <T : Any> get(key: ComponentKey<T>): T
|
||||
fun <T : Any> getOrNull(key: ComponentKey<T>): T?
|
||||
|
||||
val keys: Set<ComponentKey<*>>
|
||||
|
||||
override fun toString(): String
|
||||
}
|
||||
|
||||
internal operator fun ComponentStorage.plus(fallback: ComponentStorage): ComponentStorage =
|
||||
CombinedComponentStorage(this, fallback)
|
||||
|
||||
private class CombinedComponentStorage(
|
||||
val main: ComponentStorage,
|
||||
val fallback: ComponentStorage,
|
||||
) : ComponentStorage {
|
||||
override val keys: Set<ComponentKey<*>> get() = main.keys + fallback.keys
|
||||
override val size: Int get() = keys.size
|
||||
|
||||
override fun <T : Any> get(key: ComponentKey<T>): T {
|
||||
return main.getOrNull(key) ?: fallback.getOrNull(key) ?: main[key] // let `main` throw exception
|
||||
}
|
||||
|
||||
override fun <T : Any> getOrNull(key: ComponentKey<T>): T? {
|
||||
return main.getOrNull(key) ?: fallback.getOrNull(key)
|
||||
}
|
||||
|
||||
override fun toString(): String = buildString {
|
||||
appendLine("CombinedComponentStorage {")
|
||||
appendLine("* main:")
|
||||
main.toString().lines().forEach {
|
||||
append(" ").appendLine(it)
|
||||
}
|
||||
appendLine("*** fallback:")
|
||||
fallback.toString().lines().forEach {
|
||||
append(" ").appendLine(it)
|
||||
}
|
||||
appendLine("}")
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ internal class ConcurrentComponentStorage(
|
||||
) : ComponentStorage, MutableComponentStorage {
|
||||
private val map = ConcurrentHashMap<ComponentKey<*>, Any?>()
|
||||
|
||||
override val keys: Set<ComponentKey<*>> get() = map.keys
|
||||
override val size: Int get() = map.size
|
||||
|
||||
override operator fun <T : Any> get(key: ComponentKey<T>): T {
|
||||
|
@ -9,7 +9,14 @@
|
||||
|
||||
package net.mamoe.mirai.internal.network.component
|
||||
|
||||
/**
|
||||
* Should not be thrown normally.
|
||||
*/
|
||||
internal data class NoSuchComponentException(
|
||||
val key: ComponentKey<*>,
|
||||
val storage: ComponentStorage
|
||||
) : NoSuchElementException("No such component: $key")
|
||||
) : NoSuchElementException() {
|
||||
override val message: String by lazy {
|
||||
"No such component '$key' in storage: \n$storage"
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ import net.mamoe.mirai.internal.QQAndroidBot
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.internal.network.component.ComponentKey
|
||||
import net.mamoe.mirai.internal.network.component.ComponentStorage
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State
|
||||
import net.mamoe.mirai.internal.network.handler.state.JobAttachStateObserver
|
||||
import net.mamoe.mirai.internal.network.handler.state.StateObserver
|
||||
@ -28,6 +29,13 @@ import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.info
|
||||
|
||||
|
||||
/**
|
||||
* Facade of [ContactUpdater], [OtherClientUpdater], [ConfigPushSyncer].
|
||||
* Handles initialization jobs after successful logon.
|
||||
*
|
||||
* Attached to handler state [NetworkHandler.State.LOADING] [as state observer][asObserver].
|
||||
*/
|
||||
internal interface BotInitProcessor {
|
||||
suspend fun init()
|
||||
|
||||
|
@ -22,13 +22,16 @@ import net.mamoe.mirai.utils.loadNotBlankAs
|
||||
import net.mamoe.mirai.utils.runBIO
|
||||
|
||||
/**
|
||||
* Maintains cache. Used by [ContactUpdater].
|
||||
* Strategy of caching contacts. Used by [ContactUpdater].
|
||||
*/
|
||||
internal interface ContactCacheService {
|
||||
val friendListCache: FriendListCache?
|
||||
val groupMemberListCaches: GroupMemberListCaches?
|
||||
val friendListCache: FriendListCache? // from old code
|
||||
val groupMemberListCaches: GroupMemberListCaches? // from old code
|
||||
|
||||
fun saveFriendCache()
|
||||
/**
|
||||
* Implementation does not need to be thread-safe.
|
||||
*/
|
||||
fun saveFriendCache() // from old code
|
||||
|
||||
companion object : ComponentKey<ContactCacheService>
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import net.mamoe.mirai.Mirai
|
||||
import net.mamoe.mirai.contact.Contact
|
||||
import net.mamoe.mirai.data.FriendInfo
|
||||
import net.mamoe.mirai.data.MemberInfo
|
||||
import net.mamoe.mirai.internal.QQAndroidBot
|
||||
@ -47,11 +48,23 @@ import net.mamoe.mirai.utils.retryCatching
|
||||
import net.mamoe.mirai.utils.verbose
|
||||
|
||||
/**
|
||||
* Uses [ContactCacheService]
|
||||
* Manager of caches for [Contact]s.
|
||||
*
|
||||
* Uses [ContactCacheService].
|
||||
*/
|
||||
internal interface ContactUpdater {
|
||||
/**
|
||||
* Load all caches to the bot this [ContactUpdater] works for.
|
||||
*
|
||||
* Implementation must be thread-safe.
|
||||
*/
|
||||
suspend fun loadAll(registerResp: SvcRespRegister)
|
||||
|
||||
/**
|
||||
* Closes all contacts and save them to cache if needed.
|
||||
*
|
||||
* Implementation must be thread-safe.
|
||||
*/
|
||||
fun closeAllContacts(e: CancellationException)
|
||||
|
||||
companion object : ComponentKey<ContactUpdater>
|
||||
|
@ -15,16 +15,21 @@ import net.mamoe.mirai.internal.network.handler.NetworkHandler
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.login.StatSvc
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
|
||||
|
||||
internal class HeartbeatProcessor {
|
||||
internal interface HeartbeatProcessor {
|
||||
|
||||
@Throws(Exception::class)
|
||||
suspend fun doHeartbeatNow(networkHandler: NetworkHandler) {
|
||||
suspend fun doHeartbeatNow(networkHandler: NetworkHandler)
|
||||
|
||||
companion object : ComponentKey<HeartbeatProcessor>
|
||||
}
|
||||
|
||||
internal class HeartbeatProcessorImpl : HeartbeatProcessor {
|
||||
@Throws(Exception::class)
|
||||
override suspend fun doHeartbeatNow(networkHandler: NetworkHandler) {
|
||||
StatSvc.SimpleGet(networkHandler.context.bot.client).sendAndExpect(
|
||||
networkHandler,
|
||||
timeoutMillis = networkHandler.context[SsoProcessorContext].configuration.heartbeatTimeoutMillis,
|
||||
retry = 2
|
||||
)
|
||||
}
|
||||
|
||||
companion object : ComponentKey<HeartbeatProcessor>
|
||||
}
|
@ -28,10 +28,27 @@ internal data class ServerAddress(
|
||||
fun toSocketAddress(): InetSocketAddress = InetSocketAddress.createUnresolved(host, port)
|
||||
}
|
||||
|
||||
/**
|
||||
* Self-refillable (similarly circular) queue of servers. Pop each time when trying to connect.
|
||||
*
|
||||
* [Preferred][getPreferred] prevails if present than [DEFAULT_SERVER_LIST].
|
||||
*
|
||||
* *+Implementation must be thread-safe**.
|
||||
*/
|
||||
internal interface ServerList {
|
||||
/**
|
||||
* Set preferred so not using [DEFAULT_SERVER_LIST].
|
||||
*/
|
||||
fun setPreferred(list: Collection<ServerAddress>)
|
||||
|
||||
/**
|
||||
* Might return [DEFAULT_SERVER_LIST] if not present.
|
||||
*/
|
||||
fun getPreferred(): Set<ServerAddress>
|
||||
|
||||
/**
|
||||
* Refill the queue. Mostly do not call this function.
|
||||
*/
|
||||
fun refresh()
|
||||
|
||||
/**
|
||||
@ -60,9 +77,6 @@ internal interface ServerList {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue of servers. Pop each time when trying to connect.
|
||||
*/
|
||||
internal class ServerListImpl(
|
||||
initial: Collection<ServerAddress> = emptyList()
|
||||
) : ServerList {
|
||||
|
@ -41,7 +41,6 @@ import net.mamoe.mirai.utils.withExceptionCollector
|
||||
* Handles login, and acts also as a mediator of [BotInitProcessor], []
|
||||
*/
|
||||
internal interface SsoProcessor {
|
||||
val ssoContext: SsoProcessorContext
|
||||
val client: QQAndroidClient
|
||||
val ssoSession: SsoSession
|
||||
|
||||
@ -50,7 +49,7 @@ internal interface SsoProcessor {
|
||||
*
|
||||
* E.g. start heartbeat job for [NetworkHandler.State.OK].
|
||||
*/
|
||||
fun createObserverChain(): StateObserver
|
||||
fun createObserverChain(): StateObserver // todo not used
|
||||
|
||||
/**
|
||||
* Do login. Throws [LoginFailedException] if failed
|
||||
@ -69,7 +68,7 @@ internal interface SsoProcessor {
|
||||
* Used by [NettyNetworkHandler.StateConnecting].
|
||||
*/
|
||||
internal class SsoProcessorImpl(
|
||||
override val ssoContext: SsoProcessorContext,
|
||||
val ssoContext: SsoProcessorContext,
|
||||
) : SsoProcessor {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user