From 1ff84a4c912fdf3fdf9c15a9597abdd850a30e1d Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 10 Apr 2020 15:06:06 +0800 Subject: [PATCH] Fix #212 --- .../mirai/qqandroid/contact/GroupImpl.kt | 3 +- .../mirai/qqandroid/contact/MemberImpl.kt | 1 + .../net/mamoe/mirai/qqandroid/contact/util.kt | 25 +++++++++ .../network/protocol/data/proto/OnlinePush.kt | 2 +- .../packet/chat/receive/OnlinePush.kt | 54 +++++++++++-------- 5 files changed, 60 insertions(+), 25 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt index fbfe0779f..42ffbc04c 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt @@ -65,7 +65,8 @@ internal class GroupImpl( ) : Group() { companion object - val lastRecalledMessageRandoms: LockFreeLinkedList = LockFreeLinkedList() + val lastRecalledMessageRandoms: LockFreeCacheList = LockFreeCacheList(16) // events per 3 second + val lastMemberPermissionChangeSequences: LockFreeCacheList = LockFreeCacheList(16) // events per 3 second override val bot: QQAndroidBot by bot.unsafeWeakRef() diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt index 9a0b42624..e964edda4 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt @@ -49,6 +49,7 @@ internal class MemberImpl constructor( ) : Member() { override val group: GroupImpl by group.unsafeWeakRef() + @Suppress("unused") // false positive val lastMessageSequence: AtomicInt = atomic(-1) // region QQ delegate diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt index 09908253d..589370925 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/util.kt @@ -25,6 +25,7 @@ import net.mamoe.mirai.qqandroid.message.ensureSequenceIdAvailable import net.mamoe.mirai.qqandroid.message.firstIsInstanceOrNull import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc +import net.mamoe.mirai.utils.LockFreeLinkedList import net.mamoe.mirai.utils.MiraiExperimentalAPI import net.mamoe.mirai.utils.MiraiInternalAPI @@ -61,3 +62,27 @@ internal fun Contact.logMessageSent(message: Message) { internal fun String.singleLine(): String { return this.replace("\n", """\n""").replace("\r", "") } + + +/** + * Size management isn't atomic. + */ +internal class LockFreeCacheList(private val maxSize: Int) : LockFreeLinkedList() { + override fun addLast(element: E) { + if (size >= maxSize) { + this.removeFirst() + } + + super.addLast(element) + } + + @Deprecated("prohibited", level = DeprecationLevel.HIDDEN) + override fun addAll(iterable: Iterable) { + super.addAll(iterable) + } + + @Deprecated("prohibited", level = DeprecationLevel.HIDDEN) + override fun addAll(iterable: Sequence) { + super.addAll(iterable) + } +} \ No newline at end of file diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/OnlinePush.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/OnlinePush.kt index 5fd26962d..09a9fdf47 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/OnlinePush.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/OnlinePush.kt @@ -47,7 +47,7 @@ internal class OnlinePushTrans : ProtoBuf { @ProtoId(9) val nickName: String = "", @ProtoId(10) val msgData: ByteArray = EMPTY_BYTE_ARRAY, @ProtoId(11) val svrIp: Int = 0, - @ProtoId(12) val extGroupKeyInfo: OnlinePushTrans.ExtGroupKeyInfo? = null, + @ProtoId(12) val extGroupKeyInfo: ExtGroupKeyInfo? = null, @ProtoId(17) val generalFlag: Int = 0 ) : ProtoBuf } \ No newline at end of file diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt index ca8908ac5..616ca0e57 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt @@ -113,9 +113,9 @@ internal class OnlinePush { IncomingPacketFactory("OnlinePush.PbPushTransMsg", "OnlinePush.RespPush") { @OptIn(MiraiInternalAPI::class) - @ExperimentalUnsignedTypes override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): Packet? { val content = this.readProtoBuf(OnlinePushTrans.PbMsgInfo.serializer()) + content.msgData.read { when (content.msgType) { 44 -> { @@ -128,21 +128,33 @@ internal class OnlinePush { } val group = bot.getGroupByUin(content.fromUin) as GroupImpl - if (var5 == 0L && this.remaining == 1L) {//管理员变更 - val newPermission = - if (this.readByte() - .toInt() == 1 - ) MemberPermission.ADMINISTRATOR else MemberPermission.MEMBER + if (group.lastMemberPermissionChangeSequences.remove(content.msgSeq)) { + return null + } - return if (target == bot.id) { - BotGroupPermissionChangeEvent( + if (var5 == 0L && this.remaining == 1L) {//管理员变更 + group.lastMemberPermissionChangeSequences.addLast(content.msgSeq) + val newPermission = + if (this.readByte().toInt() == 1) MemberPermission.ADMINISTRATOR + else MemberPermission.MEMBER + + if (target == bot.id) { + if (group.botPermission == newPermission) { + return null + } + + return BotGroupPermissionChangeEvent( group, group.botPermission.also { group.botPermission = newPermission }, newPermission ) } else { val member = group[target] as MemberImpl - MemberPermissionChangeEvent( + if (member.permission == newPermission) { + return null + } + + return MemberPermissionChangeEvent( member, member.permission.also { member.permission = newPermission }, newPermission @@ -173,21 +185,17 @@ internal class OnlinePush { val groupUin = content.fromUin when (type) { - 0x82 -> { // 2020/4/8: 在这里拿到了一个 Group xxx not found - bot.getGroupByUinOrNull(groupUin)?.let { group -> - val member = group.getOrNull(target) as? MemberImpl ?: return null - return MemberLeaveEvent.Quit(member.also { - group.members.delegate.remove(member) - }) - } + 0x82 -> bot.getGroupByUinOrNull(groupUin)?.let { group -> + val member = group.getOrNull(target) as? MemberImpl ?: return null + return MemberLeaveEvent.Quit(member.also { + group.members.delegate.remove(member) + }) } - 0x83 -> { - bot.getGroupByUin(groupUin).let { group -> - val member = group.getOrNull(target) as? MemberImpl ?: return null - return MemberLeaveEvent.Kick(member.also { - group.members.delegate.remove(member) - }, group.members[operator]) - } + 0x83 -> bot.getGroupByUin(groupUin).let { group -> + val member = group.getOrNull(target) as? MemberImpl ?: return null + return MemberLeaveEvent.Kick(member.also { + group.members.delegate.remove(member) + }, group.members[operator]) } } }