mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-07 16:40:43 +08:00
Revise MessageSerializers.registerSerializer, fix #951:
- Don't register contextual serializer - Register polymorphic serializers to all superclasses inheriting SingleMessage
This commit is contained in:
parent
a834916f3c
commit
2e91ae0d7f
@ -22,9 +22,10 @@ import kotlinx.serialization.modules.polymorphic
|
||||
import net.mamoe.mirai.Mirai
|
||||
import net.mamoe.mirai.message.MessageSerializers
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.message.data.MessageChainImpl
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.allSuperclasses
|
||||
import kotlin.reflect.full.isSubclassOf
|
||||
|
||||
|
||||
internal fun ClassSerialDescriptorBuilder.takeElementsFrom(descriptor: SerialDescriptor) {
|
||||
@ -70,38 +71,45 @@ public open class MessageSourceSerializerImpl(serialName: String) :
|
||||
|
||||
private val builtInSerializersModule by lazy {
|
||||
SerializersModule {
|
||||
// non-Message classes
|
||||
contextual(RawForwardMessage::class, RawForwardMessage.serializer())
|
||||
contextual(ForwardMessage.Node::class, ForwardMessage.Node.serializer())
|
||||
contextual(VipFace.Kind::class, VipFace.Kind.serializer())
|
||||
// NOTE: contextual serializers disabled because of https://github.com/mamoe/mirai/issues/951
|
||||
|
||||
// // non-Message classes
|
||||
// contextual(RawForwardMessage::class, RawForwardMessage.serializer())
|
||||
// contextual(ForwardMessage.Node::class, ForwardMessage.Node.serializer())
|
||||
// contextual(VipFace.Kind::class, VipFace.Kind.serializer())
|
||||
//
|
||||
//
|
||||
// // In case Proguard or something else obfuscated the Kotlin metadata, providing the serializers explicitly will help.
|
||||
// contextual(At::class, At.serializer())
|
||||
// contextual(AtAll::class, AtAll.serializer())
|
||||
// contextual(CustomMessage::class, CustomMessage.serializer())
|
||||
// contextual(CustomMessageMetadata::class, CustomMessageMetadata.serializer())
|
||||
// contextual(Face::class, Face.serializer())
|
||||
// contextual(Image::class, Image.Serializer)
|
||||
// contextual(PlainText::class, PlainText.serializer())
|
||||
// contextual(QuoteReply::class, QuoteReply.serializer())
|
||||
//
|
||||
// contextual(ForwardMessage::class, ForwardMessage.serializer())
|
||||
//
|
||||
//
|
||||
// contextual(LightApp::class, LightApp.serializer())
|
||||
// contextual(SimpleServiceMessage::class, SimpleServiceMessage.serializer())
|
||||
// contextual(AbstractServiceMessage::class, AbstractServiceMessage.serializer())
|
||||
//
|
||||
// contextual(PttMessage::class, PttMessage.serializer())
|
||||
// contextual(Voice::class, Voice.serializer())
|
||||
// contextual(PokeMessage::class, PokeMessage.serializer())
|
||||
// contextual(VipFace::class, VipFace.serializer())
|
||||
// contextual(FlashImage::class, FlashImage.serializer())
|
||||
//
|
||||
// contextual(MusicShare::class, MusicShare.serializer())
|
||||
//
|
||||
// contextual(MessageSource::class, MessageSource.serializer())
|
||||
|
||||
// In case Proguard or something else obfuscated the Kotlin metadata, providing the serializers explicitly will help.
|
||||
contextual(At::class, At.serializer())
|
||||
contextual(AtAll::class, AtAll.serializer())
|
||||
contextual(CustomMessage::class, CustomMessage.serializer())
|
||||
contextual(CustomMessageMetadata::class, CustomMessageMetadata.serializer())
|
||||
contextual(Face::class, Face.serializer())
|
||||
contextual(Image::class, Image.Serializer)
|
||||
contextual(PlainText::class, PlainText.serializer())
|
||||
contextual(QuoteReply::class, QuoteReply.serializer())
|
||||
// contextual(SingleMessage::class, SingleMessage.Serializer)
|
||||
contextual(MessageChain::class, MessageChain.Serializer)
|
||||
contextual(MessageChainImpl::class, MessageChainImpl.serializer())
|
||||
|
||||
contextual(ForwardMessage::class, ForwardMessage.serializer())
|
||||
|
||||
|
||||
contextual(LightApp::class, LightApp.serializer())
|
||||
contextual(SimpleServiceMessage::class, SimpleServiceMessage.serializer())
|
||||
contextual(AbstractServiceMessage::class, AbstractServiceMessage.serializer())
|
||||
|
||||
contextual(PttMessage::class, PttMessage.serializer())
|
||||
contextual(Voice::class, Voice.serializer())
|
||||
contextual(PokeMessage::class, PokeMessage.serializer())
|
||||
contextual(VipFace::class, VipFace.serializer())
|
||||
contextual(FlashImage::class, FlashImage.serializer())
|
||||
|
||||
contextual(MusicShare::class, MusicShare.serializer())
|
||||
|
||||
contextual(MessageSource::class, MessageSource.serializer())
|
||||
|
||||
fun PolymorphicModuleBuilder<MessageMetadata>.messageMetadataSubclasses() {
|
||||
subclass(MessageSource::class, MessageSource.serializer())
|
||||
@ -132,11 +140,6 @@ private val builtInSerializersModule by lazy {
|
||||
subclass(MusicShare::class, MusicShare.serializer())
|
||||
}
|
||||
|
||||
contextual(SingleMessage::class, SingleMessage.Serializer)
|
||||
contextual(MessageChain::class, MessageChain.Serializer)
|
||||
contextual(MessageChainImpl::class, MessageChainImpl.serializer())
|
||||
|
||||
// polymorphicDefault(MessageChain::class) { MessageChainImpl.serializer() }
|
||||
|
||||
// polymorphic(SingleMessage::class) {
|
||||
// subclass(MessageSource::class, MessageSource.serializer())
|
||||
@ -153,6 +156,23 @@ private val builtInSerializersModule by lazy {
|
||||
messageMetadataSubclasses()
|
||||
}
|
||||
|
||||
polymorphic(MessageContent::class) {
|
||||
messageContentSubclasses()
|
||||
}
|
||||
|
||||
polymorphic(MessageMetadata::class) {
|
||||
messageMetadataSubclasses()
|
||||
}
|
||||
|
||||
polymorphic(RichMessage::class) {
|
||||
subclass(SimpleServiceMessage::class, SimpleServiceMessage.serializer())
|
||||
subclass(LightApp::class, LightApp.serializer())
|
||||
}
|
||||
|
||||
polymorphic(ServiceMessage::class) {
|
||||
subclass(SimpleServiceMessage::class, SimpleServiceMessage.serializer())
|
||||
}
|
||||
|
||||
//contextual(SingleMessage::class, SingleMessage.Serializer)
|
||||
// polymorphic(SingleMessage::class, SingleMessage.Serializer) {
|
||||
// messageContentSubclasses()
|
||||
@ -180,11 +200,16 @@ internal object MessageSerializersImpl : MessageSerializers {
|
||||
override val serializersModule: SerializersModule get() = serializersModuleField ?: builtInSerializersModule
|
||||
|
||||
@Synchronized
|
||||
override fun <M : SingleMessage> registerSerializer(baseClass: KClass<M>, serializer: KSerializer<M>) {
|
||||
override fun <M : SingleMessage> registerSerializer(type: KClass<M>, serializer: KSerializer<M>) {
|
||||
serializersModuleField = serializersModule.overwriteWith(SerializersModule {
|
||||
contextual(baseClass, serializer)
|
||||
polymorphic(SingleMessage::class) {
|
||||
subclass(baseClass, serializer)
|
||||
// contextual(type, serializer)
|
||||
for (superclass in type.allSuperclasses) {
|
||||
if (superclass.isFinal) continue
|
||||
if (!superclass.isSubclassOf(SingleMessage::class)) continue
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
polymorphic(superclass as KClass<Any>) {
|
||||
subclass(type, serializer)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -12,7 +12,9 @@ package net.mamoe.mirai.message
|
||||
import kotlinx.serialization.ContextualSerializer
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.modules.*
|
||||
import kotlinx.serialization.modules.PolymorphicModuleBuilder
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.subclass
|
||||
import net.mamoe.mirai.internal.message.MessageSerializersImpl
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
@ -50,21 +52,26 @@ public interface MessageSerializers {
|
||||
public val serializersModule: SerializersModule
|
||||
|
||||
/**
|
||||
* 注册一个 [SerializersModuleBuilder.contextual] 和 [SingleMessage] 多态域的 [PolymorphicModuleBuilder.subclass].
|
||||
* 注册 [serializer] 到 [type] 的所有为 [SingleMessage] 子类型的超类型的多态域 [PolymorphicModuleBuilder.subclass]
|
||||
*
|
||||
* 相当于
|
||||
* 实现:
|
||||
* ```
|
||||
* contextual(baseClass, serializer)
|
||||
* polymorphic(SingleMessage::class) {
|
||||
* subclass(baseClass, serializer)
|
||||
* for (superclass in type.allSuperclasses) {
|
||||
* if (superclass.isFinal) continue
|
||||
* if (superclass.isSubclassOf(SingleMessage::class)) continue
|
||||
* polymorphic(superclass) {
|
||||
* subclass(type, serializer)
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* 若要自己实现消息类型, 务必在这里注册对应序列化器, 否则在 [MessageChain.serializeToJsonString] 时将会出错.
|
||||
*
|
||||
* @since 2.0, revised 2.3
|
||||
*/
|
||||
@MiraiExperimentalApi
|
||||
public fun <M : SingleMessage> registerSerializer(baseClass: KClass<M>, serializer: KSerializer<M>)
|
||||
public fun <M : SingleMessage> registerSerializer(type: KClass<M>, serializer: KSerializer<M>)
|
||||
|
||||
/**
|
||||
* 合并 [serializersModule] 到 [MessageSerializers.serializersModule] 并覆盖.
|
||||
|
@ -245,7 +245,7 @@ public interface MessageChain :
|
||||
*/
|
||||
public object Serializer : KSerializer<MessageChain> {
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
private val delegate = ListSerializer(PolymorphicSerializer(SingleMessage::class))
|
||||
private val delegate = ListSerializer(SingleMessage.Serializer)
|
||||
override val descriptor: SerialDescriptor = delegate.descriptor
|
||||
override fun deserialize(decoder: Decoder): MessageChain = delegate.deserialize(decoder).toMessageChain()
|
||||
override fun serialize(encoder: Encoder, value: MessageChain): Unit = delegate.serialize(encoder, value)
|
||||
|
Loading…
Reference in New Issue
Block a user