mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-26 16:10:11 +08:00
[mock] Unified contacts data
This commit is contained in:
parent
495542d2a2
commit
cae7b1161c
@ -23,7 +23,9 @@ import net.mamoe.mirai.contact.friendgroup.FriendGroups
|
||||
import net.mamoe.mirai.event.EventChannel
|
||||
import net.mamoe.mirai.event.GlobalEventChannel
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.event.events.*
|
||||
import net.mamoe.mirai.event.events.BotEvent
|
||||
import net.mamoe.mirai.event.events.BotOnlineEvent
|
||||
import net.mamoe.mirai.event.events.BotReloginEvent
|
||||
import net.mamoe.mirai.internal.network.component.ComponentStorage
|
||||
import net.mamoe.mirai.internal.network.component.ConcurrentComponentStorage
|
||||
import net.mamoe.mirai.internal.network.components.EventDispatcher
|
||||
@ -37,15 +39,16 @@ import net.mamoe.mirai.mock.database.MessageDatabase
|
||||
import net.mamoe.mirai.mock.internal.components.MockEventDispatcherImpl
|
||||
import net.mamoe.mirai.mock.internal.contact.*
|
||||
import net.mamoe.mirai.mock.internal.contact.friendfroup.MockFriendGroups
|
||||
import net.mamoe.mirai.mock.internal.contactbase.ContactDatabase
|
||||
import net.mamoe.mirai.mock.internal.serverfs.TmpResourceServerImpl
|
||||
import net.mamoe.mirai.mock.resserver.TmpResourceServer
|
||||
import net.mamoe.mirai.mock.userprofile.UserProfileService
|
||||
import net.mamoe.mirai.mock.utils.NameGenerator
|
||||
import net.mamoe.mirai.mock.utils.broadcastBlocking
|
||||
import net.mamoe.mirai.mock.utils.simpleMemberInfo
|
||||
import net.mamoe.mirai.utils.*
|
||||
import java.util.concurrent.CancellationException
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import net.mamoe.mirai.internal.utils.subLoggerImpl as subLog
|
||||
|
||||
@ -58,22 +61,22 @@ internal class MockBotImpl(
|
||||
override val msgDatabase: MessageDatabase,
|
||||
override val userProfileService: UserProfileService,
|
||||
) : MockBot, Bot, ContactOrBot {
|
||||
@JvmField
|
||||
internal val contactDatabase = ContactDatabase(this)
|
||||
private val botccinfo = contactDatabase.acquireCI(id, nick)
|
||||
|
||||
private val loginBefore = AtomicBoolean(false)
|
||||
override var nickNoEvent: String = nick
|
||||
override var nickNoEvent: String by botccinfo::nick
|
||||
override var nick: String
|
||||
get() = nickNoEvent
|
||||
get() = botccinfo.nick
|
||||
set(value) {
|
||||
val ov = nickNoEvent
|
||||
if (value == ov) return
|
||||
nickNoEvent = value
|
||||
BotNickChangedEvent(this, ov, value).broadcastBlocking()
|
||||
botccinfo.changeNick(value)
|
||||
}
|
||||
|
||||
override var avatarUrl: String
|
||||
get() = asFriend.avatarUrl
|
||||
set(value) {
|
||||
asFriend.mockApi.avatarUrl = value
|
||||
BotAvatarChangedEvent(this).broadcastBlocking()
|
||||
asFriend.changeAvatarUrl(value)
|
||||
}
|
||||
|
||||
override fun avatarUrl(spec: AvatarSpec): String {
|
||||
@ -186,4 +189,9 @@ internal class MockBotImpl(
|
||||
override fun toString(): String {
|
||||
return "MockBot($id)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun MockBot.impl(): MockBotImpl {
|
||||
contract { returns() implies (this@impl is MockBotImpl) }
|
||||
return cast()
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
package net.mamoe.mirai.mock.internal.contact
|
||||
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.contact.AvatarSpec
|
||||
import net.mamoe.mirai.contact.Friend
|
||||
import net.mamoe.mirai.contact.friendgroup.FriendGroup
|
||||
@ -28,13 +27,13 @@ import net.mamoe.mirai.mock.MockBot
|
||||
import net.mamoe.mirai.mock.contact.MockFriend
|
||||
import net.mamoe.mirai.mock.internal.contact.friendfroup.MockFriendGroups
|
||||
import net.mamoe.mirai.mock.internal.contact.roaming.MockRoamingMessages
|
||||
import net.mamoe.mirai.mock.internal.impl
|
||||
import net.mamoe.mirai.mock.internal.msgsrc.OnlineMsgSrcFromFriend
|
||||
import net.mamoe.mirai.mock.internal.msgsrc.OnlineMsgSrcToFriend
|
||||
import net.mamoe.mirai.mock.internal.msgsrc.newMsgSrc
|
||||
import net.mamoe.mirai.mock.utils.broadcastBlocking
|
||||
import net.mamoe.mirai.utils.ExternalResource
|
||||
import net.mamoe.mirai.utils.cast
|
||||
import net.mamoe.mirai.utils.lateinitMutableProperty
|
||||
import java.util.concurrent.CancellationException
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
@ -48,33 +47,15 @@ internal class MockFriendImpl(
|
||||
parentCoroutineContext,
|
||||
bot, id
|
||||
), MockFriend {
|
||||
private val ccinfo = bot.impl().contactDatabase.acquireCI(id, nick)
|
||||
|
||||
override val mockApi: MockFriend.MockApi = object : MockFriend.MockApi {
|
||||
override val contact: MockFriend get() = this@MockFriendImpl
|
||||
|
||||
override var nick: String = nick
|
||||
override var remark: String = remark
|
||||
override var avatarUrl: String
|
||||
get() = this@MockFriendImpl._avatarUrl
|
||||
set(value) {
|
||||
this@MockFriendImpl._avatarUrl = value
|
||||
bot.groups.forEach { g ->
|
||||
val mems = if (this@MockFriendImpl.id == bot.id) {
|
||||
sequenceOf(g.botAsMember)
|
||||
} else g.members.asSequence().filter {
|
||||
it.id == this@MockFriendImpl.id
|
||||
}
|
||||
mems.forEach { m ->
|
||||
m.cast<MockNormalMemberImpl>().avatarUrl = value
|
||||
}
|
||||
}
|
||||
if (this@MockFriendImpl.id == bot.id) {
|
||||
sequenceOf(bot.asStranger)
|
||||
} else {
|
||||
bot.strangers.asSequence().filter { s ->
|
||||
s.id == this@MockFriendImpl.id
|
||||
}
|
||||
}.forEach { it.cast<MockStrangerImpl>().avatarUrl = value }
|
||||
}
|
||||
|
||||
override var nick: String by ccinfo::nick
|
||||
override var avatarUrl: String by ccinfo::avatarUrl
|
||||
|
||||
override var friendGroupId: Int = 0
|
||||
}
|
||||
@ -82,15 +63,13 @@ internal class MockFriendImpl(
|
||||
override val friendGroup: FriendGroup
|
||||
get() = bot.friendGroups.cast<MockFriendGroups>().findOrDefault(mockApi.friendGroupId)
|
||||
|
||||
private var _avatarUrl: String by lateinitMutableProperty { runBlocking { MockImage.random(bot).getUrl(bot) } }
|
||||
override val avatarUrl: String get() = _avatarUrl
|
||||
override val avatarUrl: String get() = ccinfo.avatarUrl
|
||||
internal fun initAvatarUrl(v: String) {
|
||||
_avatarUrl = v
|
||||
ccinfo.avatarUrl = v
|
||||
}
|
||||
|
||||
override fun changeAvatarUrl(newAvatar: String) {
|
||||
mockApi.avatarUrl = newAvatar
|
||||
FriendAvatarChangedEvent(this).broadcastBlocking()
|
||||
ccinfo.changeAvatarUrl(newAvatar)
|
||||
}
|
||||
|
||||
override fun avatarUrl(spec: AvatarSpec): String {
|
||||
@ -98,12 +77,9 @@ internal class MockFriendImpl(
|
||||
}
|
||||
|
||||
override var nick: String
|
||||
get() = mockApi.nick
|
||||
get() = ccinfo.nick
|
||||
set(value) {
|
||||
val ov = mockApi.nick
|
||||
if (ov == value) return
|
||||
mockApi.nick = value
|
||||
FriendNickChangedEvent(this, ov, value).broadcastBlocking()
|
||||
ccinfo.changeNick(value)
|
||||
}
|
||||
|
||||
override var remark: String
|
||||
|
@ -10,7 +10,6 @@
|
||||
package net.mamoe.mirai.mock.internal.contact
|
||||
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.contact.*
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.event.events.*
|
||||
@ -24,13 +23,13 @@ import net.mamoe.mirai.mock.contact.MockGroup
|
||||
import net.mamoe.mirai.mock.contact.MockNormalMember
|
||||
import net.mamoe.mirai.mock.contact.active.MockMemberActive
|
||||
import net.mamoe.mirai.mock.internal.contact.active.MockMemberActiveImpl
|
||||
import net.mamoe.mirai.mock.internal.impl
|
||||
import net.mamoe.mirai.mock.internal.msgsrc.OnlineMsgSrcFromGroup
|
||||
import net.mamoe.mirai.mock.internal.msgsrc.OnlineMsgSrcToTemp
|
||||
import net.mamoe.mirai.mock.internal.msgsrc.newMsgSrc
|
||||
import net.mamoe.mirai.mock.utils.broadcastBlocking
|
||||
import net.mamoe.mirai.utils.cast
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
import net.mamoe.mirai.utils.lateinitMutableProperty
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
import kotlin.math.max
|
||||
@ -52,18 +51,19 @@ internal class MockNormalMemberImpl(
|
||||
parentCoroutineContext, bot,
|
||||
id
|
||||
), MockNormalMember {
|
||||
override var avatarUrl: String by lateinitMutableProperty {
|
||||
bot.getFriend(id)?.let { return@lateinitMutableProperty it.avatarUrl }
|
||||
runBlocking { MockImage.random(bot).getUrl(bot) }
|
||||
private val ccinfo = bot.impl().contactDatabase.let {
|
||||
if (nick.isEmpty()) it.acquireCI(id)
|
||||
else it.acquireCI(id, nick)
|
||||
}
|
||||
|
||||
override val avatarUrl: String get() = ccinfo.avatarUrl
|
||||
|
||||
override fun avatarUrl(spec: AvatarSpec): String {
|
||||
return avatarUrl
|
||||
}
|
||||
|
||||
override fun changeAvatarUrl(newAvatar: String) {
|
||||
bot.getFriend(id)?.let { return it.changeAvatarUrl(newAvatar) }
|
||||
this.avatarUrl = newAvatar
|
||||
ccinfo.changeAvatarUrl(newAvatar)
|
||||
}
|
||||
|
||||
private inline fun <T> crossFriendAccess(
|
||||
@ -80,11 +80,7 @@ internal class MockNormalMemberImpl(
|
||||
override var joinTimestamp: Int = joinTimestamp
|
||||
override var muteTimeEndTimestamp: Long = currentTimeSeconds() + muteTimeRemaining
|
||||
|
||||
override var nick: String = nick
|
||||
get() = crossFriendAccess(ifExists = { it.nick }, ifNotExists = { field })
|
||||
set(value) {
|
||||
crossFriendAccess(ifExists = { it.mockApi.nick = value }, ifNotExists = { field = value })
|
||||
}
|
||||
override var nick: String by ccinfo::nick
|
||||
|
||||
override var remark: String = remark
|
||||
get() = crossFriendAccess(ifExists = { it.remark }, ifNotExists = { field })
|
||||
@ -95,15 +91,7 @@ internal class MockNormalMemberImpl(
|
||||
override var permission: MemberPermission = permission
|
||||
override var nameCard: String = nameCard
|
||||
override var specialTitle: String = specialTitle
|
||||
override var avatarUrl: String
|
||||
get() = this@MockNormalMemberImpl.avatarUrl
|
||||
set(value) {
|
||||
this@MockNormalMemberImpl.avatarUrl = value
|
||||
|
||||
bot.getFriend(this@MockNormalMemberImpl.id)?.let { f ->
|
||||
f.mockApi.avatarUrl = value
|
||||
}
|
||||
}
|
||||
override var avatarUrl: String by ccinfo::avatarUrl
|
||||
}
|
||||
|
||||
override val permission: MemberPermission
|
||||
|
@ -10,7 +10,6 @@
|
||||
package net.mamoe.mirai.mock.internal.contact
|
||||
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.contact.AvatarSpec
|
||||
import net.mamoe.mirai.contact.Stranger
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
@ -21,11 +20,11 @@ import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.OnlineMessageSource
|
||||
import net.mamoe.mirai.mock.MockBot
|
||||
import net.mamoe.mirai.mock.contact.MockStranger
|
||||
import net.mamoe.mirai.mock.internal.impl
|
||||
import net.mamoe.mirai.mock.internal.msgsrc.OnlineMsgSrcFromStranger
|
||||
import net.mamoe.mirai.mock.internal.msgsrc.OnlineMsgSrcToStranger
|
||||
import net.mamoe.mirai.mock.internal.msgsrc.newMsgSrc
|
||||
import net.mamoe.mirai.utils.cast
|
||||
import net.mamoe.mirai.utils.lateinitMutableProperty
|
||||
import java.util.concurrent.CancellationException
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
@ -37,34 +36,23 @@ internal class MockStrangerImpl(
|
||||
remark: String,
|
||||
nick: String
|
||||
) : AbstractMockContact(parentCoroutineContext, bot, id), MockStranger {
|
||||
private val ccinfo = bot.impl().contactDatabase.acquireCI(id, nick)
|
||||
|
||||
override val mockApi: MockStranger.MockApi = object : MockStranger.MockApi {
|
||||
override val contact: MockStranger get() = this@MockStrangerImpl
|
||||
override var nick: String = nick
|
||||
override var nick: String by ccinfo::nick
|
||||
override var remark: String = remark
|
||||
override var avatarUrl: String
|
||||
get() = this@MockStrangerImpl.avatarUrl
|
||||
set(value) {
|
||||
this@MockStrangerImpl.avatarUrl = value
|
||||
override var avatarUrl: String by ccinfo::avatarUrl
|
||||
}
|
||||
|
||||
bot.getFriend(this@MockStrangerImpl.id)?.let { f ->
|
||||
f.mockApi.avatarUrl = value
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
override var avatarUrl: String by lateinitMutableProperty {
|
||||
bot.getFriend(id)?.let { return@lateinitMutableProperty it.avatarUrl }
|
||||
runBlocking { MockImage.random(bot).getUrl(bot) }
|
||||
}
|
||||
override val avatarUrl: String get() = ccinfo.avatarUrl
|
||||
|
||||
override fun avatarUrl(spec: AvatarSpec): String {
|
||||
return avatarUrl
|
||||
}
|
||||
|
||||
override fun changeAvatarUrl(newAvatar: String) {
|
||||
this.avatarUrl = newAvatar
|
||||
bot.getFriend(id)?.let { return it.changeAvatarUrl(newAvatar) }
|
||||
ccinfo.changeAvatarUrl(newAvatar)
|
||||
}
|
||||
|
||||
override val nick: String
|
||||
|
33
mirai-core-mock/src/internal/contactbase/ContactDatabase.kt
Normal file
33
mirai-core-mock/src/internal/contactbase/ContactDatabase.kt
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.mock.internal.contactbase
|
||||
|
||||
import net.mamoe.mirai.mock.internal.MockBotImpl
|
||||
import net.mamoe.mirai.utils.ConcurrentHashMap
|
||||
|
||||
internal class ContactDatabase(
|
||||
private val bot: MockBotImpl,
|
||||
) {
|
||||
val contacts = ConcurrentHashMap<Long, ContactInfo>()
|
||||
|
||||
fun acquireCI(id: Long): ContactInfo {
|
||||
return contacts.computeIfAbsent(id) {
|
||||
ContactInfo(bot, id, bot.nameGenerator.nextFriendName())
|
||||
}
|
||||
}
|
||||
|
||||
fun acquireCI(id: Long, name: String): ContactInfo {
|
||||
return contacts.computeIfAbsent(id) {
|
||||
ContactInfo(bot, id, name)
|
||||
}.also { rsp ->
|
||||
if (rsp.nick != name) rsp.changeNick(name)
|
||||
}
|
||||
}
|
||||
}
|
58
mirai-core-mock/src/internal/contactbase/ContactInfo.kt
Normal file
58
mirai-core-mock/src/internal/contactbase/ContactInfo.kt
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.mock.internal.contactbase
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.event.events.BotAvatarChangedEvent
|
||||
import net.mamoe.mirai.event.events.BotNickChangedEvent
|
||||
import net.mamoe.mirai.event.events.FriendAvatarChangedEvent
|
||||
import net.mamoe.mirai.event.events.FriendNickChangedEvent
|
||||
import net.mamoe.mirai.mock.internal.MockBotImpl
|
||||
import net.mamoe.mirai.mock.internal.contact.MockImage
|
||||
import net.mamoe.mirai.mock.utils.broadcastBlocking
|
||||
import net.mamoe.mirai.utils.lateinitMutableProperty
|
||||
|
||||
internal class ContactInfo(
|
||||
private val declaredBot: MockBotImpl,
|
||||
@JvmField val id: Long,
|
||||
@JvmField var nick: String,
|
||||
) {
|
||||
var avatarUrl: String by lateinitMutableProperty {
|
||||
runBlocking { MockImage.random(declaredBot).getUrl(declaredBot) }
|
||||
}
|
||||
|
||||
fun changeAvatarUrl(newAvatar: String) {
|
||||
avatarUrl = newAvatar
|
||||
if (declaredBot.id == id) {
|
||||
BotAvatarChangedEvent(declaredBot).broadcastBlocking()
|
||||
return
|
||||
}
|
||||
declaredBot.getFriend(id)?.let {
|
||||
FriendAvatarChangedEvent(it).broadcastBlocking()
|
||||
}
|
||||
}
|
||||
|
||||
fun changeNick(newNick: String) {
|
||||
if (id == declaredBot.id) {
|
||||
val o = nick
|
||||
nick = newNick
|
||||
BotNickChangedEvent(declaredBot, o, newNick).broadcastBlocking()
|
||||
return
|
||||
}
|
||||
val friend = declaredBot.getFriend(id)
|
||||
if (friend == null) {
|
||||
nick = newNick
|
||||
return
|
||||
}
|
||||
val o = nick
|
||||
nick = newNick
|
||||
FriendNickChangedEvent(friend, o, newNick).broadcastBlocking()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user