diff --git a/mirai-core-api/src/commonMain/kotlin/contact/ContactList.kt b/mirai-core-api/src/commonMain/kotlin/contact/ContactList.kt index 6be74c496..daa75840b 100644 --- a/mirai-core-api/src/commonMain/kotlin/contact/ContactList.kt +++ b/mirai-core-api/src/commonMain/kotlin/contact/ContactList.kt @@ -12,8 +12,9 @@ package net.mamoe.mirai.contact import net.mamoe.mirai.utils.LockFreeLinkedList -import net.mamoe.mirai.utils.asSequence -import kotlin.jvm.JvmField +import net.mamoe.mirai.utils.MiraiInternalApi +import net.mamoe.mirai.utils.PlannedRemoval +import java.util.concurrent.ConcurrentLinkedQueue /** @@ -23,27 +24,27 @@ import kotlin.jvm.JvmField */ @Suppress("unused") public class ContactList -internal constructor(@JvmField internal val delegate: LockFreeLinkedList) : Collection { +internal constructor(@JvmField @MiraiInternalApi public val delegate: ConcurrentLinkedQueue) : + Collection by delegate { + internal constructor(collection: Collection) : this(ConcurrentLinkedQueue(collection)) + internal constructor() : this(ConcurrentLinkedQueue()) - public operator fun get(id: Long): C = - delegate.asSequence().firstOrNull { it.id == id } ?: throw NoSuchElementException("Contact id $id") + @PlannedRemoval("2.0-M2") + @Deprecated("Use get", ReplaceWith("get(id)")) + public fun getOrNull(id: Long): C? = get(id) - public fun getOrNull(id: Long): C? = delegate.getOrNull(id) + public operator fun get(id: Long): C? = delegate.firstOrNull { it.id == id } + public fun remove(id: Long): Boolean = delegate.removeAll { it.id == id } + public operator fun contains(id: Long): Boolean = get(id) != null - public override val size: Int get() = delegate.size - public override operator fun contains(element: C): Boolean = delegate.contains(element) - public operator fun contains(id: Long): Boolean = delegate.getOrNull(id) != null - public override fun containsAll(elements: Collection): Boolean = elements.all { contains(it) } - public override fun isEmpty(): Boolean = delegate.isEmpty() - - public override fun toString(): String = - delegate.asSequence().joinToString(separator = ", ", prefix = "ContactList(", postfix = ")") - - public override fun iterator(): Iterator { - return this.delegate.asSequence().iterator() - } + override fun toString(): String = delegate.joinToString(separator = ", ", prefix = "ContactList(", postfix = ")") + override fun equals(other: Any?): Boolean = other is ContactList<*> && delegate == other.delegate + override fun hashCode(): Int = delegate.hashCode() } +@Deprecated("x", ReplaceWith("this.add(c)")) +internal fun ConcurrentLinkedQueue.addLast(c: C): Boolean = this.add(c) + /** * ID 列表的字符串表示. * 如: diff --git a/mirai-core/src/commonMain/kotlin/MiraiImpl.kt b/mirai-core/src/commonMain/kotlin/MiraiImpl.kt index 5c9c5a834..7cab3f5a1 100644 --- a/mirai-core/src/commonMain/kotlin/MiraiImpl.kt +++ b/mirai-core/src/commonMain/kotlin/MiraiImpl.kt @@ -672,7 +672,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor { blackList = blackList ).sendWithoutExpect() @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") - bot.friends.delegate.addLast(_lowLevelNewFriend(bot, object : FriendInfo { + bot.friends.delegate.add(_lowLevelNewFriend(bot, object : FriendInfo { override val uin: Long get() = fromId override val nick: String get() = fromNick override val remark: String get() = "" @@ -727,9 +727,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor { } if (accept ?: return@run) - groups[groupId].apply { - @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") - members.delegate.addLast(newMember(object : MemberInfo { + groups[groupId]?.apply { + members.delegate.add(newMember(object : MemberInfo { override val nameCard: String get() = "" override val permission: MemberPermission get() = MemberPermission.MEMBER override val specialTitle: String get() = "" diff --git a/mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt b/mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt index 3df2bcad1..c29e5601b 100644 --- a/mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt +++ b/mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt @@ -63,7 +63,7 @@ internal abstract class QQAndroidBotBase constructor( inline val json get() = configuration.json - override val friends: ContactList = ContactList(LockFreeLinkedList()) + override val friends: ContactList = ContactList() override lateinit var nick: String @@ -99,7 +99,7 @@ internal abstract class QQAndroidBotBase constructor( return QQAndroidBotNetworkHandler(coroutineContext, this as QQAndroidBot) } - override val groups: ContactList = ContactList(LockFreeLinkedList()) + override val groups: ContactList = ContactList() @JvmField val groupListModifyLock = Mutex() diff --git a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt index a7f220f7b..3dc272333 100644 --- a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt @@ -42,6 +42,7 @@ import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.data.* import net.mamoe.mirai.utils.* import java.io.InputStream +import java.util.concurrent.ConcurrentLinkedQueue import kotlin.contracts.contract import kotlin.coroutines.CoroutineContext import kotlin.time.ExperimentalTime @@ -97,7 +98,7 @@ internal class GroupImpl( owner = member } } - }.toLockFreeLinkedList()) + }.mapTo(ConcurrentLinkedQueue()) { it }) internal var _name: String = groupInfo.name private var _announcement: String = groupInfo.memo @@ -220,7 +221,7 @@ internal class GroupImpl( ).sendAndExpect() check(response.errorCode == 0) { "Group.quit failed: $response".also { - bot.groups.delegate.addLast(this@GroupImpl) + bot.groups.delegate.add(this@GroupImpl) } } } diff --git a/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt index e53221783..961566e79 100644 --- a/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/network/QQAndroidBotNetworkHandler.kt @@ -252,7 +252,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo totalFriendCount = data.totalFriendCount data.friendList.forEach { // atomic - bot.friends.delegate.addLast( + bot.friends.delegate.add( FriendImpl(bot, bot.coroutineContext, it.friendUin, FriendInfoImpl(it)) ).also { currentFriendCount++ } } @@ -268,7 +268,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo suspend fun StTroopNum.reloadGroup() { retryCatching(3) { - bot.groups.delegate.addLast( + bot.groups.delegate.add( GroupImpl( bot = bot, coroutineContext = bot.coroutineContext, @@ -314,10 +314,10 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo CancellationException("re-init").let { reInitCancellationException -> if (!initFriendOk) { - bot.friends.delegate.clear { it.cancel(reInitCancellationException) } + bot.friends.delegate.removeAll { it.cancel(reInitCancellationException); true } } if (!initGroupOk) { - bot.groups.delegate.clear { it.cancel(reInitCancellationException) } + bot.groups.delegate.removeAll { it.cancel(reInitCancellationException); true } } } diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt index 5863cef9e..5647eb5f3 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbGetMsg.kt @@ -141,9 +141,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory owner.checkIsMemberImpl().permission = MemberPermission.OWNER - group.members.delegate.addLast(owner) + group.members.delegate.add(owner) results.add(MemberJoinEvent.Retrieve(owner)) } if (newOwner.permission != MemberPermission.OWNER) { @@ -239,7 +239,8 @@ internal object OnlinePushPbPushTransMsg : } 3, 0x83 -> bot.getGroupByUin(groupUin).let { group -> if (target == bot.id) { - return BotLeaveEvent.Kick(group.members[operator]).also { + val member = group.members[operator] ?: return@let null + return BotLeaveEvent.Kick(member).also { group.cancel(CancellationException("Being kicked")) bot.groups.delegate.remove(group) } diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.ReqPush.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.ReqPush.kt index ebdbfcfa5..83872d43b 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.ReqPush.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/OnlinePush.ReqPush.kt @@ -462,7 +462,7 @@ internal object Transformers528 : Map by mapOf( override val nick: String get() = body.msgAddFrdNotify.fuinNick override val remark: String get() = "" }) - bot.friends.delegate.addLast(new) + bot.friends.delegate.add(new) return@lambda528 sequenceOf(FriendAddEvent(new)) }, 0xE2L to lambda528 { _ ->