mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-08 23:40:14 +08:00
Better API visibility
This commit is contained in:
parent
f2843df162
commit
83faf81fb2
@ -10,6 +10,7 @@
|
|||||||
package net.mamoe.mirai.qqandroid.message
|
package net.mamoe.mirai.qqandroid.message
|
||||||
|
|
||||||
import io.ktor.utils.io.core.*
|
import io.ktor.utils.io.core.*
|
||||||
|
import net.mamoe.mirai.LowLevelAPI
|
||||||
import net.mamoe.mirai.contact.Member
|
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
|
||||||
@ -330,14 +331,13 @@ internal class NotOnlineImageFromServer(
|
|||||||
internal fun MsgComm.Msg.toMessageChain(): MessageChain {
|
internal fun MsgComm.Msg.toMessageChain(): MessageChain {
|
||||||
val elements = this.msgBody.richText.elems
|
val elements = this.msgBody.richText.elems
|
||||||
|
|
||||||
val message = MessageChainBuilder(elements.size + 1)
|
return buildMessageChain(elements.size + 1) {
|
||||||
message.add(MessageSourceFromMsg(delegate = this))
|
+MessageSourceFromMsg(delegate = this@toMessageChain)
|
||||||
elements.joinToMessageChain(message)
|
elements.joinToMessageChain(this)
|
||||||
return message.asMessageChain()
|
}.removeAtAfterQuoteReply().asMessageChain()
|
||||||
}
|
}
|
||||||
|
|
||||||
// These two functions are not the same.
|
// These two functions are not identical, dont combine.
|
||||||
|
|
||||||
@UseExperimental(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
|
@UseExperimental(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
|
||||||
internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain {
|
internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain {
|
||||||
val elements = this.elems!!
|
val elements = this.elems!!
|
||||||
@ -345,11 +345,25 @@ internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain {
|
|||||||
return buildMessageChain(elements.size + 1) {
|
return buildMessageChain(elements.size + 1) {
|
||||||
+MessageSourceFromServer(delegate = this@toMessageChain)
|
+MessageSourceFromServer(delegate = this@toMessageChain)
|
||||||
elements.joinToMessageChain(this)
|
elements.joinToMessageChain(this)
|
||||||
|
}.removeAtAfterQuoteReply().asMessageChain()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MessageChain.removeAtAfterQuoteReply(): List<Message> {
|
||||||
|
var last: Message? = null
|
||||||
|
return this.filterNot { message: Message ->
|
||||||
|
if (message is At) { // 筛除因 QuoteReply 导致的多余的 At
|
||||||
|
if (last != null || last !is QuoteReply) {
|
||||||
|
return@filterNot true
|
||||||
|
}
|
||||||
|
} else if (message is MessageContent) {
|
||||||
|
return@filterNot true
|
||||||
|
}
|
||||||
|
last = message
|
||||||
|
return@filterNot false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseExperimental(MiraiInternalAPI::class, ExperimentalUnsignedTypes::class, MiraiDebugAPI::class, LowLevelAPI::class)
|
||||||
@UseExperimental(MiraiInternalAPI::class, ExperimentalUnsignedTypes::class, MiraiDebugAPI::class)
|
|
||||||
internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChainBuilder) {
|
internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChainBuilder) {
|
||||||
this.forEach {
|
this.forEach {
|
||||||
when {
|
when {
|
||||||
@ -372,7 +386,7 @@ internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChainBuilde
|
|||||||
if (id == 0L) {
|
if (id == 0L) {
|
||||||
message.add(AtAll)
|
message.add(AtAll)
|
||||||
} else {
|
} else {
|
||||||
message.add(At(id, it.text.str))
|
message.add(At._lowLevelConstructAtInstance(id, it.text.str))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,12 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.message.data
|
package net.mamoe.mirai.message.data
|
||||||
|
|
||||||
|
import net.mamoe.mirai.LowLevelAPI
|
||||||
import net.mamoe.mirai.contact.Member
|
import net.mamoe.mirai.contact.Member
|
||||||
import net.mamoe.mirai.contact.nameCardOrNick
|
import net.mamoe.mirai.contact.nameCardOrNick
|
||||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
|
||||||
import kotlin.jvm.JvmMultifileClass
|
import kotlin.jvm.JvmMultifileClass
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
|
import kotlin.jvm.JvmStatic
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,13 +28,24 @@ import kotlin.jvm.JvmName
|
|||||||
* @see AtAll 全体成员
|
* @see AtAll 全体成员
|
||||||
*/
|
*/
|
||||||
class At
|
class At
|
||||||
@MiraiInternalAPI constructor(val target: Long, val display: String) : Message, MessageContent {
|
private constructor(val target: Long, val display: String) : Message, MessageContent {
|
||||||
@UseExperimental(MiraiInternalAPI::class)
|
|
||||||
|
/**
|
||||||
|
* 构造一个 [At] 实例. 这是唯一的公开的构造方式.
|
||||||
|
*/
|
||||||
constructor(member: Member) : this(member.id, "@${member.nameCardOrNick}")
|
constructor(member: Member) : this(member.id, "@${member.nameCardOrNick}")
|
||||||
|
|
||||||
override fun toString(): String = display
|
override fun toString(): String = display
|
||||||
|
|
||||||
companion object Key : Message.Key<At>
|
companion object Key : Message.Key<At> {
|
||||||
|
/**
|
||||||
|
* 构造一个 [At], 仅供内部使用, 否则可能造成消息无法发出的问题.
|
||||||
|
*/
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
@JvmStatic
|
||||||
|
@LowLevelAPI
|
||||||
|
fun _lowLevelConstructAtInstance(target: Long, display: String): At = At(target, display)
|
||||||
|
}
|
||||||
|
|
||||||
// 自动为消息补充 " "
|
// 自动为消息补充 " "
|
||||||
|
|
||||||
|
@ -9,12 +9,13 @@
|
|||||||
|
|
||||||
@file:JvmMultifileClass
|
@file:JvmMultifileClass
|
||||||
@file:JvmName("MessageUtils")
|
@file:JvmName("MessageUtils")
|
||||||
@file:Suppress("unused")
|
@file:Suppress("unused", "NOTHING_TO_INLINE")
|
||||||
|
|
||||||
package net.mamoe.mirai.message.data
|
package net.mamoe.mirai.message.data
|
||||||
|
|
||||||
import net.mamoe.mirai.message.data.NullMessageChain.equals
|
import net.mamoe.mirai.message.data.NullMessageChain.equals
|
||||||
import net.mamoe.mirai.message.data.NullMessageChain.toString
|
import net.mamoe.mirai.message.data.NullMessageChain.toString
|
||||||
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||||
import kotlin.js.JsName
|
import kotlin.js.JsName
|
||||||
import kotlin.jvm.JvmMultifileClass
|
import kotlin.jvm.JvmMultifileClass
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
@ -33,6 +34,8 @@ import kotlin.reflect.KProperty
|
|||||||
* @see toChain 将单个 [Message] 转换为 [MessageChain]
|
* @see toChain 将单个 [Message] 转换为 [MessageChain]
|
||||||
* @see asMessageChain 将 [Iterable] 或 [Sequence] 委托为 [MessageChain]
|
* @see asMessageChain 将 [Iterable] 或 [Sequence] 委托为 [MessageChain]
|
||||||
*
|
*
|
||||||
|
* @see foreachContent 遍历内容
|
||||||
|
*
|
||||||
* @see orNull 属性委托扩展
|
* @see orNull 属性委托扩展
|
||||||
* @see orElse 属性委托扩展
|
* @see orElse 属性委托扩展
|
||||||
* @see getValue 属性委托扩展
|
* @see getValue 属性委托扩展
|
||||||
@ -56,6 +59,18 @@ interface MessageChain : Message, Iterable<SingleMessage> {
|
|||||||
* @param key 由各个类型消息的伴生对象持有. 如 [PlainText.Key]
|
* @param key 由各个类型消息的伴生对象持有. 如 [PlainText.Key]
|
||||||
*/
|
*/
|
||||||
fun <M : Message> getOrNull(key: Message.Key<M>): M? = firstOrNull(key)
|
fun <M : Message> getOrNull(key: Message.Key<M>): M? = firstOrNull(key)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage].
|
||||||
|
* 仅供 `Java` 使用
|
||||||
|
*/
|
||||||
|
@JsName("forEachContent")
|
||||||
|
@JvmName("forEachContent")
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
@MiraiInternalAPI
|
||||||
|
fun `__forEachContent for Java__`(block: (Message) -> Unit) {
|
||||||
|
this.foreachContent(block)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// region accessors
|
// region accessors
|
||||||
@ -64,16 +79,8 @@ interface MessageChain : Message, Iterable<SingleMessage> {
|
|||||||
* 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage]
|
* 遍历每一个有内容的消息, 即 [At], [AtAll], [PlainText], [Image], [Face], [XMLMessage]
|
||||||
*/
|
*/
|
||||||
inline fun MessageChain.foreachContent(block: (Message) -> Unit) {
|
inline fun MessageChain.foreachContent(block: (Message) -> Unit) {
|
||||||
var last: Message? = null
|
this.forEach {
|
||||||
this.forEach { message: Message ->
|
if (it !is MessageMetadata) block(it)
|
||||||
if (message is At) { // 筛除因 QuoteReply 导致的多余的 At
|
|
||||||
if (last != null || last !is QuoteReply) {
|
|
||||||
block(message)
|
|
||||||
}
|
|
||||||
} else if (message is MessageContent) {
|
|
||||||
block(message)
|
|
||||||
}
|
|
||||||
last = message
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +145,7 @@ fun <M : Message> MessageChain.any(key: Message.Key<M>): Boolean = firstOrNull(k
|
|||||||
* val at: At by message
|
* val at: At by message
|
||||||
* val image: Image by message
|
* val image: Image by message
|
||||||
*/
|
*/
|
||||||
|
@JvmSynthetic
|
||||||
inline operator fun <reified T : Message> MessageChain.getValue(thisRef: Any?, property: KProperty<*>): T = this.first()
|
inline operator fun <reified T : Message> MessageChain.getValue(thisRef: Any?, property: KProperty<*>): T = this.first()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -161,6 +169,7 @@ inline class OrNullDelegate<out R : Message?>(private val value: Any?) {
|
|||||||
* @see orNull 提供一个不存在则 null 的委托
|
* @see orNull 提供一个不存在则 null 的委托
|
||||||
* @see orElse 提供一个不存在则使用默认值的委托
|
* @see orElse 提供一个不存在则使用默认值的委托
|
||||||
*/
|
*/
|
||||||
|
@JvmSynthetic
|
||||||
inline fun <reified T : Message> MessageChain.orNull(): OrNullDelegate<T?> = OrNullDelegate(this.firstOrNull<T>())
|
inline fun <reified T : Message> MessageChain.orNull(): OrNullDelegate<T?> = OrNullDelegate(this.firstOrNull<T>())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,6 +184,7 @@ inline fun <reified T : Message> MessageChain.orNull(): OrNullDelegate<T?> = OrN
|
|||||||
* ```
|
* ```
|
||||||
* @see orNull 提供一个不存在则 null 的委托
|
* @see orNull 提供一个不存在则 null 的委托
|
||||||
*/
|
*/
|
||||||
|
@JvmSynthetic
|
||||||
inline fun <reified T : Message?> MessageChain.orElse(
|
inline fun <reified T : Message?> MessageChain.orElse(
|
||||||
lazyDefault: () -> T
|
lazyDefault: () -> T
|
||||||
): OrNullDelegate<T> =
|
): OrNullDelegate<T> =
|
||||||
@ -184,88 +194,61 @@ inline fun <reified T : Message?> MessageChain.orElse(
|
|||||||
|
|
||||||
|
|
||||||
// region converters
|
// region converters
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回 [EmptyMessageChain]
|
|
||||||
*/
|
|
||||||
@JvmName("newChain")
|
|
||||||
@JsName("newChain")
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
fun MessageChain(): MessageChain = EmptyMessageChain
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造 [MessageChain]
|
|
||||||
* 若仅提供一个参数, 请考虑使用 [Message.toChain] 以优化性能
|
|
||||||
*/
|
|
||||||
@JvmName("newChain")
|
|
||||||
@JsName("newChain")
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
fun MessageChain(vararg messages: Message): MessageChain =
|
|
||||||
if (messages.isEmpty()) EmptyMessageChain
|
|
||||||
else MessageChainImplBySequence(messages.asSequence().flatten())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造 [MessageChain] 的快速途径 (无 [Array] 创建)
|
|
||||||
* 若仅提供一个参数, 请考虑使用 [Message.toChain] 以优化性能
|
|
||||||
*/
|
|
||||||
@JvmName("newChain")
|
|
||||||
@JsName("newChain")
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
fun MessageChain(message: Message): MessageChain =
|
|
||||||
when (message) {
|
|
||||||
is SingleMessage -> SingleMessageChainImpl(message)
|
|
||||||
else -> MessageChainImplBySequence(message.flatten())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造 [MessageChain]
|
|
||||||
*/
|
|
||||||
@JvmName("newChain")
|
|
||||||
@JsName("newChain")
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
fun MessageChain(messages: Iterable<Message>): MessageChain =
|
|
||||||
MessageChainImplBySequence(messages.flatten())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [扁平化][flatten] [messages] 然后构造 [MessageChain]
|
|
||||||
*/
|
|
||||||
@JvmName("newChain")
|
|
||||||
@JsName("newChain")
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
fun MessageChain(messages: List<Message>): MessageChain =
|
|
||||||
MessageChainImplByIterable(messages.flatten().asIterable())
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 得到包含 [this] 的 [MessageChain].
|
* 得到包含 [this] 的 [MessageChain].
|
||||||
*
|
*
|
||||||
* 若 [this] 为 [MessageChain] 将直接返回 this,
|
* 若 [this] 为 [MessageChain] 将直接返回 this,
|
||||||
* 若 [this] 为 [CombinedMessage] 将 [扁平化][flatten] 后委托为 [MessageChain],
|
* 若 [this] 为 [CombinedMessage] 将 [扁平化][flatten] 后委托为 [MessageChain],
|
||||||
* 否则将调用 [MessageChain] 构造一个 [MessageChainImplByIterable]
|
* 否则将调用 [asMessageChain]
|
||||||
*/
|
*/
|
||||||
@Suppress("NOTHING_TO_INLINE", "UNCHECKED_CAST")
|
@JvmName("newChain")
|
||||||
@JvmSynthetic
|
@JsName("newChain")
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun Message.toChain(): MessageChain = when (this) {
|
fun Message.toChain(): MessageChain = when (this) {
|
||||||
is MessageChain -> this
|
is MessageChain -> this
|
||||||
is CombinedMessage -> MessageChainImplByIterable((this as Iterable<Message>).flatten().asIterable())
|
is CombinedMessage -> (this as Iterable<Message>).asMessageChain()
|
||||||
else -> SingleMessageChainImpl(this as SingleMessage)
|
else -> SingleMessageChainImpl(this as SingleMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 直接将 [this] 委托为一个 [MessageChain]
|
* 直接将 [this] 委托为一个 [MessageChain]
|
||||||
*/
|
*/
|
||||||
@JvmName("asMessageChain1")
|
|
||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
@Suppress("unused", "NOTHING_TO_INLINE")
|
fun Collection<SingleMessage>.asMessageChain(): MessageChain = MessageChainImplByCollection(this)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 [this] [扁平化后][flatten] 委托为一个 [MessageChain]
|
||||||
|
*/
|
||||||
|
@JvmName("newChain")
|
||||||
|
@JsName("newChain")
|
||||||
|
fun Collection<Message>.asMessageChain(): MessageChain = MessageChainImplBySequence(this.flatten())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接将 [this] 委托为一个 [MessageChain]
|
||||||
|
*/
|
||||||
|
@JvmSynthetic
|
||||||
fun Iterable<SingleMessage>.asMessageChain(): MessageChain = MessageChainImplByIterable(this)
|
fun Iterable<SingleMessage>.asMessageChain(): MessageChain = MessageChainImplByIterable(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 [this] [扁平化后][flatten] 委托为一个 [MessageChain]
|
* 将 [this] [扁平化后][flatten] 委托为一个 [MessageChain]
|
||||||
*/
|
*/
|
||||||
@JvmSynthetic
|
@JvmName("newChain")
|
||||||
@Suppress("unused", "NOTHING_TO_INLINE")
|
@JsName("newChain")
|
||||||
fun Iterable<Message>.asMessageChain(): MessageChain = MessageChainImplBySequence(this.flatten())
|
fun Iterable<Message>.asMessageChain(): MessageChain = MessageChainImplBySequence(this.flatten())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接将 [this] 委托为一个 [MessageChain]
|
||||||
|
*/
|
||||||
|
@JvmSynthetic
|
||||||
|
fun Sequence<SingleMessage>.asMessageChain(): MessageChain = MessageChainImplBySequence(this)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 [this] [扁平化后][flatten] 委托为一个 [MessageChain]
|
||||||
|
*/
|
||||||
|
@JvmName("newChain")
|
||||||
|
@JsName("newChain")
|
||||||
|
fun Sequence<Message>.asMessageChain(): MessageChain = MessageChainImplBySequence(this.flatten())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扁平化消息序列.
|
* 扁平化消息序列.
|
||||||
*
|
*
|
||||||
@ -280,6 +263,9 @@ fun Iterable<Message>.asMessageChain(): MessageChain = MessageChainImplBySequenc
|
|||||||
*/
|
*/
|
||||||
fun Iterable<Message>.flatten(): Sequence<SingleMessage> = asSequence().flatten()
|
fun Iterable<Message>.flatten(): Sequence<SingleMessage> = asSequence().flatten()
|
||||||
|
|
||||||
|
@JvmSynthetic
|
||||||
|
fun Iterable<SingleMessage>.flatten(): Sequence<SingleMessage> = this.asSequence() // fast path
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扁平化消息序列.
|
* 扁平化消息序列.
|
||||||
*
|
*
|
||||||
@ -294,6 +280,9 @@ fun Iterable<Message>.flatten(): Sequence<SingleMessage> = asSequence().flatten(
|
|||||||
*/
|
*/
|
||||||
fun Sequence<Message>.flatten(): Sequence<SingleMessage> = flatMap { it.flatten() }
|
fun Sequence<Message>.flatten(): Sequence<SingleMessage> = flatMap { it.flatten() }
|
||||||
|
|
||||||
|
@JvmSynthetic
|
||||||
|
fun Sequence<SingleMessage>.flatten(): Sequence<SingleMessage> = this // fast path
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扁平化 [Message]
|
* 扁平化 [Message]
|
||||||
*
|
*
|
||||||
@ -346,17 +335,34 @@ internal inline class MessageChainImplByIterable constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用 [Iterable] 作为委托的 [MessageChain]
|
* 使用 [Collection] 作为委托的 [MessageChain]
|
||||||
*/
|
*/
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal inline class MessageChainImplBySequence constructor(
|
internal inline class MessageChainImplByCollection constructor(
|
||||||
private val delegate: Sequence<SingleMessage>
|
private val delegate: Collection<SingleMessage>
|
||||||
) : Message, Iterable<SingleMessage>, MessageChain {
|
) : Message, Iterable<SingleMessage>, MessageChain {
|
||||||
override fun iterator(): Iterator<SingleMessage> = delegate.iterator()
|
override fun iterator(): Iterator<SingleMessage> = delegate.iterator()
|
||||||
override fun toString(): String = this.delegate.joinToString("") { it.toString() }
|
override fun toString(): String = this.delegate.joinToString("") { it.toString() }
|
||||||
override operator fun contains(sub: String): Boolean = delegate.any { it.contains(sub) }
|
override operator fun contains(sub: String): Boolean = delegate.any { it.contains(sub) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 [Iterable] 作为委托的 [MessageChain]
|
||||||
|
*/
|
||||||
|
@PublishedApi
|
||||||
|
internal class MessageChainImplBySequence constructor(
|
||||||
|
delegate: Sequence<SingleMessage>
|
||||||
|
) : Message, Iterable<SingleMessage>, MessageChain {
|
||||||
|
/**
|
||||||
|
* [Sequence] 可能只能消耗一遍, 因此需要先转为 [List]
|
||||||
|
*/
|
||||||
|
private val collected: List<SingleMessage> by lazy { delegate.toList() }
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<SingleMessage> = collected.iterator()
|
||||||
|
override fun toString(): String = this.collected.joinToString("") { it.toString() }
|
||||||
|
override operator fun contains(sub: String): Boolean = collected.any { it.contains(sub) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单个 [SingleMessage] 作为 [MessageChain]
|
* 单个 [SingleMessage] 作为 [MessageChain]
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user