Add RefineContext for refining (#1195)

* Add RefineContext for refining

* Add RefineContext argument

* Fix build
This commit is contained in:
Karlatemp 2021-04-17 11:45:02 +08:00 committed by GitHub
parent 83fa78b50d
commit 0c93aeb425
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 18 deletions

View File

@ -21,7 +21,7 @@ internal data class LongMessageInternal internal constructor(override val conten
AbstractServiceMessage(), RefinableMessage {
override val serviceId: Int get() = 35
override suspend fun refine(bot: Bot, context: MessageChain): Message {
override suspend fun refine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message {
bot.asQQAndroidBot()
val long = Mirai.downloadLongMessage(bot, resId)
@ -38,7 +38,7 @@ internal data class ForwardMessageInternal(override val content: String, val res
RefinableMessage {
override val serviceId: Int get() = 35
override suspend fun refine(bot: Bot, context: MessageChain): Message {
override suspend fun refine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message {
bot.asQQAndroidBot()
val msgXml = content.substringAfter("<msg", "")

View File

@ -44,7 +44,7 @@ internal class MarketFaceInternal(
override val name: String get() = delegate.faceName.decodeToString()
override val id: Int get() = delegate.tabId
override fun tryRefine(bot: Bot, context: MessageChain): Message {
override fun tryRefine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message {
delegate.toDiceOrNull()?.let { return it } // TODO: 2021/2/12 add dice origin, maybe rename MessageOrigin
return MarketFaceImpl(delegate)
}

View File

@ -32,21 +32,23 @@ import net.mamoe.mirai.utils.*
internal fun ImMsgBody.SourceMsg.toMessageChainNoSource(
bot: Bot,
messageSourceKind: MessageSourceKind,
groupIdOrZero: Long
groupIdOrZero: Long,
refineContext: RefineContext = EmptyRefineContext,
): MessageChain {
val elements = this.elems
return buildMessageChain(elements.size + 1) {
joinToMessageChain(elements, groupIdOrZero, messageSourceKind, bot, this)
}.cleanupRubbishMessageElements().refineLight(bot)
}.cleanupRubbishMessageElements().refineLight(bot, refineContext)
}
internal suspend fun List<MsgComm.Msg>.toMessageChainOnline(
bot: Bot,
groupIdOrZero: Long,
messageSourceKind: MessageSourceKind
messageSourceKind: MessageSourceKind,
refineContext: RefineContext = EmptyRefineContext,
): MessageChain {
return toMessageChain(bot, groupIdOrZero, true, messageSourceKind).refineDeep(bot)
return toMessageChain(bot, groupIdOrZero, true, messageSourceKind).refineDeep(bot, refineContext)
}
//internal fun List<MsgComm.Msg>.toMessageChainOffline(
@ -60,9 +62,10 @@ internal suspend fun List<MsgComm.Msg>.toMessageChainOnline(
internal fun List<MsgComm.Msg>.toMessageChainNoSource(
bot: Bot,
groupIdOrZero: Long,
messageSourceKind: MessageSourceKind
messageSourceKind: MessageSourceKind,
refineContext: RefineContext = EmptyRefineContext,
): MessageChain {
return toMessageChain(bot, groupIdOrZero, null, messageSourceKind).refineLight(bot)
return toMessageChain(bot, groupIdOrZero, null, messageSourceKind).refineLight(bot, refineContext)
}

View File

@ -25,6 +25,7 @@ internal interface RefinableMessage : SingleMessage {
fun tryRefine(
bot: Bot,
context: MessageChain,
refineContext: RefineContext = EmptyRefineContext,
): Message? = this
/**
@ -33,7 +34,8 @@ internal interface RefinableMessage : SingleMessage {
suspend fun refine(
bot: Bot,
context: MessageChain,
): Message? = tryRefine(bot, context)
refineContext: RefineContext = EmptyRefineContext,
): Message? = tryRefine(bot, context, refineContext)
}
internal sealed class MessageRefiner {
@ -45,7 +47,7 @@ internal sealed class MessageRefiner {
if (none {
it is RefinableMessage
|| (it is PlainText && convertLineSeparator && it.content.contains('\r'))
|| (it is PlainText && convertLineSeparator && it.content.contains('\r'))
}
) return this
@ -76,14 +78,76 @@ internal sealed class MessageRefiner {
}
}
@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(this@RefineContextKey.hashCode())
}
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>
) : 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)
}
}
internal object LightMessageRefiner : MessageRefiner() {
fun MessageChain.refineLight(bot: Bot): MessageChain {
return refineImpl(bot) { it.tryRefine(bot, this) }
fun MessageChain.refineLight(
bot: Bot,
refineContext: RefineContext = EmptyRefineContext,
): MessageChain {
return refineImpl(bot) { it.tryRefine(bot, this, refineContext) }
}
}
internal object DeepMessageRefiner : MessageRefiner() {
suspend fun MessageChain.refineDeep(bot: Bot): MessageChain {
return refineImpl(bot) { it.refine(bot, this) }
suspend fun MessageChain.refineDeep(
bot: Bot,
refineContext: RefineContext = EmptyRefineContext,
): MessageChain {
return refineImpl(bot) { it.refine(bot, this, refineContext) }
}
}

View File

@ -22,7 +22,7 @@ internal data class LightAppInternal(
companion object Key :
AbstractPolymorphicMessageKey<RichMessage, LightAppInternal>(RichMessage, { it.safeCast() })
override fun tryRefine(bot: Bot, context: MessageChain): Message {
override fun tryRefine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message {
val struct = tryDeserialize() ?: return LightApp(content)
struct.run {
if (meta.music != null) {

View File

@ -21,6 +21,7 @@ import net.mamoe.mirai.internal.message.LightMessageRefiner.refineLight
import net.mamoe.mirai.internal.message.OfflineMessageSourceImplData
import net.mamoe.mirai.internal.message.ReceiveMessageTransformer
import net.mamoe.mirai.internal.message.RefinableMessage
import net.mamoe.mirai.internal.message.RefineContext
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
import net.mamoe.mirai.internal.test.runBlockingUnit
@ -75,7 +76,7 @@ private fun RefinableMessage(
refine: (bot: Bot, context: MessageChain) -> Message?
): RefinableMessage {
return object : RefinableMessage, TM() {
override fun tryRefine(bot: Bot, context: MessageChain): Message? {
override fun tryRefine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message? {
return refine(bot, context)
}
}
@ -86,7 +87,7 @@ private fun RefinableMessage0(
refine: () -> Message?
): RefinableMessage {
return object : RefinableMessage, TM() {
override fun tryRefine(bot: Bot, context: MessageChain): Message? {
override fun tryRefine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message? {
return refine()
}
}