This commit is contained in:
Him188 2020-04-10 15:06:06 +08:00
parent 94557a2a33
commit 1ff84a4c91
5 changed files with 60 additions and 25 deletions

View File

@ -65,7 +65,8 @@ internal class GroupImpl(
) : Group() {
companion object
val lastRecalledMessageRandoms: LockFreeLinkedList<Int> = LockFreeLinkedList()
val lastRecalledMessageRandoms: LockFreeCacheList<Int> = LockFreeCacheList(16) // events per 3 second
val lastMemberPermissionChangeSequences: LockFreeCacheList<Int> = LockFreeCacheList(16) // events per 3 second
override val bot: QQAndroidBot by bot.unsafeWeakRef()

View File

@ -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

View File

@ -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<E>(private val maxSize: Int) : LockFreeLinkedList<E>() {
override fun addLast(element: E) {
if (size >= maxSize) {
this.removeFirst()
}
super.addLast(element)
}
@Deprecated("prohibited", level = DeprecationLevel.HIDDEN)
override fun addAll(iterable: Iterable<E>) {
super.addAll(iterable)
}
@Deprecated("prohibited", level = DeprecationLevel.HIDDEN)
override fun addAll(iterable: Sequence<E>) {
super.addAll(iterable)
}
}

View File

@ -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
}

View File

@ -113,9 +113,9 @@ internal class OnlinePush {
IncomingPacketFactory<Packet?>("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<Unit> {
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])
}
}
}