mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-28 16:50:09 +08:00
ContactUpdater and ContactCacheService
This commit is contained in:
parent
e08fc5d874
commit
3ec8a94096
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import net.mamoe.mirai.internal.QQAndroidBot
|
||||||
|
import net.mamoe.mirai.internal.network.FriendListCache
|
||||||
|
import net.mamoe.mirai.internal.network.GroupMemberListCaches
|
||||||
|
import net.mamoe.mirai.internal.network.JsonForCache
|
||||||
|
import net.mamoe.mirai.internal.network.handler.component.ComponentKey
|
||||||
|
import net.mamoe.mirai.internal.utils.ScheduledJob
|
||||||
|
import net.mamoe.mirai.internal.utils.friendCacheFile
|
||||||
|
import net.mamoe.mirai.utils.createFileIfNotExists
|
||||||
|
import net.mamoe.mirai.utils.info
|
||||||
|
import net.mamoe.mirai.utils.loadNotBlankAs
|
||||||
|
import net.mamoe.mirai.utils.runBIO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maintains cache. Used by [ContactUpdater].
|
||||||
|
*/
|
||||||
|
internal interface ContactCacheService {
|
||||||
|
val friendListCache: FriendListCache?
|
||||||
|
val groupMemberListCaches: GroupMemberListCaches?
|
||||||
|
|
||||||
|
fun saveFriendCache()
|
||||||
|
|
||||||
|
companion object : ComponentKey<ContactCacheService>
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ContactCacheServiceImpl(
|
||||||
|
private val bot: QQAndroidBot
|
||||||
|
) : ContactCacheService {
|
||||||
|
private val configuration get() = bot.configuration
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// contact cache
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline val json get() = configuration.json
|
||||||
|
|
||||||
|
override val friendListCache: FriendListCache? by lazy {
|
||||||
|
if (!configuration.contactListCache.friendListCacheEnabled) return@lazy null
|
||||||
|
val file = configuration.friendCacheFile()
|
||||||
|
val ret = file.loadNotBlankAs(FriendListCache.serializer(), JsonForCache) ?: FriendListCache()
|
||||||
|
|
||||||
|
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||||
|
bot.eventChannel.parentScope(bot)
|
||||||
|
.subscribeAlways<net.mamoe.mirai.event.events.FriendInfoChangeEvent> {
|
||||||
|
friendListSaver?.notice()
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
override val groupMemberListCaches: GroupMemberListCaches? by lazy {
|
||||||
|
if (!configuration.contactListCache.groupMemberListCacheEnabled) {
|
||||||
|
return@lazy null
|
||||||
|
}
|
||||||
|
GroupMemberListCaches(bot)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val friendListSaver: ScheduledJob? by lazy {
|
||||||
|
if (!configuration.contactListCache.friendListCacheEnabled) return@lazy null
|
||||||
|
ScheduledJob(bot.coroutineContext, configuration.contactListCache.saveIntervalMillis) {
|
||||||
|
runBIO { saveFriendCache() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveFriendCache() {
|
||||||
|
val friendListCache = friendListCache ?: return
|
||||||
|
|
||||||
|
configuration.friendCacheFile().run {
|
||||||
|
createFileIfNotExists()
|
||||||
|
writeText(JsonForCache.encodeToString(FriendListCache.serializer(), friendListCache))
|
||||||
|
bot.network.context.logger.info { "Saved ${friendListCache.list.size} friends to local cache." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -29,6 +29,7 @@ import net.mamoe.mirai.internal.contact.info.StrangerInfoImpl
|
|||||||
import net.mamoe.mirai.internal.contact.toMiraiFriendInfo
|
import net.mamoe.mirai.internal.contact.toMiraiFriendInfo
|
||||||
import net.mamoe.mirai.internal.network.Packet
|
import net.mamoe.mirai.internal.network.Packet
|
||||||
import net.mamoe.mirai.internal.network.handler.component.ComponentKey
|
import net.mamoe.mirai.internal.network.handler.component.ComponentKey
|
||||||
|
import net.mamoe.mirai.internal.network.handler.component.ComponentStorage
|
||||||
import net.mamoe.mirai.internal.network.handler.logger
|
import net.mamoe.mirai.internal.network.handler.logger
|
||||||
import net.mamoe.mirai.internal.network.isValid
|
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.StTroopNum
|
||||||
@ -41,8 +42,11 @@ import net.mamoe.mirai.utils.info
|
|||||||
import net.mamoe.mirai.utils.retryCatching
|
import net.mamoe.mirai.utils.retryCatching
|
||||||
import net.mamoe.mirai.utils.verbose
|
import net.mamoe.mirai.utils.verbose
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses [ContactCacheService]
|
||||||
|
*/
|
||||||
internal interface ContactUpdater {
|
internal interface ContactUpdater {
|
||||||
suspend fun loadAll(registerResp: SvcRespRegister)
|
suspend fun loadAll(registerResp: SvcRespRegister) // TODO: 2021/4/17 call this fun
|
||||||
|
|
||||||
fun closeAllContacts(e: CancellationException)
|
fun closeAllContacts(e: CancellationException)
|
||||||
|
|
||||||
@ -50,8 +54,11 @@ internal interface ContactUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class ContactUpdaterImpl(
|
internal class ContactUpdaterImpl(
|
||||||
val bot: QQAndroidBot,
|
val bot: QQAndroidBot, // not good
|
||||||
|
val components: ComponentStorage
|
||||||
) : ContactUpdater {
|
) : ContactUpdater {
|
||||||
|
private val cacheService get() = components[ContactCacheService]
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override suspend fun loadAll(registerResp: SvcRespRegister) {
|
override suspend fun loadAll(registerResp: SvcRespRegister) {
|
||||||
coroutineScope {
|
coroutineScope {
|
||||||
@ -92,14 +99,14 @@ internal class ContactUpdaterImpl(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val friendListCache = bot.friendListCache
|
val friendListCache = cacheService.friendListCache
|
||||||
|
|
||||||
fun updateCacheSeq(list: List<FriendInfoImpl>) {
|
fun updateCacheSeq(list: List<FriendInfoImpl>) {
|
||||||
bot.friendListCache?.apply {
|
cacheService.friendListCache?.apply {
|
||||||
friendListSeq = registerResp.iLargeSeq
|
friendListSeq = registerResp.iLargeSeq
|
||||||
timeStamp = registerResp.timeStamp
|
timeStamp = registerResp.timeStamp
|
||||||
this.list = list
|
this.list = list
|
||||||
bot.saveFriendCache()
|
cacheService.saveFriendCache()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +172,7 @@ internal class ContactUpdaterImpl(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val cache = bot.groupMemberListCaches?.get(groupCode)
|
val cache = cacheService.groupMemberListCaches?.get(groupCode)
|
||||||
val members = if (cache != null) {
|
val members = if (cache != null) {
|
||||||
if (cache.isValid(stTroopNum)) {
|
if (cache.isValid(stTroopNum)) {
|
||||||
cache.list.asSequence().also {
|
cache.list.asSequence().also {
|
||||||
@ -174,7 +181,7 @@ internal class ContactUpdaterImpl(
|
|||||||
} else refreshGroupMemberList().also { sequence ->
|
} else refreshGroupMemberList().also { sequence ->
|
||||||
cache.troopMemberNumSeq = dwMemberNumSeq ?: 0
|
cache.troopMemberNumSeq = dwMemberNumSeq ?: 0
|
||||||
cache.list = sequence.mapTo(ArrayList()) { it as MemberInfoImpl }
|
cache.list = sequence.mapTo(ArrayList()) { it as MemberInfoImpl }
|
||||||
bot.groupMemberListCaches!!.reportChanged(groupCode)
|
cacheService.groupMemberListCaches!!.reportChanged(groupCode)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
refreshGroupMemberList()
|
refreshGroupMemberList()
|
||||||
@ -236,7 +243,7 @@ internal class ContactUpdaterImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.info { "Successfully loaded group list: ${troopListData.groups.size} in total." }
|
logger.info { "Successfully loaded group list: ${troopListData.groups.size} in total." }
|
||||||
bot.groupMemberListCaches?.saveGroupCaches()
|
cacheService.groupMemberListCaches?.saveGroupCaches()
|
||||||
initGroupOk = true
|
initGroupOk = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ internal class ScheduledJobTest : AbstractTest() {
|
|||||||
throwable.printStackTrace()
|
throwable.printStackTrace()
|
||||||
})
|
})
|
||||||
val invoked = AtomicInteger(0)
|
val invoked = AtomicInteger(0)
|
||||||
val job = ScheduledJob(scope.coroutineContext, 1 * 1000) {
|
val job = ScheduledJob(scope.coroutineContext, 1000) {
|
||||||
invoked.incrementAndGet()
|
invoked.incrementAndGet()
|
||||||
}
|
}
|
||||||
delay(100)
|
delay(100)
|
||||||
|
Loading…
Reference in New Issue
Block a user