| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /*
- * Copyright 2019-2022 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/dev/LICENSE
- */
- package net.mamoe.mirai.internal.message
- import net.mamoe.mirai.Bot
- import net.mamoe.mirai.internal.message.DeepMessageRefiner.refineDeep
- import net.mamoe.mirai.internal.message.LightMessageRefiner.refineLight
- import net.mamoe.mirai.internal.message.LightMessageRefiner.refineMessageSource
- import net.mamoe.mirai.internal.message.flags.InternalFlagOnlyMessage
- import net.mamoe.mirai.internal.message.source.IncomingMessageSourceInternal
- import net.mamoe.mirai.message.data.*
- import net.mamoe.mirai.utils.safeCast
- /**
- * 在接收解析消息后会经过一层转换的消息.
- *
- * @see DeepMessageRefiner.refineDeep
- * @see LightMessageRefiner.refineLight
- */
- internal interface RefinableMessage : SingleMessage {
- /**
- * Refine if possible (without suspension), returns self otherwise.
- * @since 2.6
- */ // see #1157
- fun tryRefine(
- bot: Bot,
- context: MessageChain,
- refineContext: RefineContext = EmptyRefineContext,
- ): Message? = this
- /**
- * This message [RefinableMessage] will be replaced by return value of [refineLight]
- */
- suspend fun refine(
- bot: Bot,
- context: MessageChain,
- refineContext: RefineContext = EmptyRefineContext,
- ): Message? = tryRefine(bot, context, refineContext)
- }
- internal sealed class MessageRefiner {
- protected inline fun MessageChain.refineImpl(
- bot: Bot,
- refineAction: (message: RefinableMessage) -> Message?,
- ): MessageChain {
- val convertLineSeparator = bot.configuration.convertLineSeparator
- if (none {
- it is RefinableMessage
- || (it is PlainText && convertLineSeparator && it.content.contains('\r'))
- }
- ) return this
- val builder = MessageChainBuilder(this.size)
- for (singleMessage in this) {
- if (singleMessage is RefinableMessage) {
- val v = refineAction(singleMessage)
- if (v != null) builder.add(v)
- } else if (singleMessage is PlainText && convertLineSeparator) {
- val content = singleMessage.content
- if (content.contains('\r')) {
- builder.add(
- PlainText(
- content
- .replace("\r\n", "\n")
- .replace('\r', '\n')
- )
- )
- } else {
- builder.add(singleMessage)
- }
- } else {
- builder.add(singleMessage)
- }
- }
- return builder.build()
- }
- }
- @Suppress("unused")
- internal class RefineContextKey<T : Any>(
- val name: String?,
- ) {
- override fun toString(): String {
- return buildString {
- append("Key(")
- name?.also(this@buildString::append) ?: kotlin.run {
- append('#').append([email protected]())
- }
- append(')')
- }
- }
- }
- /**
- * 转换消息时的上下文
- */
- internal interface RefineContext {
- operator fun contains(key: RefineContextKey<*>): Boolean
- operator fun <T : Any> get(key: RefineContextKey<T>): T?
- fun <T : Any> getNotNull(key: RefineContextKey<T>): T = get(key) ?: error("No such value of `$key`")
- }
- internal interface MutableRefineContext : RefineContext {
- operator fun <T : Any> set(key: RefineContextKey<T>, value: T)
- fun remove(key: RefineContextKey<*>)
- }
- internal object EmptyRefineContext : RefineContext {
- override fun contains(key: RefineContextKey<*>): Boolean = false
- override fun <T : Any> get(key: RefineContextKey<T>): T? = null
- override fun toString(): String {
- return "EmptyRefineContext"
- }
- }
- @Suppress("UNCHECKED_CAST")
- internal class SimpleRefineContext(
- private val delegate: MutableMap<RefineContextKey<*>, Any> = mutableMapOf(),
- ) : MutableRefineContext {
- override fun contains(key: RefineContextKey<*>): Boolean = delegate.containsKey(key)
- override fun <T : Any> get(key: RefineContextKey<T>): T? {
- return (delegate[key] ?: return null) as T
- }
- override fun <T : Any> set(key: RefineContextKey<T>, value: T) {
- delegate[key] = value
- }
- override fun remove(key: RefineContextKey<*>) {
- delegate.remove(key)
- }
- }
- /**
- * 执行不需要 `suspend` 的 refine. 用于 [MessageSource.originalMessage].
- */
- internal object LightMessageRefiner : MessageRefiner() {
- /* note:
- * 不在 refineLight 中处理的原因是 refineMessageSource
- * 需要的是 **最终处理完成后** 的 MessageChain (即 refineDeep 后的 MessageChain)
- *
- * 在 refineLight/RefinableMessage.(try)refine 中直接处理将导致获取不到最终结果导致逻辑错误
- */
- fun MessageChain.refineMessageSource(): MessageChain {
- val source = this.sourceOrNull?.safeCast<IncomingMessageSourceInternal>() ?: return this
- val originalMessage = this
- source.originalMessageLazy = lazy {
- originalMessage.filterNot { it is MessageSource }.toMessageChain()
- // @Suppress("INVISIBLE_MEMBER")
- // createMessageChainImplOptimized(originalMessage.filterNot { it is MessageSource })
- }
- return this
- }
- fun MessageChain.refineLight(
- bot: Bot,
- refineContext: RefineContext = EmptyRefineContext,
- ): MessageChain {
- return refineImpl(bot) { it.tryRefine(bot, this, refineContext) }
- }
- /**
- * 去除 [MessageChain] 携带的内部标识
- *
- * 用于 [createMessageReceipt] <- `RemoteFile.uploadAndSend` (文件操作API v1)
- */
- fun MessageChain.dropMiraiInternalFlags(): MessageChain {
- return asSequence().filterNot { it is InternalFlagOnlyMessage }.toMessageChain()
- }
- }
- /**
- * 执行需要 `suspend` 的 refine. 用于解析到的消息.
- */
- internal object DeepMessageRefiner : MessageRefiner() {
- suspend fun MessageChain.refineDeep(
- bot: Bot,
- refineContext: RefineContext = EmptyRefineContext,
- ): MessageChain {
- return refineImpl(bot) { it.refine(bot, this, refineContext) }
- .refineMessageSource()
- }
- }
|