This commit is contained in:
Him188 2020-03-29 14:28:32 +08:00
parent f223971c4e
commit 2f063987a9
2 changed files with 47 additions and 22 deletions

View File

@ -12,6 +12,8 @@
package net.mamoe.mirai.qqandroid.contact
import kotlinx.atomicfu.AtomicInt
import kotlinx.atomicfu.atomic
import kotlinx.io.core.Closeable
import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.Contact
@ -37,6 +39,8 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.toUHexString
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic
@ -47,12 +51,23 @@ internal inline class FriendInfoImpl(
override val uin: Long get() = jceFriendInfo.friendUin
}
@OptIn(ExperimentalContracts::class)
internal fun QQ.checkIsQQImpl(): QQImpl {
contract {
returns() implies (this@checkIsQQImpl is QQImpl)
}
check(this is QQImpl) { "A QQ instance is not instance of QQImpl. Don't interlace two protocol implementations together!" }
return this
}
internal class QQImpl(
bot: QQAndroidBot,
override val coroutineContext: CoroutineContext,
override val id: Long,
private val friendInfo: FriendInfo
) : QQ() {
var lastMessageSequence: AtomicInt = atomic(-1)
override val bot: QQAndroidBot by bot.unsafeWeakRef()
override val nick: String
get() = friendInfo.nick
@ -68,12 +83,12 @@ internal class QQImpl(
bot.network.run {
check(
MessageSvc.PbSendMsg.ToFriend(
bot.client,
id,
event.message
) {
source = it
}
bot.client,
id,
event.message
) {
source = it
}
.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS
) { "send message failed" }
}

View File

@ -11,6 +11,7 @@
package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
import kotlinx.atomicfu.loop
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.*
import kotlinx.io.core.ByteReadPacket
@ -19,16 +20,15 @@ import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.qqandroid.network.MultiPacketByIterable
import net.mamoe.mirai.qqandroid.network.Packet
import net.mamoe.mirai.event.events.BotJoinGroupEvent
import net.mamoe.mirai.event.events.BotOfflineEvent
import net.mamoe.mirai.event.events.MemberJoinEvent
import net.mamoe.mirai.getFriendOrNull
import net.mamoe.mirai.message.FriendMessage
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.qqandroid.contact.GroupImpl
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.contact.GroupImpl
import net.mamoe.mirai.qqandroid.contact.checkIsQQImpl
import net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
import net.mamoe.mirai.qqandroid.io.serialization.toByteArray
@ -37,6 +37,8 @@ import net.mamoe.mirai.qqandroid.message.MessageSourceFromSendFriend
import net.mamoe.mirai.qqandroid.message.MessageSourceFromSendGroup
import net.mamoe.mirai.qqandroid.message.toMessageChain
import net.mamoe.mirai.qqandroid.message.toRichTextElems
import net.mamoe.mirai.qqandroid.network.MultiPacketByIterable
import net.mamoe.mirai.qqandroid.network.Packet
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushForceOffline
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPushNotify
@ -195,9 +197,8 @@ internal class MessageSvc {
bot.groups.delegate.addLast(newGroup)
return@mapNotNull BotJoinGroupEvent(newGroup)
} else {
if (group == null) {
return@mapNotNull null
}
group ?: return@mapNotNull null
if (group.members.contains(msg.msgHead.authUin)) {
return@mapNotNull null
}
@ -207,21 +208,30 @@ internal class MessageSvc {
override val specialTitle: String get() = ""
override val muteTimestamp: Int get() = 0
override val uin: Long get() = msg.msgHead.authUin
override val nick: String
get() = msg.msgHead.authNick.takeIf { it.isNotEmpty() }
?: msg.msgHead.fromNick
override val nick: String = msg.msgHead.authNick.takeIf { it.isNotEmpty() }
?: msg.msgHead.fromNick
}).also { group.members.delegate.addLast(it) })
}
}
166 -> {
val friend = bot.getFriendOrNull(msg.msgHead.fromUin) ?: return@mapNotNull null
return@mapNotNull when {
msg.msgHead.fromUin == bot.uin -> null
!bot.firstLoginSucceed -> null
else -> FriendMessage(
friend,
msg.toMessageChain()
)
friend.checkIsQQImpl()
if (msg.msgHead.fromUin == bot.uin || !bot.firstLoginSucceed) {
return@mapNotNull null
}
friend.lastMessageSequence.loop { instant ->
if (msg.msgHead.msgSeq > instant) {
println("bigger")
if (friend.lastMessageSequence.compareAndSet(instant, msg.msgHead.msgSeq)) {
println("set ok")
return@mapNotNull FriendMessage(
friend,
msg.toMessageChain()
)
}
} else return@mapNotNull null
}
}
else -> return@mapNotNull null