Support MessageSource in MessageSource.originalMessage

This commit is contained in:
Him188 2020-04-07 10:06:11 +08:00
parent 6c25516143
commit fb19c0af36
4 changed files with 56 additions and 15 deletions

View File

@ -38,7 +38,7 @@ import net.mamoe.mirai.utils.MiraiExperimentalAPI
internal interface MessageSourceImpl {
val sequenceId: Int
var isRecalledOrPlanned: Boolean
var isRecalledOrPlanned: Boolean // // TODO: 2020/4/7 实现 isRecalledOrPlanned
}
internal suspend inline fun MessageSource.ensureSequenceIdAvailable() {
@ -60,7 +60,13 @@ internal class MessageSourceFromFriendImpl(
}
override val id: Int get() = msg.msgBody.richText.attr!!.random
override val time: Int get() = msg.msgHead.msgTime
override val originalMessage: MessageChain by lazy { msg.toMessageChain(bot, groupIdOrZero = 0, addSource = false) }
override val originalMessage: MessageChain by lazy {
msg.toMessageChain(
bot,
groupIdOrZero = 0,
onlineSource = false
)
}
override val target: Bot get() = bot
override val sender: QQ get() = bot.getFriend(msg.msgHead.fromUin)
@ -121,7 +127,7 @@ internal class MessageSourceFromGroupImpl(
msg.toMessageChain(
bot,
groupIdOrZero = group.id,
addSource = false
onlineSource = false
)
}
override val target: Bot get() = bot
@ -148,7 +154,34 @@ internal class MessageSourceFromGroupImpl(
}
}
internal class OfflineMessageSourceImpl( // from others' quotation
internal class OfflineMessageSourceImplByMsg( // from other sources' originalMessage
val delegate: MsgComm.Msg,
override val bot: Bot
) : OfflineMessageSource(), MessageSourceImpl {
override val kind: Kind = if (delegate.msgHead.groupInfo != null) Kind.GROUP else Kind.FRIEND
override val id: Int
get() = delegate.msgHead.msgUid.toInt()
override val time: Int
get() = delegate.msgHead.msgTime
override val fromId: Long
get() = delegate.msgHead.fromUin
override val targetId: Long
get() = delegate.msgHead.groupInfo?.groupCode ?: delegate.msgHead.toUin
override val originalMessage: MessageChain by lazy {
delegate.toMessageChain(bot, delegate.msgHead.groupInfo?.groupCode ?: 0, false)
}
override val sequenceId: Int
get() = delegate.msgHead.msgSeq
private val isRecalled: AtomicBoolean = atomic(false)
override var isRecalledOrPlanned: Boolean
get() = isRecalled.value
set(value) {
isRecalled.value = value
}
}
internal class OfflineMessageSourceImplBySourceMsg( // from others' quotation
val delegate: ImMsgBody.SourceMsg,
override val bot: Bot,
groupIdOrZero: Long
@ -164,7 +197,7 @@ internal class OfflineMessageSourceImpl( // from others' quotation
override val sequenceId: Int
get() = delegate.origSeqs?.first() ?: error("cannot find sequenceId")
override val time: Int get() = delegate.time
override val originalMessage: MessageChain by lazy { delegate.toMessageChain(bot, groupIdOrZero, false) }
override val originalMessage: MessageChain by lazy { delegate.toMessageChain(bot, groupIdOrZero) }
/*
override val id: Long
get() = (delegate.origSeqs?.firstOrNull()

View File

@ -42,7 +42,7 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B
if (this.anyIsInstance<QuoteReply>()) {
when (val source = this[QuoteReply].source) {
is OfflineMessageSourceImpl -> elements.add(ImMsgBody.Elem(srcMsg = source.delegate))
is OfflineMessageSourceImplBySourceMsg -> elements.add(ImMsgBody.Elem(srcMsg = source.delegate))
is MessageSourceToFriendImpl -> elements.add(ImMsgBody.Elem(srcMsg = source.toJceDataImplForFriend()))
is MessageSourceToGroupImpl -> elements.add(ImMsgBody.Elem(srcMsg = source.toJceDataImplForGroup()))
is MessageSourceFromFriendImpl -> elements.add(ImMsgBody.Elem(srcMsg = source.toJceDataImplForFriend()))
@ -179,16 +179,18 @@ private val PB_RESERVE_FOR_DOUTU = "78 00 90 01 01 F8 01 00 A0 02 00 C8 02 00".h
private val PB_RESERVE_FOR_ELSE = "78 00 F8 01 00 C8 02 00".hexToBytes()
@OptIn(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
internal fun MsgComm.Msg.toMessageChain(bot: Bot, groupIdOrZero: Long, addSource: Boolean): MessageChain {
internal fun MsgComm.Msg.toMessageChain(bot: Bot, groupIdOrZero: Long, onlineSource: Boolean): MessageChain {
val elements = this.msgBody.richText.elems
return buildMessageChain(elements.size + 1) {
if (addSource) {
if (onlineSource) {
if (groupIdOrZero != 0L) {
+MessageSourceFromGroupImpl(bot, this@toMessageChain)
} else {
+MessageSourceFromFriendImpl(bot, this@toMessageChain)
}
} else {
+OfflineMessageSourceImplByMsg(this@toMessageChain, bot)
}
elements.joinToMessageChain(groupIdOrZero, bot, this)
}.cleanupRubbishMessageElements()
@ -197,13 +199,11 @@ internal fun MsgComm.Msg.toMessageChain(bot: Bot, groupIdOrZero: Long, addSource
// These two functions have difference method signature, don't combine.
@OptIn(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
internal fun ImMsgBody.SourceMsg.toMessageChain(bot: Bot, groupIdOrZero: Long, withSource: Boolean): MessageChain {
internal fun ImMsgBody.SourceMsg.toMessageChain(bot: Bot, groupIdOrZero: Long): MessageChain {
val elements = this.elems!!
return buildMessageChain(elements.size + 1) {
if (withSource) {
+OfflineMessageSourceImpl(delegate = this@toMessageChain, bot = bot, groupIdOrZero = groupIdOrZero)
}
+OfflineMessageSourceImplBySourceMsg(delegate = this@toMessageChain, bot = bot, groupIdOrZero = groupIdOrZero)
elements.joinToMessageChain(groupIdOrZero, bot, this)
}.cleanupRubbishMessageElements()
}
@ -260,7 +260,15 @@ internal fun List<ImMsgBody.Elem>.joinToMessageChain(groupIdOrZero: Long, bot: B
// (this._miraiContentToString())
this.forEach {
when {
it.srcMsg != null -> message.add(QuoteReply(OfflineMessageSourceImpl(it.srcMsg, bot, groupIdOrZero)))
it.srcMsg != null -> message.add(
QuoteReply(
OfflineMessageSourceImplBySourceMsg(
it.srcMsg,
bot,
groupIdOrZero
)
)
)
it.notOnlineImage != null -> message.add(OnlineFriendImageImpl(it.notOnlineImage))
it.customFace != null -> message.add(OnlineGroupImageImpl(it.customFace))
it.face != null -> message.add(Face(it.face.index))

View File

@ -229,7 +229,7 @@ internal class MessageSvc {
if (friend.lastMessageSequence.compareAndSet(instant, msg.msgHead.msgSeq)) {
return@mapNotNull FriendMessage(
friend,
msg.toMessageChain(bot, groupIdOrZero = 0, addSource = true)
msg.toMessageChain(bot, groupIdOrZero = 0, onlineSource = true)
)
}
} else return@mapNotNull null

View File

@ -84,7 +84,7 @@ internal class OnlinePush {
return GroupMessage(
senderName = pbPushMsg.msg.msgHead.groupInfo.groupCard,
sender = group[pbPushMsg.msg.msgHead.fromUin],
message = pbPushMsg.msg.toMessageChain(bot, groupIdOrZero = group.id, addSource = true),
message = pbPushMsg.msg.toMessageChain(bot, groupIdOrZero = group.id, onlineSource = true),
permission = when {
flags and 16 != 0 -> MemberPermission.ADMINISTRATOR
flags and 8 != 0 -> MemberPermission.OWNER