Commit ec30eef2 authored by Him188's avatar Him188

Powerful QuoteReply

parent 5de27d47
...@@ -12,6 +12,7 @@ package net.mamoe.mirai.qqandroid.message ...@@ -12,6 +12,7 @@ package net.mamoe.mirai.qqandroid.message
import kotlinx.io.core.buildPacket import kotlinx.io.core.buildPacket
import kotlinx.io.core.readBytes import kotlinx.io.core.readBytes
import kotlinx.io.core.readUInt import kotlinx.io.core.readUInt
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.message.data.* 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.ImMsgBody
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgComm import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgComm
...@@ -220,7 +221,8 @@ private val atAllData = ImMsgBody.Elem( ...@@ -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>() val elements = mutableListOf<ImMsgBody.Elem>()
if (this.any<QuoteReply>()) { if (this.any<QuoteReply>()) {
...@@ -231,7 +233,8 @@ internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> { ...@@ -231,7 +233,8 @@ internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> {
} }
} }
this.forEach {
fun transformOneMessage(it: Message) {
when (it) { when (it) {
is PlainText -> elements.add(ImMsgBody.Elem(text = ImMsgBody.Text(str = it.stringValue))) 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 = " "))) } 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> { ...@@ -241,6 +244,14 @@ internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> {
is NotOnlineImageFromFile -> elements.add(ImMsgBody.Elem(notOnlineImage = it.toJceData())) is NotOnlineImageFromFile -> elements.add(ImMsgBody.Elem(notOnlineImage = it.toJceData()))
is AtAll -> elements.add(atAllData) is AtAll -> elements.add(atAllData)
is Face -> elements.add(ImMsgBody.Elem(face = it.toJceData())) 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 QuoteReply,
is MessageSource -> { is MessageSource -> {
...@@ -248,6 +259,7 @@ internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> { ...@@ -248,6 +259,7 @@ internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> {
else -> error("unsupported message type: ${it::class.simpleName}") else -> error("unsupported message type: ${it::class.simpleName}")
} }
} }
this.forEach(::transformOneMessage)
// if(this.any<QuoteReply>()){ // if(this.any<QuoteReply>()){
elements.add(ImMsgBody.Elem(generalFlags = ImMsgBody.GeneralFlags(pbReserve = "78 00 F8 01 00 C8 02 00".hexToBytes()))) elements.add(ImMsgBody.Elem(generalFlags = ImMsgBody.GeneralFlags(pbReserve = "78 00 F8 01 00 C8 02 00".hexToBytes())))
......
...@@ -338,7 +338,7 @@ internal class MessageSvc { ...@@ -338,7 +338,7 @@ internal class MessageSvc {
contentHead = MsgComm.ContentHead(pkgNum = 1), contentHead = MsgComm.ContentHead(pkgNum = 1),
msgBody = ImMsgBody.MsgBody( msgBody = ImMsgBody.MsgBody(
richText = ImMsgBody.RichText( richText = ImMsgBody.RichText(
elems = message.toRichTextElems() elems = message.toRichTextElems(false)
) )
), ),
msgSeq = client.atomicNextMessageSequenceId(), msgSeq = client.atomicNextMessageSequenceId(),
...@@ -389,7 +389,7 @@ internal class MessageSvc { ...@@ -389,7 +389,7 @@ internal class MessageSvc {
contentHead = MsgComm.ContentHead(pkgNum = 1), contentHead = MsgComm.ContentHead(pkgNum = 1),
msgBody = ImMsgBody.MsgBody( msgBody = ImMsgBody.MsgBody(
richText = ImMsgBody.RichText( richText = ImMsgBody.RichText(
elems = message.toRichTextElems() elems = message.toRichTextElems(true)
) )
), ),
msgSeq = client.atomicNextMessageSequenceId(), msgSeq = client.atomicNextMessageSequenceId(),
......
...@@ -124,9 +124,9 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact> : Packet, Bot ...@@ -124,9 +124,9 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact> : Packet, Bot
suspend inline fun MessageChain.quoteReply(): MessageReceipt<TSubject> = quoteReply(this) 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 { operator fun <M : Message> get(at: Message.Key<M>): M {
return this.message[at] return this.message[at]
......
...@@ -97,7 +97,7 @@ open class MessageReceipt<C : Contact>( ...@@ -97,7 +97,7 @@ open class MessageReceipt<C : Contact>(
* @throws IllegalStateException 当此消息不是群消息时 * @throws IllegalStateException 当此消息不是群消息时
*/ */
@MiraiExperimentalAPI("unstable") @MiraiExperimentalAPI("unstable")
open fun quote(): MessageChain { open fun quote(): QuoteReplyToSend {
val target = target val target = target
check(target is Group) { "quote is only available for GroupMessage" } check(target is Group) { "quote is only available for GroupMessage" }
return this.source.quote(target.botAsMember) return this.source.quote(target.botAsMember)
......
...@@ -14,48 +14,57 @@ package net.mamoe.mirai.message.data ...@@ -14,48 +14,57 @@ package net.mamoe.mirai.message.data
import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.QQ import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiInternalAPI
import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName 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> companion object Key : Message.Key<QuoteReply>
override fun toString(): String = "" override fun toString(): String = ""
} }
/**
* 群内的引用回复.
* 总是使用 [quote] 来构造实例.
*/
@UseExperimental(MiraiInternalAPI::class)
class QuoteReplyToSend @MiraiInternalAPI constructor(source: MessageSource, val sender: QQ) : QuoteReply(source) {
fun createAt(): At = At(sender as Member)
}
/** /**
* 引用这条消息. * 引用这条消息.
* 返回 `[QuoteReply] + [At] + [PlainText]`(必要的结构) * 好友消息: 返回 `[QuoteReply]`
* 群消息: 返回 `[QuoteReply] + [At] + [PlainText]`(必要的结构)
*/ */
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
fun MessageChain.quote(sender: QQ): MessageChain { fun MessageChain.quote(sender: QQ): QuoteReplyToSend {
this.firstOrNull<MessageSource>()?.let { this.firstOrNull<MessageSource>()?.let {
return if (it.groupId == 0L) { return it.quote(sender)
QuoteReply(it).toChain() // required
} else {
check(sender is Member) { "sender must be Member to quote a GroupMessage" }
QuoteReply(it) + sender.at() + " " // required
}
} }
error("cannot find MessageSource") error("cannot find MessageSource")
} }
/** /**
* 引用这条消息. * 引用这条消息.
* 返回 `[QuoteReply] + [At] + [PlainText]`(必要的结构) * 好友消息: 返回 `[QuoteReply]`
* 群消息: 返回 `[QuoteReply] + [At] + [PlainText]`(必要的结构)
*/ */
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
fun MessageSource.quote(sender: QQ): MessageChain { fun MessageSource.quote(sender: QQ): QuoteReplyToSend {
return if (this.groupId == 0L) { if (this.groupId != 0L) {
QuoteReply(this) + " " // required
} else {
check(sender is Member) { "sender must be Member to quote a GroupMessage" } check(sender is Member) { "sender must be Member to quote a GroupMessage" }
QuoteReply(this) + sender.at() + " " // required
} }
return QuoteReplyToSend(this, sender)
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment