mirror of
https://github.com/mamoe/mirai.git
synced 2026-08-22 14:13:32 +08:00
[core] Load FriendGroups separately from Friends. Fix #2274.
This commit is contained in:
@@ -93,14 +93,16 @@ internal class BotInitProcessorImpl(
|
||||
val registerResp =
|
||||
context[SsoProcessor].registerResp ?: error("Internal error: registerResp is not yet available.")
|
||||
|
||||
// do them parallel.
|
||||
context[MessageSvcSyncer].startSync()
|
||||
context[BdhSessionSyncer].loadFromCache()
|
||||
|
||||
|
||||
// do them parallel.
|
||||
coroutineScope {
|
||||
launch { runWithCoverage { context[OtherClientUpdater].update() } }
|
||||
launch { runWithCoverage { context[ContactUpdater].loadAll(registerResp.origin) } }
|
||||
launch { runWithCoverage("loading OtherClients") { context[OtherClientUpdater].update() } }
|
||||
launch { runWithCoverage("loading friends") { context[ContactUpdater].reloadFriendList(registerResp.origin) } }
|
||||
launch { runWithCoverage("loading groups") { context[ContactUpdater].reloadGroupList() } }
|
||||
launch { runWithCoverage("loading otherClients") { context[ContactUpdater].reloadStrangerList() } }
|
||||
launch { runWithCoverage("loading friendGroups") { context[ContactUpdater].reloadFriendGroupList() } }
|
||||
}
|
||||
|
||||
state.value = INITIALIZED
|
||||
@@ -112,12 +114,12 @@ internal class BotInitProcessorImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun runWithCoverage(block: () -> Unit) {
|
||||
private inline fun runWithCoverage(hint: String, block: () -> Unit) {
|
||||
try {
|
||||
block()
|
||||
} catch (e: NetworkException) {
|
||||
logger.warning(
|
||||
"An NetworkException was thrown during initialization process of Bot ${bot.id}. " +
|
||||
"An NetworkException was thrown during '$hint' of Bot ${bot.id}. " +
|
||||
"This means your network is unstable at this moment, " +
|
||||
"or the server has closed the connection due to some reason (you will see the cause if further trials are all failed). " +
|
||||
"Halting the log-in process to wait for a while to reconnect..."
|
||||
@@ -125,7 +127,7 @@ internal class BotInitProcessorImpl(
|
||||
throw e
|
||||
} catch (e: Throwable) {
|
||||
logger.warning(
|
||||
"An exception was thrown during initialization process of Bot ${bot.id}. " +
|
||||
"An exception was thrown during '$hint' of Bot ${bot.id}. " +
|
||||
"Trying to ignore the error and continue logging in...",
|
||||
e
|
||||
)
|
||||
|
||||
@@ -41,7 +41,6 @@ import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.info
|
||||
import net.mamoe.mirai.utils.retryCatching
|
||||
import net.mamoe.mirai.utils.verbose
|
||||
import kotlin.jvm.Synchronized
|
||||
import kotlin.jvm.Volatile
|
||||
|
||||
/**
|
||||
@@ -52,13 +51,14 @@ import kotlin.jvm.Volatile
|
||||
internal interface ContactUpdater {
|
||||
val otherClientsLock: Mutex
|
||||
val groupListModifyLock: Mutex
|
||||
val friendListLock: Mutex
|
||||
val friendGroupsLock: Mutex
|
||||
val strangerListLock: Mutex
|
||||
|
||||
/**
|
||||
* Load all caches to the bot this [ContactUpdater] works for.
|
||||
*
|
||||
* Implementation must be thread-safe.
|
||||
*/
|
||||
suspend fun loadAll(registerResp: SvcRespRegister)
|
||||
suspend fun reloadFriendList(registerResp: SvcRespRegister)
|
||||
suspend fun reloadFriendGroupList()
|
||||
suspend fun reloadGroupList()
|
||||
suspend fun reloadStrangerList()
|
||||
|
||||
/**
|
||||
* Closes all contacts and save them to cache if needed.
|
||||
@@ -77,20 +77,11 @@ internal class ContactUpdaterImpl(
|
||||
) : ContactUpdater, NewContactSupport {
|
||||
override val otherClientsLock: Mutex = Mutex()
|
||||
override val groupListModifyLock: Mutex = Mutex()
|
||||
override val friendListLock: Mutex = Mutex()
|
||||
override val friendGroupsLock: Mutex = Mutex()
|
||||
override val strangerListLock: Mutex = Mutex()
|
||||
private val cacheService get() = components[ContactCacheService]
|
||||
private val lock = Mutex()
|
||||
|
||||
override suspend fun loadAll(registerResp: SvcRespRegister) {
|
||||
lock.withLock {
|
||||
coroutineScope {
|
||||
launch { reloadFriendList(registerResp) }
|
||||
launch { reloadGroupList() }
|
||||
launch { reloadStrangerList() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun closeAllContacts(e: CancellationException) {
|
||||
if (!initFriendOk) {
|
||||
bot.friends.delegate.removeAll { it.cancel(e); true }
|
||||
@@ -101,12 +92,18 @@ internal class ContactUpdaterImpl(
|
||||
if (!initStrangerOk) {
|
||||
bot.strangers.delegate.removeAll { it.cancel(e); true }
|
||||
}
|
||||
if (!initFriendGroupOk) {
|
||||
bot.friendGroups.friendGroups.clear()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Volatile
|
||||
private var initFriendOk = false
|
||||
|
||||
@Volatile
|
||||
private var initFriendGroupOk = false
|
||||
|
||||
@Volatile
|
||||
private var initGroupOk = false
|
||||
|
||||
@@ -116,7 +113,7 @@ internal class ContactUpdaterImpl(
|
||||
/**
|
||||
* Don't use concurrently
|
||||
*/
|
||||
private suspend fun reloadFriendList(registerResp: SvcRespRegister) {
|
||||
override suspend fun reloadFriendList(registerResp: SvcRespRegister) = friendListLock.withLock {
|
||||
if (initFriendOk) {
|
||||
return
|
||||
}
|
||||
@@ -159,6 +156,34 @@ internal class ContactUpdaterImpl(
|
||||
return friendInfos
|
||||
}
|
||||
|
||||
val list = if (friendListCache?.isValid(registerResp) == true) {
|
||||
val list = friendListCache.list
|
||||
logger.info { "Loaded ${list.size} friends from local cache." }
|
||||
|
||||
// For sync bot nick
|
||||
bot.network.sendAndExpect(
|
||||
FriendList.GetFriendGroupList(
|
||||
bot.client, 0, 1, 0, 0
|
||||
)
|
||||
)
|
||||
|
||||
list
|
||||
} else {
|
||||
refreshFriendList().also {
|
||||
updateCacheSeq(it)
|
||||
}
|
||||
}
|
||||
|
||||
for (friendInfoImpl in list) {
|
||||
bot.addNewFriendAndRemoveStranger(friendInfoImpl)
|
||||
}
|
||||
|
||||
initFriendOk = true
|
||||
}
|
||||
|
||||
override suspend fun reloadFriendGroupList() = friendGroupsLock.withLock {
|
||||
if (initFriendGroupOk) return
|
||||
|
||||
suspend fun refreshFriendGroupList(): List<FriendGroupImpl> {
|
||||
logger.info { "Start loading friendGroup list..." }
|
||||
val friendGroupInfos = mutableListOf<FriendGroupImpl>()
|
||||
@@ -191,32 +216,10 @@ internal class ContactUpdaterImpl(
|
||||
return friendGroupInfos
|
||||
}
|
||||
|
||||
val list = if (friendListCache?.isValid(registerResp) == true) {
|
||||
val list = friendListCache.list
|
||||
logger.info { "Loaded ${list.size} friends from local cache." }
|
||||
|
||||
// For sync bot nick
|
||||
bot.network.sendAndExpect(
|
||||
FriendList.GetFriendGroupList(
|
||||
bot.client, 0, 1, 0, 0
|
||||
)
|
||||
)
|
||||
|
||||
list
|
||||
} else {
|
||||
refreshFriendList().also {
|
||||
updateCacheSeq(it)
|
||||
}
|
||||
}
|
||||
|
||||
bot.friendGroups.friendGroups.clear()
|
||||
bot.friendGroups.friendGroups.addAll(refreshFriendGroupList())
|
||||
|
||||
for (friendInfoImpl in list) {
|
||||
bot.addNewFriendAndRemoveStranger(friendInfoImpl)
|
||||
}
|
||||
|
||||
initFriendOk = true
|
||||
initFriendGroupOk = true
|
||||
}
|
||||
|
||||
private suspend fun addGroupToBot(stTroopNum: StTroopNum, stGroupRankInfo: StGroupRankInfo?) = stTroopNum.run {
|
||||
@@ -256,7 +259,7 @@ internal class ContactUpdaterImpl(
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun reloadStrangerList() {
|
||||
override suspend fun reloadStrangerList() = strangerListLock.withLock {
|
||||
if (initStrangerOk) {
|
||||
return
|
||||
}
|
||||
@@ -282,7 +285,7 @@ internal class ContactUpdaterImpl(
|
||||
|
||||
}
|
||||
|
||||
private suspend fun reloadGroupList() {
|
||||
override suspend fun reloadGroupList() = groupListModifyLock.withLock {
|
||||
if (initGroupOk) {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user