Powerful QuoteReply

This commit is contained in:
Him188 2020-02-23 02:12:04 +08:00
parent 5de27d47b9
commit ec30eef250
5 changed files with 46 additions and 25 deletions

View File

@ -12,6 +12,7 @@ package net.mamoe.mirai.qqandroid.message
import kotlinx.io.core.buildPacket
import kotlinx.io.core.readBytes
import kotlinx.io.core.readUInt
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgComm
@ -220,7 +221,8 @@ private val atAllData = ImMsgBody.Elem(
)
)
internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> {
@UseExperimental(MiraiInternalAPI::class)
internal fun MessageChain.toRichTextElems(forGroup: Boolean): MutableList<ImMsgBody.Elem> {
val elements = mutableListOf<ImMsgBody.Elem>()
if (this.any<QuoteReply>()) {
@ -231,7 +233,8 @@ internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> {
}
}
this.forEach {
fun transformOneMessage(it: Message) {
when (it) {
is PlainText -> elements.add(ImMsgBody.Elem(text = ImMsgBody.Text(str = it.stringValue)))
is At -> elements.add(ImMsgBody.Elem(text = it.toJceData())).also { elements.add(ImMsgBody.Elem(text = ImMsgBody.Text(str = " "))) }
@ -241,6 +244,14 @@ internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> {
is NotOnlineImageFromFile -> elements.add(ImMsgBody.Elem(notOnlineImage = it.toJceData()))
is AtAll -> elements.add(atAllData)
is Face -> elements.add(ImMsgBody.Elem(face = it.toJceData()))
is QuoteReplyToSend -> {
if (forGroup) {
if (it.sender is Member) {
transformOneMessage(it.createAt())
}
transformOneMessage(" ".toMessage())
}
}
is QuoteReply,
is MessageSource -> {
@ -248,6 +259,7 @@ internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> {
else -> error("unsupported message type: ${it::class.simpleName}")
}
}
this.forEach(::transformOneMessage)
// if(this.any<QuoteReply>()){
elements.add(ImMsgBody.Elem(generalFlags = ImMsgBody.GeneralFlags(pbReserve = "78 00 F8 01 00 C8 02 00".hexToBytes())))

View File

@ -338,7 +338,7 @@ internal class MessageSvc {
contentHead = MsgComm.ContentHead(pkgNum = 1),
msgBody = ImMsgBody.MsgBody(
richText = ImMsgBody.RichText(
elems = message.toRichTextElems()
elems = message.toRichTextElems(false)
)
),
msgSeq = client.atomicNextMessageSequenceId(),
@ -389,7 +389,7 @@ internal class MessageSvc {
contentHead = MsgComm.ContentHead(pkgNum = 1),
msgBody = ImMsgBody.MsgBody(
richText = ImMsgBody.RichText(
elems = message.toRichTextElems()
elems = message.toRichTextElems(true)
)
),
msgSeq = client.atomicNextMessageSequenceId(),

View File

@ -124,9 +124,9 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact> : Packet, Bot
suspend inline fun MessageChain.quoteReply(): MessageReceipt<TSubject> = quoteReply(this)
/**
* 引用这个消息. 当且仅当消息为群消息时可用. 否则将会抛出 [IllegalArgumentException]
* 引用这个消息
*/
inline fun MessageChain.quote(): MessageChain = this.quote(sender)
inline fun MessageChain.quote(): QuoteReplyToSend = this.quote(sender)
operator fun <M : Message> get(at: Message.Key<M>): M {
return this.message[at]

View File

@ -97,7 +97,7 @@ open class MessageReceipt<C : Contact>(
* @throws IllegalStateException 当此消息不是群消息时
*/
@MiraiExperimentalAPI("unstable")
open fun quote(): MessageChain {
open fun quote(): QuoteReplyToSend {
val target = target
check(target is Group) { "quote is only available for GroupMessage" }
return this.source.quote(target.botAsMember)

View File

@ -14,48 +14,57 @@ package net.mamoe.mirai.message.data
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.utils.MiraiInternalAPI
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/**
* 群内的引用回复.
* 总是使用 [quote] 来构造实例.
* 群内的或好友的引用回复.
*
* 可以引用一条群消息并发送给一个好友, 或是引用好友消息发送给群.
* 可以引用自己发出的消息. 详见 [MessageReceipt.quote]
*
* 总是使用 [quote] 来构造这个实例.
*/
class QuoteReply @MiraiInternalAPI constructor(val source: MessageSource) : Message {
open class QuoteReply @MiraiInternalAPI constructor(val source: MessageSource) : Message {
companion object Key : Message.Key<QuoteReply>
override fun toString(): String = ""
}
/**
* 引用这条消息.
* 返回 `[QuoteReply] + [At] + [PlainText]`(必要的结构)
* 群内的引用回复.
* 总是使用 [quote] 来构造实例.
*/
@UseExperimental(MiraiInternalAPI::class)
fun MessageChain.quote(sender: QQ): MessageChain {
class QuoteReplyToSend @MiraiInternalAPI constructor(source: MessageSource, val sender: QQ) : QuoteReply(source) {
fun createAt(): At = At(sender as Member)
}
/**
* 引用这条消息.
* 好友消息: 返回 `[QuoteReply]`
* 群消息: 返回 `[QuoteReply] + [At] + [PlainText]`(必要的结构)
*/
@UseExperimental(MiraiInternalAPI::class)
fun MessageChain.quote(sender: QQ): QuoteReplyToSend {
this.firstOrNull<MessageSource>()?.let {
return if (it.groupId == 0L) {
QuoteReply(it).toChain() // required
} else {
check(sender is Member) { "sender must be Member to quote a GroupMessage" }
QuoteReply(it) + sender.at() + " " // required
}
return it.quote(sender)
}
error("cannot find MessageSource")
}
/**
* 引用这条消息.
* 返回 `[QuoteReply] + [At] + [PlainText]`(必要的结构)
* 好友消息: 返回 `[QuoteReply]`
* 群消息: 返回 `[QuoteReply] + [At] + [PlainText]`(必要的结构)
*/
@UseExperimental(MiraiInternalAPI::class)
fun MessageSource.quote(sender: QQ): MessageChain {
return if (this.groupId == 0L) {
QuoteReply(this) + " " // required
} else {
fun MessageSource.quote(sender: QQ): QuoteReplyToSend {
if (this.groupId != 0L) {
check(sender is Member) { "sender must be Member to quote a GroupMessage" }
QuoteReply(this) + sender.at() + " " // required
}
return QuoteReplyToSend(this, sender)
}