mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-30 19:00:33 +08:00
parent
c934ff5b89
commit
28249b317c
@ -35,6 +35,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcP
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.createToGroup
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.voice.PttStore
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.list.ProfileService
|
||||
import net.mamoe.mirai.internal.utils.GroupPkgMsgParsingCache
|
||||
import net.mamoe.mirai.internal.utils.MiraiPlatformUtils
|
||||
import net.mamoe.mirai.internal.utils.estimateLength
|
||||
import net.mamoe.mirai.internal.utils.toUHexString
|
||||
@ -460,4 +461,6 @@ internal class GroupImpl(
|
||||
|
||||
|
||||
override fun toString(): String = "Group($id)"
|
||||
|
||||
val groupPkgMsgParsingCache = GroupPkgMsgParsingCache()
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.HummerCommelem
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgOnlinePush
|
||||
import net.mamoe.mirai.internal.utils.*
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
|
||||
@ -234,24 +235,52 @@ internal fun MsgComm.Msg.toMessageChain(
|
||||
isTemp: Boolean = false
|
||||
): MessageChain = toMessageChain(bot, bot.id, groupIdOrZero, onlineSource, isTemp)
|
||||
|
||||
internal fun List<MsgOnlinePush.PbPushMsg>.toMessageChain(
|
||||
bot: Bot,
|
||||
groupIdOrZero: Long,
|
||||
onlineSource: Boolean,
|
||||
isTemp: Boolean = false
|
||||
): MessageChain = toMessageChain(bot, bot.id, groupIdOrZero, onlineSource, isTemp)
|
||||
|
||||
@JvmName("toMessageChain1")
|
||||
internal fun List<MsgOnlinePush.PbPushMsg>.toMessageChain(
|
||||
bot: Bot?,
|
||||
botId: Long,
|
||||
groupIdOrZero: Long,
|
||||
onlineSource: Boolean,
|
||||
isTemp: Boolean = false
|
||||
): MessageChain = map{it.msg}.toMessageChain(bot, botId, groupIdOrZero, onlineSource, isTemp)
|
||||
|
||||
internal fun MsgComm.Msg.toMessageChain(
|
||||
bot: Bot?,
|
||||
botId: Long,
|
||||
groupIdOrZero: Long,
|
||||
onlineSource: Boolean,
|
||||
isTemp: Boolean = false
|
||||
): MessageChain {
|
||||
val elements = this.msgBody.richText.elems
|
||||
): MessageChain = listOf(this).toMessageChain(bot, botId, groupIdOrZero, onlineSource, isTemp)
|
||||
|
||||
val pptMsg = msgBody.richText.ptt?.run {
|
||||
internal fun List<MsgComm.Msg>.toMessageChain(
|
||||
bot: Bot?,
|
||||
botId: Long,
|
||||
groupIdOrZero: Long,
|
||||
onlineSource: Boolean,
|
||||
isTemp: Boolean = false
|
||||
): MessageChain {
|
||||
val elements = this.flatMap { it.msgBody.richText.elems }
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
val ppts = buildList<Message> {
|
||||
this@toMessageChain.forEach { msg ->
|
||||
msg.msgBody.richText.ptt?.run {
|
||||
// when (fileType) {
|
||||
// 4 -> Voice(String(fileName), fileMd5, fileSize.toLong(),String(downPara))
|
||||
// else -> null
|
||||
// }
|
||||
Voice(String(fileName), fileMd5, fileSize.toLong(), format, String(downPara))
|
||||
add(Voice(String(fileName), fileMd5, fileSize.toLong(), format, String(downPara)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buildMessageChain(elements.size + 1 + if (pptMsg == null) 0 else 1) {
|
||||
return buildMessageChain(elements.size + 1 + ppts.size) {
|
||||
if (onlineSource) {
|
||||
checkNotNull(bot) { "bot is null" }
|
||||
when {
|
||||
@ -263,7 +292,6 @@ internal fun MsgComm.Msg.toMessageChain(
|
||||
+OfflineMessageSourceImplByMsg(this@toMessageChain, botId)
|
||||
}
|
||||
elements.joinToMessageChain(groupIdOrZero, botId, this)
|
||||
pptMsg?.let(::add)
|
||||
}.cleanupRubbishMessageElements()
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
import net.mamoe.mirai.message.data.OnlineMessageSource
|
||||
import net.mamoe.mirai.utils.mapToIntArray
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
internal interface MessageSourceInternal {
|
||||
@ -64,44 +65,44 @@ internal suspend inline fun Message.ensureSequenceIdAvailable() {
|
||||
|
||||
internal class MessageSourceFromFriendImpl(
|
||||
override val bot: Bot,
|
||||
val msg: MsgComm.Msg
|
||||
val msg: List<MsgComm.Msg>
|
||||
) : OnlineMessageSource.Incoming.FromFriend(), MessageSourceInternal {
|
||||
override val sequenceIds: IntArray get() = intArrayOf(msg.msgHead.msgSeq)
|
||||
override val sequenceIds: IntArray get() = msg.mapToIntArray { it.msgHead.msgSeq }
|
||||
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
|
||||
override val ids: IntArray get() = sequenceIds// msg.msgBody.richText.attr!!.random
|
||||
override val internalIds: IntArray get() = intArrayOf(msg.msgBody.richText.attr!!.random)
|
||||
override val time: Int get() = msg.msgHead.msgTime
|
||||
override val internalIds: IntArray get() = msg.mapToIntArray { it.msgBody.richText.attr!!.random }
|
||||
override val time: Int get() = msg.first().msgHead.msgTime
|
||||
override val originalMessage: MessageChain by lazy { msg.toMessageChain(bot, bot.id, 0, false) }
|
||||
override val sender: Friend get() = bot.getFriendOrFail(msg.msgHead.fromUin)
|
||||
override val sender: Friend get() = bot.getFriendOrFail(msg.first().msgHead.fromUin)
|
||||
|
||||
private val jceData by lazy { msg.toJceDataFriendOrTemp(internalIds) }
|
||||
|
||||
override fun toJceData(): ImMsgBody.SourceMsg = jceData
|
||||
}
|
||||
|
||||
private fun MsgComm.Msg.toJceDataFriendOrTemp(ids: IntArray): ImMsgBody.SourceMsg {
|
||||
val elements = msgBody.richText.elems.toMutableList().also {
|
||||
private fun List<MsgComm.Msg>.toJceDataFriendOrTemp(ids: IntArray): ImMsgBody.SourceMsg {
|
||||
val elements = flatMap {it.msgBody.richText.elems}.toMutableList().also {
|
||||
if (it.last().elemFlags2 == null) it.add(ImMsgBody.Elem(elemFlags2 = ImMsgBody.ElemFlags2()))
|
||||
}
|
||||
return ImMsgBody.SourceMsg(
|
||||
origSeqs = intArrayOf(this.msgHead.msgSeq),
|
||||
senderUin = this.msgHead.fromUin,
|
||||
toUin = this.msgHead.toUin,
|
||||
origSeqs = mapToIntArray { it.msgHead.msgSeq },
|
||||
senderUin = first().msgHead.fromUin,
|
||||
toUin = first().msgHead.toUin,
|
||||
flag = 1,
|
||||
elems = this.msgBody.richText.elems,
|
||||
elems = flatMap{it.msgBody.richText.elems},
|
||||
type = 0,
|
||||
time = this.msgHead.msgTime,
|
||||
time = this.first().msgHead.msgTime,
|
||||
pbReserve = SourceMsg.ResvAttr(
|
||||
origUids = ids.map { it.toLong() and 0xFFFF_FFFF }
|
||||
).toByteArray(SourceMsg.ResvAttr.serializer()),
|
||||
srcMsg = MsgComm.Msg(
|
||||
msgHead = MsgComm.MsgHead(
|
||||
fromUin = this.msgHead.fromUin, // qq
|
||||
toUin = this.msgHead.toUin, // group
|
||||
msgType = this.msgHead.msgType, // 82?
|
||||
c2cCmd = this.msgHead.c2cCmd,
|
||||
msgSeq = this.msgHead.msgSeq,
|
||||
msgTime = this.msgHead.msgTime,
|
||||
fromUin = this.first().msgHead.fromUin, // qq
|
||||
toUin = this.first().msgHead.toUin, // group
|
||||
msgType = this.first().msgHead.msgType, // 82?
|
||||
c2cCmd = this.first().msgHead.c2cCmd,
|
||||
msgSeq = this.first().msgHead.msgSeq,
|
||||
msgTime = this.first().msgHead.msgTime,
|
||||
msgUid = ids.single().toLong() and 0xFFFF_FFFF, // ok
|
||||
// groupInfo = MsgComm.GroupInfo(groupCode = this.msgHead.groupInfo.groupCode),
|
||||
isSrcMsg = true
|
||||
@ -117,16 +118,24 @@ private fun MsgComm.Msg.toJceDataFriendOrTemp(ids: IntArray): ImMsgBody.SourceMs
|
||||
|
||||
internal class MessageSourceFromTempImpl(
|
||||
override val bot: Bot,
|
||||
private val msg: MsgComm.Msg
|
||||
private val msg: List<MsgComm.Msg>
|
||||
) : OnlineMessageSource.Incoming.FromTemp(), MessageSourceInternal {
|
||||
override val sequenceIds: IntArray get() = intArrayOf(msg.msgHead.msgSeq)
|
||||
override val internalIds: IntArray get() = intArrayOf(msg.msgBody.richText.attr!!.random)
|
||||
override val sequenceIds: IntArray get() = msg.mapToIntArray { it.msgHead.msgSeq }
|
||||
override val internalIds: IntArray get() = msg.mapToIntArray{it.msgBody.richText.attr!!.random }
|
||||
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
|
||||
override val ids: IntArray get() = sequenceIds//
|
||||
override val time: Int get() = msg.msgHead.msgTime
|
||||
override val originalMessage: MessageChain by lazy { msg.toMessageChain(bot, 0, false) }
|
||||
override val time: Int get() = msg.first().msgHead.msgTime
|
||||
override val originalMessage: MessageChain by lazy {
|
||||
msg.toMessageChain(
|
||||
bot,
|
||||
bot.id,
|
||||
groupIdOrZero = 0,
|
||||
onlineSource = false,
|
||||
isTemp = false,
|
||||
)
|
||||
}
|
||||
override val sender: Member
|
||||
get() = with(msg.msgHead) {
|
||||
get() = with(msg.first().msgHead) {
|
||||
bot.getGroupOrFail(c2cTmpMsgHead!!.groupUin).getOrFail(fromUin)
|
||||
}
|
||||
|
||||
@ -136,24 +145,24 @@ internal class MessageSourceFromTempImpl(
|
||||
|
||||
internal data class MessageSourceFromGroupImpl(
|
||||
override val bot: Bot,
|
||||
private val msg: MsgComm.Msg
|
||||
private val msg: List<MsgComm.Msg>
|
||||
) : OnlineMessageSource.Incoming.FromGroup(), MessageSourceInternal {
|
||||
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
|
||||
override val sequenceIds: IntArray get() = intArrayOf(msg.msgHead.msgSeq)
|
||||
override val internalIds: IntArray get() = intArrayOf(msg.msgBody.richText.attr!!.random)
|
||||
override val sequenceIds: IntArray get() = msg.mapToIntArray { it.msgHead.msgSeq }
|
||||
override val internalIds: IntArray get() = msg.mapToIntArray{ it.msgBody.richText.attr!!.random }
|
||||
override val ids: IntArray get() = sequenceIds
|
||||
override val time: Int get() = msg.msgHead.msgTime
|
||||
override val time: Int get() = msg.first().msgHead.msgTime
|
||||
override val originalMessage: MessageChain by lazy {
|
||||
msg.toMessageChain(bot, groupIdOrZero = group.id, onlineSource = false)
|
||||
msg.toMessageChain(bot, bot.id, groupIdOrZero = group.id, onlineSource = false)
|
||||
}
|
||||
|
||||
override val sender: Member by lazy {
|
||||
(bot.getGroup(
|
||||
msg.msgHead.groupInfo?.groupCode
|
||||
msg.first().msgHead.groupInfo?.groupCode
|
||||
?: error("cannot find groupCode for MessageSourceFromGroupImpl. msg=${msg._miraiContentToString()}")
|
||||
) as GroupImpl).run {
|
||||
get(msg.msgHead.fromUin)
|
||||
?: msg.msgBody.richText.elems.firstOrNull { it.anonGroupMsg != null }?.run {
|
||||
get(msg.first().msgHead.fromUin)
|
||||
?: msg.first().msgBody.richText.elems.firstOrNull { it.anonGroupMsg != null }?.run {
|
||||
newAnonymous(anonGroupMsg!!.anonNick.encodeToString())
|
||||
}
|
||||
?: error("cannot find member for MessageSourceFromGroupImpl. msg=${msg._miraiContentToString()}")
|
||||
@ -162,13 +171,13 @@ internal data class MessageSourceFromGroupImpl(
|
||||
|
||||
override fun toJceData(): ImMsgBody.SourceMsg {
|
||||
return ImMsgBody.SourceMsg(
|
||||
origSeqs = intArrayOf(msg.msgHead.msgSeq),
|
||||
senderUin = msg.msgHead.fromUin,
|
||||
origSeqs = intArrayOf(msg.first().msgHead.msgSeq),
|
||||
senderUin = msg.first().msgHead.fromUin,
|
||||
toUin = 0,
|
||||
flag = 1,
|
||||
elems = msg.msgBody.richText.elems,
|
||||
elems = msg.flatMap { it.msgBody.richText.elems },
|
||||
type = 0,
|
||||
time = msg.msgHead.msgTime,
|
||||
time = msg.first().msgHead.msgTime,
|
||||
pbReserve = EMPTY_BYTE_ARRAY,
|
||||
srcMsg = EMPTY_BYTE_ARRAY
|
||||
)
|
||||
|
@ -25,41 +25,41 @@ import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
internal class OfflineMessageSourceImplByMsg(
|
||||
// from other sources' originalMessage
|
||||
val delegate: MsgComm.Msg,
|
||||
val delegate: List<MsgComm.Msg>,
|
||||
override val botId: Long,
|
||||
) : OfflineMessageSource(), MessageSourceInternal {
|
||||
override val kind: MessageSourceKind =
|
||||
if (delegate.msgHead.groupInfo != null) MessageSourceKind.GROUP else MessageSourceKind.FRIEND
|
||||
if (delegate.first().msgHead.groupInfo != null) MessageSourceKind.GROUP else MessageSourceKind.FRIEND
|
||||
override val ids: IntArray get() = sequenceIds
|
||||
override val internalIds: IntArray = intArrayOf(delegate.msgHead.msgUid.toInt())
|
||||
override val internalIds: IntArray = delegate.mapToIntArray { it.msgHead.msgUid.toInt() }
|
||||
override val time: Int
|
||||
get() = delegate.msgHead.msgTime
|
||||
get() = delegate.first().msgHead.msgTime
|
||||
override val fromId: Long
|
||||
get() = delegate.msgHead.fromUin
|
||||
get() = delegate.first().msgHead.fromUin
|
||||
override val targetId: Long
|
||||
get() = delegate.msgHead.groupInfo?.groupCode ?: delegate.msgHead.toUin
|
||||
get() = delegate.first().msgHead.groupInfo?.groupCode ?: delegate.first().msgHead.toUin
|
||||
override val originalMessage: MessageChain by lazy {
|
||||
delegate.toMessageChain(
|
||||
null,
|
||||
botId,
|
||||
groupIdOrZero = delegate.msgHead.groupInfo?.groupCode ?: 0,
|
||||
groupIdOrZero = delegate.first().msgHead.groupInfo?.groupCode ?: 0,
|
||||
onlineSource = false,
|
||||
isTemp = delegate.msgHead.c2cTmpMsgHead != null
|
||||
isTemp = delegate.first().msgHead.c2cTmpMsgHead != null
|
||||
)
|
||||
}
|
||||
override val sequenceIds: IntArray = intArrayOf(delegate.msgHead.msgSeq)
|
||||
override val sequenceIds: IntArray = delegate.mapToIntArray { it.msgHead.msgSeq }
|
||||
|
||||
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
|
||||
|
||||
override fun toJceData(): ImMsgBody.SourceMsg {
|
||||
return ImMsgBody.SourceMsg(
|
||||
origSeqs = intArrayOf(delegate.msgHead.msgSeq),
|
||||
senderUin = delegate.msgHead.fromUin,
|
||||
origSeqs = delegate.mapToIntArray { it.msgHead.msgSeq },
|
||||
senderUin = delegate.first().msgHead.fromUin,
|
||||
toUin = 0,
|
||||
flag = 1,
|
||||
elems = delegate.msgBody.richText.elems,
|
||||
elems = delegate.flatMap { it.msgBody.richText.elems },
|
||||
type = 0,
|
||||
time = delegate.msgHead.msgTime,
|
||||
time = delegate.first().msgHead.msgTime,
|
||||
pbReserve = EMPTY_BYTE_ARRAY,
|
||||
srcMsg = EMPTY_BYTE_ARRAY
|
||||
)
|
||||
|
@ -60,19 +60,23 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory<Packet?>("Onlin
|
||||
pbPushMsg.msg.msgHead.msgSeq
|
||||
)
|
||||
}
|
||||
val group =
|
||||
bot.getGroup(pbPushMsg.msg.msgHead.groupInfo!!.groupCode) as GroupImpl? ?: return null // 机器人还正在进群
|
||||
val msgs = group.groupPkgMsgParsingCache.put(pbPushMsg)
|
||||
if (msgs.isEmpty()) return null
|
||||
|
||||
var extraInfo: ImMsgBody.ExtraInfo? = null
|
||||
var anonymous: ImMsgBody.AnonymousGroupMsg? = null
|
||||
|
||||
for (elem in pbPushMsg.msg.msgBody.richText.elems) {
|
||||
when {
|
||||
elem.extraInfo != null -> extraInfo = elem.extraInfo
|
||||
elem.anonGroupMsg != null -> anonymous = elem.anonGroupMsg
|
||||
for (msg in msgs) {
|
||||
for (elem in msg.msg.msgBody.richText.elems) {
|
||||
when {
|
||||
elem.extraInfo != null -> extraInfo = elem.extraInfo
|
||||
elem.anonGroupMsg != null -> anonymous = elem.anonGroupMsg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val group =
|
||||
bot.getGroup(pbPushMsg.msg.msgHead.groupInfo!!.groupCode) as GroupImpl? ?: return null // 机器人还正在进群
|
||||
val sender = if (anonymous != null) {
|
||||
group.newAnonymous(anonymous.anonNick.encodeToString())
|
||||
} else {
|
||||
@ -106,7 +110,7 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory<Packet?>("Onlin
|
||||
}
|
||||
},
|
||||
sender = sender,
|
||||
message = pbPushMsg.msg.toMessageChain(bot, groupIdOrZero = group.id, onlineSource = true),
|
||||
message = msgs.toMessageChain(bot, groupIdOrZero = group.id, onlineSource = true),
|
||||
permission = when {
|
||||
flags and 16 != 0 -> MemberPermission.ADMINISTRATOR
|
||||
flags and 8 != 0 -> MemberPermission.OWNER
|
||||
|
@ -44,6 +44,7 @@ import net.mamoe.mirai.internal.network.protocol.data.proto.TroopTips0x857
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacketFactory
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.buildResponseUniPacket
|
||||
import net.mamoe.mirai.internal.utils.*
|
||||
import net.mamoe.mirai.internal.utils._miraiContentToString
|
||||
import net.mamoe.mirai.internal.utils.encodeToString
|
||||
import net.mamoe.mirai.internal.utils.io.ProtoBuf
|
||||
@ -53,6 +54,7 @@ import net.mamoe.mirai.internal.utils.read
|
||||
import net.mamoe.mirai.internal.utils.toUHexString
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
import net.mamoe.mirai.utils.debug
|
||||
import net.mamoe.mirai.utils.mapToIntArray
|
||||
|
||||
|
||||
//0C 01 B1 89 BE 09 5E 3D 72 A6 00 01 73 68 FC 06 00 00 00 3C
|
||||
@ -357,22 +359,21 @@ private object Transformers732 : Map<Int, Lambda732> by mapOf(
|
||||
val operator =
|
||||
if (recallReminder.uin == bot.id) group.botAsMember
|
||||
else group[recallReminder.uin] ?: return@lambda732 emptySequence()
|
||||
val firstPkg = recallReminder.recalledMsgList.firstOrNull() ?: return@lambda732 emptySequence()
|
||||
|
||||
return@lambda732 recallReminder.recalledMsgList.asSequence().mapNotNull { pkg ->
|
||||
when {
|
||||
pkg.authorUin == bot.id && operator.id == bot.id -> null
|
||||
else -> {
|
||||
MessageRecallEvent.GroupRecall(
|
||||
bot,
|
||||
pkg.authorUin,
|
||||
intArrayOf(pkg.seq),
|
||||
intArrayOf(pkg.msgRandom),
|
||||
pkg.time,
|
||||
operator,
|
||||
group
|
||||
)
|
||||
}
|
||||
}
|
||||
return@lambda732 when {
|
||||
firstPkg.authorUin == bot.id && operator.id == bot.id -> emptySequence()
|
||||
else -> sequenceOf(
|
||||
MessageRecallEvent.GroupRecall(
|
||||
bot,
|
||||
firstPkg.authorUin,
|
||||
recallReminder.recalledMsgList.mapToIntArray { it.seq },
|
||||
recallReminder.recalledMsgList.mapToIntArray { it.msgRandom },
|
||||
firstPkg.time,
|
||||
operator,
|
||||
group
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2019-2020 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/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.utils
|
||||
|
||||
import kotlinx.atomicfu.locks.withLock
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgOnlinePush
|
||||
import net.mamoe.mirai.utils.currentTimeMillis
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
internal class GroupPkgMsgParsingCache {
|
||||
class PkgMsg(
|
||||
val size: Int,
|
||||
val divSeq: Int,
|
||||
val data: MutableMap<Int, MsgOnlinePush.PbPushMsg>,
|
||||
) {
|
||||
val createTime = currentTimeMillis()
|
||||
}
|
||||
|
||||
private val deque = ArrayList<PkgMsg>(16)
|
||||
private val accessLock = ReentrantLock()
|
||||
private fun clearInvalid() {
|
||||
deque.removeIf {
|
||||
currentTimeMillis() - it.createTime > 10000L
|
||||
}
|
||||
}
|
||||
|
||||
fun put(msg: MsgOnlinePush.PbPushMsg): List<MsgOnlinePush.PbPushMsg> {
|
||||
val head = msg.msg.contentHead ?: return listOf(msg)
|
||||
val size = head.pkgNum
|
||||
if (size < 2) return listOf(msg)
|
||||
accessLock.withLock {
|
||||
clearInvalid()
|
||||
val seq = head.divSeq
|
||||
val index = head.pkgIndex
|
||||
val pkgMsg = deque.find {
|
||||
it.divSeq == seq
|
||||
} ?: PkgMsg(size, seq, mutableMapOf()).also { deque.add(it) }
|
||||
pkgMsg.data[index] = msg
|
||||
if (pkgMsg.data.size == pkgMsg.size) {
|
||||
deque.removeIf { it.divSeq == seq }
|
||||
return pkgMsg.data.entries.asSequence()
|
||||
.sortedBy { it.key }
|
||||
.map { it.value }
|
||||
.toList()
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user