mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-01 22:00:46 +08:00
Rewrite MessageSerializers, register serializers in each MessageProtocol, implement for native targets
This commit is contained in:
parent
13dadd5a95
commit
d27228c8c8
@ -13,10 +13,8 @@ import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
|
||||
import kotlinx.serialization.modules.PolymorphicModuleBuilder
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.overwriteWith
|
||||
import kotlinx.serialization.modules.polymorphic
|
||||
import net.mamoe.mirai.Mirai
|
||||
import net.mamoe.mirai.message.MessageSerializers
|
||||
import net.mamoe.mirai.message.data.*
|
||||
@ -55,142 +53,11 @@ public open class MessageSourceSerializerImpl(serialName: String) :
|
||||
}
|
||||
|
||||
|
||||
private val builtInSerializersModule by lazy {
|
||||
SerializersModule {
|
||||
// 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())
|
||||
|
||||
// contextual(SingleMessage::class, SingleMessage.Serializer)
|
||||
contextual(MessageChain::class, MessageChain.Serializer)
|
||||
contextual(LinearMessageChainImpl::class, LinearMessageChainImpl.serializer())
|
||||
|
||||
contextual(ShowImageFlag::class, ShowImageFlag.Serializer)
|
||||
|
||||
contextual(MessageOriginKind::class, MessageOriginKind.serializer())
|
||||
|
||||
fun PolymorphicModuleBuilder<MessageMetadata>.messageMetadataSubclasses() {
|
||||
subclass(MessageSource::class, MessageSource.serializer())
|
||||
subclass(QuoteReply::class, QuoteReply.serializer())
|
||||
subclass(ShowImageFlag::class, ShowImageFlag.Serializer)
|
||||
subclass(MessageOrigin::class, MessageOrigin.serializer())
|
||||
}
|
||||
|
||||
fun PolymorphicModuleBuilder<MessageContent>.messageContentSubclasses() {
|
||||
subclass(At::class, At.serializer())
|
||||
subclass(AtAll::class, AtAll.serializer())
|
||||
subclass(Face::class, Face.serializer())
|
||||
subclass(Image::class, Image.Serializer)
|
||||
subclass(PlainText::class, PlainText.serializer())
|
||||
|
||||
subclass(ForwardMessage::class, ForwardMessage.serializer())
|
||||
|
||||
|
||||
subclass(LightApp::class, LightApp.serializer())
|
||||
subclass(SimpleServiceMessage::class, SimpleServiceMessage.serializer())
|
||||
|
||||
// subclass(PttMessage::class, PttMessage.serializer())
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
subclass(net.mamoe.mirai.message.data.Voice::class, net.mamoe.mirai.message.data.Voice.serializer())
|
||||
|
||||
// subclass(HummerMessage::class, HummerMessage.serializer())
|
||||
subclass(PokeMessage::class, PokeMessage.serializer())
|
||||
subclass(VipFace::class, VipFace.serializer())
|
||||
subclass(FlashImage::class, FlashImage.serializer())
|
||||
|
||||
subclass(MusicShare::class, MusicShare.serializer())
|
||||
|
||||
subclass(Dice::class, Dice.serializer())
|
||||
}
|
||||
|
||||
|
||||
// polymorphic(SingleMessage::class) {
|
||||
// subclass(MessageSource::class, MessageSource.serializer())
|
||||
// default {
|
||||
// Message.Serializer.serializersModule.getPolymorphic(Message::class, it)
|
||||
// }
|
||||
// }
|
||||
|
||||
// polymorphic(Message::class) {
|
||||
// subclass(PlainText::class, PlainText.serializer())
|
||||
// }
|
||||
polymorphic(SingleMessage::class) {
|
||||
messageContentSubclasses()
|
||||
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()
|
||||
// messageMetadataSubclasses()
|
||||
// singleMessageSubclasses()
|
||||
// }
|
||||
|
||||
// contextual(MessageContent::class, MessageContent.Serializer)
|
||||
// polymorphic(MessageContent::class, MessageContent.Serializer) {
|
||||
// messageContentSubclasses()
|
||||
// }
|
||||
|
||||
// contextual(MessageMetadata::class, MessageMetadata.Serializer)
|
||||
// polymorphic(MessageMetadata::class, MessageMetadata.Serializer) {
|
||||
// messageMetadataSubclasses()
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
// Tests:
|
||||
// net.mamoe.mirai.internal.message.data.MessageSerializationTest
|
||||
internal object MessageSerializersImpl : MessageSerializers {
|
||||
private var serializersModuleField: SerializersModule by lateinitMutableProperty {
|
||||
builtInSerializersModule
|
||||
SerializersModule { }
|
||||
}
|
||||
|
||||
override val serializersModule: SerializersModule
|
||||
@ -206,7 +73,7 @@ internal object MessageSerializersImpl : MessageSerializers {
|
||||
|
||||
@Synchronized
|
||||
override fun registerSerializers(serializersModule: SerializersModule) {
|
||||
serializersModuleField = serializersModule.overwriteWith(serializersModule)
|
||||
serializersModuleField = this.serializersModule.overwriteWith(serializersModule)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* 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.
|
||||
@ -73,13 +73,16 @@ public interface MessageSerializers {
|
||||
* @since 2.0, revised 2.3
|
||||
*/
|
||||
@MiraiExperimentalApi
|
||||
public fun <M : SingleMessage> registerSerializer(type: KClass<M>, serializer: KSerializer<M>)
|
||||
public fun <M : SingleMessage> registerSerializer(
|
||||
type: KClass<M>,
|
||||
serializer: KSerializer<M>
|
||||
) // not supported on native.
|
||||
|
||||
/**
|
||||
* 合并 [serializersModule] 到 [MessageSerializers.serializersModule] 并覆盖.
|
||||
*/
|
||||
@MiraiExperimentalApi
|
||||
public fun registerSerializers(serializersModule: SerializersModule)
|
||||
public fun registerSerializers(serializersModule: SerializersModule) // supported on all platforms.
|
||||
|
||||
public companion object INSTANCE : MessageSerializers by MessageSerializersImpl
|
||||
}
|
@ -17,5 +17,5 @@ internal actual fun <M : Any> SerializersModule.overwritePolymorphicWith(
|
||||
type: KClass<M>,
|
||||
serializer: KSerializer<M>
|
||||
): SerializersModule {
|
||||
TODO("Not yet implemented")
|
||||
throw UnsupportedOperationException("overwritePolymorphicWith is not supported on native.")
|
||||
}
|
@ -12,8 +12,6 @@
|
||||
package net.mamoe.mirai.internal
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.*
|
||||
import io.ktor.client.features.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.request.forms.*
|
||||
import io.ktor.utils.io.core.*
|
||||
@ -65,7 +63,6 @@ import net.mamoe.mirai.internal.network.sKey
|
||||
import net.mamoe.mirai.internal.utils.MiraiProtocolInternal
|
||||
import net.mamoe.mirai.internal.utils.crypto.TEA
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.message.MessageSerializers
|
||||
import net.mamoe.mirai.message.action.Nudge
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.*
|
||||
@ -81,71 +78,13 @@ internal expect fun _MiraiImpl_static_init()
|
||||
@OptIn(LowLevelApi::class)
|
||||
// not object for ServiceLoader.
|
||||
internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
|
||||
init {
|
||||
_MiraiImpl_static_init() // companion object is lazily initialized on native
|
||||
}
|
||||
|
||||
companion object {
|
||||
init {
|
||||
_MiraiImpl_static_init()
|
||||
MessageSerializers.registerSerializer(OfflineGroupImage::class, OfflineGroupImage.serializer())
|
||||
MessageSerializers.registerSerializer(OfflineFriendImage::class, OfflineFriendImage.serializer())
|
||||
MessageSerializers.registerSerializer(OnlineFriendImageImpl::class, OnlineFriendImageImpl.serializer())
|
||||
MessageSerializers.registerSerializer(OnlineGroupImageImpl::class, OnlineGroupImageImpl.serializer())
|
||||
|
||||
MessageSerializers.registerSerializer(MarketFaceImpl::class, MarketFaceImpl.serializer())
|
||||
MessageSerializers.registerSerializer(FileMessageImpl::class, FileMessageImpl.serializer())
|
||||
|
||||
// MessageSource
|
||||
|
||||
MessageSerializers.registerSerializer(
|
||||
OnlineMessageSourceFromGroupImpl::class,
|
||||
OnlineMessageSourceFromGroupImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OnlineMessageSourceFromFriendImpl::class,
|
||||
OnlineMessageSourceFromFriendImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OnlineMessageSourceFromTempImpl::class,
|
||||
OnlineMessageSourceFromTempImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OnlineMessageSourceFromStrangerImpl::class,
|
||||
OnlineMessageSourceFromStrangerImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OnlineMessageSourceToGroupImpl::class,
|
||||
OnlineMessageSourceToGroupImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OnlineMessageSourceToFriendImpl::class,
|
||||
OnlineMessageSourceToFriendImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OnlineMessageSourceToTempImpl::class,
|
||||
OnlineMessageSourceToTempImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OnlineMessageSourceToStrangerImpl::class,
|
||||
OnlineMessageSourceToStrangerImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OfflineMessageSourceImplData::class,
|
||||
OfflineMessageSourceImplData.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OfflineMessageSourceImplData::class,
|
||||
OfflineMessageSourceImplData.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
UnsupportedMessageImpl::class,
|
||||
UnsupportedMessageImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OnlineAudioImpl::class,
|
||||
OnlineAudioImpl.serializer()
|
||||
)
|
||||
MessageSerializers.registerSerializer(
|
||||
OfflineAudioImpl::class,
|
||||
OfflineAudioImpl.serializer()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePostpro
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePreprocessor
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessageSender
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessageTransformer
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.systemProp
|
||||
@ -30,7 +31,6 @@ internal abstract class MessageProtocol(
|
||||
}
|
||||
|
||||
fun collectProcessors(processorCollector: ProcessorCollector) {
|
||||
println("collectProcessors, this=$this, class=${this::class}")
|
||||
processorCollector.collectProcessorsImpl()
|
||||
}
|
||||
|
||||
@ -74,6 +74,8 @@ internal abstract class ProcessorCollector {
|
||||
abstract fun add(transformer: OutgoingMessageTransformer)
|
||||
abstract fun add(sender: OutgoingMessageSender)
|
||||
abstract fun add(postprocessor: OutgoingMessagePostprocessor)
|
||||
|
||||
abstract fun <T : Any> add(serializer: MessageSerializer<T>)
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
package net.mamoe.mirai.internal.message.protocol
|
||||
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.polymorphic
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.ContactOrBot
|
||||
import net.mamoe.mirai.internal.contact.AbstractContact
|
||||
@ -28,6 +30,7 @@ import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelin
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.ORIGINAL_MESSAGE
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.ORIGINAL_MESSAGE_AS_CHAIN
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.STEP
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.component.ComponentKey
|
||||
import net.mamoe.mirai.internal.network.component.ComponentStorage
|
||||
import net.mamoe.mirai.internal.network.component.buildComponentStorage
|
||||
@ -38,6 +41,7 @@ import net.mamoe.mirai.internal.pipeline.ProcessResult
|
||||
import net.mamoe.mirai.internal.utils.runCoroutineInPlace
|
||||
import net.mamoe.mirai.internal.utils.structureToString
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.MessageSerializers
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.message.data.visitor.RecursiveMessageVisitor
|
||||
import net.mamoe.mirai.message.data.visitor.accept
|
||||
@ -51,6 +55,7 @@ internal interface MessageProtocolFacade {
|
||||
val decoderPipeline: MessageDecoderPipeline
|
||||
val preprocessorPipeline: OutgoingMessagePipeline
|
||||
val outgoingPipeline: OutgoingMessagePipeline
|
||||
val serializers: Collection<MessageSerializer<*>>
|
||||
|
||||
val loaded: List<MessageProtocol>
|
||||
|
||||
@ -133,13 +138,34 @@ internal interface MessageProtocolFacade {
|
||||
bot: Bot,
|
||||
): MessageChain = buildMessageChain { decode(elements, groupIdOrZero, messageSourceKind, bot, this, null) }
|
||||
|
||||
|
||||
fun createSerializersModule(): SerializersModule = SerializersModule {
|
||||
serializers.forEach { ms ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
ms as MessageSerializer<SingleMessage>
|
||||
for (superclass in ms.superclasses) {
|
||||
polymorphic(superclass) {
|
||||
subclass(ms.forClass, ms.serializer)
|
||||
}
|
||||
}
|
||||
if (ms.registerAlsoContextual) {
|
||||
contextual(ms.forClass, ms.serializer)
|
||||
}
|
||||
// contextual(ms.forClass, ms.serializer)
|
||||
}
|
||||
}
|
||||
|
||||
fun copy(): MessageProtocolFacade
|
||||
|
||||
/**
|
||||
* The default global instance.
|
||||
*/
|
||||
companion object INSTANCE : MessageProtocolFacade by MessageProtocolFacadeImpl(),
|
||||
ComponentKey<MessageProtocolFacade>
|
||||
ComponentKey<MessageProtocolFacade> {
|
||||
init {
|
||||
MessageSerializers.registerSerializers(createSerializersModule())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun MessageProtocolFacade.decodeAndRefineLight(
|
||||
@ -167,6 +193,7 @@ internal class MessageProtocolFacadeImpl(
|
||||
override val decoderPipeline: MessageDecoderPipeline = MessageDecoderPipelineImpl()
|
||||
override val preprocessorPipeline: OutgoingMessagePipeline = OutgoingMessagePipelineImpl()
|
||||
override val outgoingPipeline: OutgoingMessagePipeline = OutgoingMessagePipelineImpl()
|
||||
override val serializers: MutableCollection<MessageSerializer<*>> = ArrayList(10)
|
||||
|
||||
override val loaded: List<MessageProtocol> = kotlin.run {
|
||||
val instances = protocols
|
||||
@ -201,6 +228,10 @@ internal class MessageProtocolFacadeImpl(
|
||||
override fun add(postprocessor: OutgoingMessagePostprocessor) {
|
||||
outgoingPipeline.registerProcessor(OutgoingMessageProcessorAdapter(postprocessor))
|
||||
}
|
||||
|
||||
override fun <T : Any> add(serializer: MessageSerializer<T>) {
|
||||
serializers.add(serializer)
|
||||
}
|
||||
})
|
||||
}
|
||||
instances.toList()
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.protocol.impl
|
||||
|
||||
import net.mamoe.mirai.internal.message.data.OfflineAudioImpl
|
||||
import net.mamoe.mirai.internal.message.data.OnlineAudioImpl
|
||||
import net.mamoe.mirai.internal.message.protocol.MessageProtocol
|
||||
import net.mamoe.mirai.internal.message.protocol.ProcessorCollector
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.message.data.*
|
||||
|
||||
internal class AudioProtocol : MessageProtocol() {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
MessageSerializer.superclassesScope(
|
||||
OnlineAudio::class,
|
||||
Audio::class,
|
||||
MessageContent::class,
|
||||
SingleMessage::class
|
||||
) {
|
||||
add(MessageSerializer(OnlineAudioImpl::class, OnlineAudioImpl.serializer()))
|
||||
}
|
||||
MessageSerializer.superclassesScope(
|
||||
OfflineAudio::class,
|
||||
Audio::class,
|
||||
MessageContent::class,
|
||||
SingleMessage::class
|
||||
) {
|
||||
add(MessageSerializer(OfflineAudioImpl::class, OfflineAudioImpl.serializer()))
|
||||
}
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
add(
|
||||
MessageSerializer(
|
||||
net.mamoe.mirai.message.data.Voice::class,
|
||||
net.mamoe.mirai.message.data.Voice.serializer()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -16,11 +16,14 @@ import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoder
|
||||
import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoder
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.HummerCommelem
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.message.data.Face
|
||||
import net.mamoe.mirai.message.data.MessageContent
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
import net.mamoe.mirai.utils.toByteArray
|
||||
|
||||
@ -29,6 +32,15 @@ internal class FaceProtocol : MessageProtocol() {
|
||||
add(Encoder())
|
||||
add(Type1Decoder())
|
||||
add(Type2Decoder())
|
||||
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
add(
|
||||
MessageSerializer(
|
||||
Face::class,
|
||||
Face.serializer()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class Encoder : MessageEncoder<Face> {
|
||||
|
@ -26,6 +26,7 @@ import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelin
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.components
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessageSender
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessageTransformer
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.message.source.createMessageReceipt
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ObjMsg
|
||||
@ -33,6 +34,8 @@ import net.mamoe.mirai.internal.network.protocol.packet.chat.FileManagement
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.readProtoBuf
|
||||
import net.mamoe.mirai.message.data.FileMessage
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.MessageContent
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.message.data.visitor.RecursiveMessageVisitor
|
||||
import net.mamoe.mirai.message.data.visitor.acceptChildren
|
||||
import net.mamoe.mirai.utils.read
|
||||
@ -51,6 +54,15 @@ internal class FileMessageProtocol : MessageProtocol() {
|
||||
})
|
||||
|
||||
add(FileMessageSender())
|
||||
|
||||
MessageSerializer.superclassesScope(FileMessage::class, MessageContent::class, SingleMessage::class) {
|
||||
add(
|
||||
MessageSerializer(
|
||||
FileMessageImpl::class,
|
||||
FileMessageImpl.serializer()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -22,18 +22,25 @@ import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoder
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Companion.collectGeneralFlags
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Companion.contact
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.HummerCommelem
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.message.data.FlashImage
|
||||
import net.mamoe.mirai.message.data.MessageContent
|
||||
import net.mamoe.mirai.message.data.PlainText
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
|
||||
internal class FlashImageProtocol : MessageProtocol() {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
add(Decoder())
|
||||
add(Encoder())
|
||||
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(FlashImage::class, FlashImage.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
private class Decoder : MessageDecoder {
|
||||
|
@ -19,14 +19,17 @@ import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelin
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.CONTACT
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.components
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePreprocessor
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.components.ClockHolder
|
||||
import net.mamoe.mirai.message.data.ForwardMessage
|
||||
import net.mamoe.mirai.message.data.RichMessage
|
||||
import net.mamoe.mirai.message.data.toMessageChain
|
||||
import net.mamoe.mirai.message.data.*
|
||||
|
||||
internal class ForwardMessageProtocol : MessageProtocol() {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
add(ForwardMessageUploader())
|
||||
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(ForwardMessage::class, ForwardMessage.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
class ForwardMessageUploader : OutgoingMessagePreprocessor {
|
||||
|
@ -26,10 +26,12 @@ import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelin
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.STEP
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.components
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessageSender
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.message.source.createMessageReceipt
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
|
||||
import net.mamoe.mirai.message.data.AtAll
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.OnlineMessageSource
|
||||
import net.mamoe.mirai.message.data.content
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
@ -40,6 +42,8 @@ import net.mamoe.mirai.utils.truncated
|
||||
internal class GeneralMessageSenderProtocol : MessageProtocol(PRIORITY_GENERAL_SENDER) {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
add(GeneralMessageSender(logger))
|
||||
|
||||
add(MessageSerializer(MessageChain::class, MessageChain.serializer(), emptyArray()))
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ internal class IgnoredMessagesProtocol : MessageProtocol(PRIORITY_IGNORE) {
|
||||
private class Encoder : MessageEncoder<SingleMessage> {
|
||||
override suspend fun MessageEncoderContext.process(data: SingleMessage) {
|
||||
when (data) {
|
||||
is ForwardMessage, // TODO: 2022/4/27 check this
|
||||
is ForwardMessage,
|
||||
is MessageSource, // mirai metadata only
|
||||
-> {
|
||||
markAsConsumed()
|
||||
|
@ -23,12 +23,12 @@ import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Co
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.CONTACT
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePreprocessor
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.CustomFace
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.utils.ImagePatcher
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.message.data.ImageType
|
||||
import net.mamoe.mirai.message.data.ShowImageFlag
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.generateImageId
|
||||
import net.mamoe.mirai.utils.toUHexString
|
||||
|
||||
@ -38,6 +38,18 @@ internal class ImageProtocol : MessageProtocol() {
|
||||
add(ImageDecoder())
|
||||
|
||||
add(ImagePatcherForGroup())
|
||||
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(Image::class, Image.Serializer, registerAlsoContextual = true))
|
||||
}
|
||||
|
||||
MessageSerializer.superclassesScope(Image::class, MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(Image::class, Image.Serializer))
|
||||
add(MessageSerializer(OfflineGroupImage::class, OfflineGroupImage.serializer()))
|
||||
add(MessageSerializer(OfflineFriendImage::class, OfflineFriendImage.serializer()))
|
||||
add(MessageSerializer(OnlineFriendImageImpl::class, OnlineFriendImageImpl.serializer()))
|
||||
add(MessageSerializer(OnlineGroupImageImpl::class, OnlineGroupImageImpl.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
private class ImagePatcherForGroup : OutgoingMessagePreprocessor {
|
||||
|
@ -17,9 +17,9 @@ import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoder
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Companion.collectGeneralFlags
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.message.data.Dice
|
||||
import net.mamoe.mirai.message.data.PlainText
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
|
||||
|
||||
@ -29,6 +29,19 @@ internal class MarketFaceProtocol : MessageProtocol() {
|
||||
add(MarketFaceImplEncoder())
|
||||
|
||||
add(MarketFaceDecoder())
|
||||
|
||||
MessageSerializer.superclassesScope(MarketFace::class, MessageContent::class, SingleMessage::class) {
|
||||
add(
|
||||
MessageSerializer(
|
||||
MarketFaceImpl::class,
|
||||
MarketFaceImpl.serializer()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
MessageSerializer.superclassesScope(MarketFace::class, MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(Dice::class, Dice.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
private class MarketFaceImplEncoder : MessageEncoder<MarketFaceImpl> {
|
||||
|
@ -22,12 +22,10 @@ import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelin
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.ORIGINAL_MESSAGE_AS_CHAIN
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePipelineContext.Companion.components
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessageSender
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.message.source.createMessageReceipt
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.MusicSharePacket
|
||||
import net.mamoe.mirai.message.data.MessageSourceKind
|
||||
import net.mamoe.mirai.message.data.MusicShare
|
||||
import net.mamoe.mirai.message.data.PlainText
|
||||
import net.mamoe.mirai.message.data.content
|
||||
import net.mamoe.mirai.message.data.*
|
||||
|
||||
internal class MusicShareProtocol : MessageProtocol() {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
@ -36,6 +34,10 @@ internal class MusicShareProtocol : MessageProtocol() {
|
||||
// add(Decoder())
|
||||
|
||||
add(Sender())
|
||||
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(MusicShare::class, MusicShare.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
private class Encoder : MessageEncoder<MusicShare> {
|
||||
|
@ -15,12 +15,15 @@ import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoder
|
||||
import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoder
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.HummerCommelem
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.message.data.MessageContent
|
||||
import net.mamoe.mirai.message.data.PlainText
|
||||
import net.mamoe.mirai.message.data.PokeMessage
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
|
||||
internal class PokeMessageProtocol : MessageProtocol() {
|
||||
companion object {
|
||||
@ -30,6 +33,10 @@ internal class PokeMessageProtocol : MessageProtocol() {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
add(Encoder())
|
||||
add(Decoder())
|
||||
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(PokeMessage::class, PokeMessage.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
private class Encoder : MessageEncoder<PokeMessage> {
|
||||
|
@ -14,14 +14,21 @@ import net.mamoe.mirai.internal.message.protocol.ProcessorCollector
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoder
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Companion.collectGeneralFlags
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.message.data.PttMessage
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
|
||||
internal class PttMessageProtocol : MessageProtocol() {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
|
||||
add(Encoder())
|
||||
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(At::class, At.serializer()))
|
||||
add(MessageSerializer(AtAll::class, AtAll.serializer()))
|
||||
add(MessageSerializer(PlainText::class, PlainText.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
private class Encoder : MessageEncoder<PttMessage> {
|
||||
|
@ -22,13 +22,10 @@ import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoder
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Companion.contact
|
||||
import net.mamoe.mirai.internal.message.protocol.outgoing.OutgoingMessagePreprocessor
|
||||
import net.mamoe.mirai.internal.message.source.MessageSourceInternal
|
||||
import net.mamoe.mirai.internal.message.source.OfflineMessageSourceImplData
|
||||
import net.mamoe.mirai.internal.message.source.ensureSequenceIdAvailable
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.message.source.*
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.message.data.At
|
||||
import net.mamoe.mirai.message.data.OnlineMessageSource
|
||||
import net.mamoe.mirai.message.data.QuoteReply
|
||||
import net.mamoe.mirai.message.data.*
|
||||
|
||||
internal class QuoteReplyProtocol : MessageProtocol(PRIORITY_METADATA) {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
@ -38,6 +35,72 @@ internal class QuoteReplyProtocol : MessageProtocol(PRIORITY_METADATA) {
|
||||
add(OutgoingMessagePreprocessor {
|
||||
currentMessageChain[QuoteReply]?.source?.ensureSequenceIdAvailable()
|
||||
})
|
||||
|
||||
MessageSerializer.superclassesScope(MessageSource::class, MessageMetadata::class, SingleMessage::class) {
|
||||
add(
|
||||
MessageSerializer(
|
||||
OnlineMessageSourceFromGroupImpl::class,
|
||||
OnlineMessageSourceFromGroupImpl.serializer()
|
||||
)
|
||||
)
|
||||
add(
|
||||
MessageSerializer(
|
||||
OnlineMessageSourceFromFriendImpl::class,
|
||||
OnlineMessageSourceFromFriendImpl.serializer()
|
||||
)
|
||||
)
|
||||
add(
|
||||
MessageSerializer(
|
||||
OnlineMessageSourceFromTempImpl::class,
|
||||
OnlineMessageSourceFromTempImpl.serializer()
|
||||
)
|
||||
)
|
||||
add(
|
||||
MessageSerializer(
|
||||
OnlineMessageSourceFromStrangerImpl::class,
|
||||
OnlineMessageSourceFromStrangerImpl.serializer()
|
||||
)
|
||||
)
|
||||
add(
|
||||
MessageSerializer(
|
||||
OnlineMessageSourceToGroupImpl::class,
|
||||
OnlineMessageSourceToGroupImpl.serializer()
|
||||
)
|
||||
)
|
||||
add(
|
||||
MessageSerializer(
|
||||
OnlineMessageSourceToFriendImpl::class,
|
||||
OnlineMessageSourceToFriendImpl.serializer()
|
||||
)
|
||||
)
|
||||
add(
|
||||
MessageSerializer(
|
||||
OnlineMessageSourceToTempImpl::class,
|
||||
OnlineMessageSourceToTempImpl.serializer()
|
||||
)
|
||||
)
|
||||
add(
|
||||
MessageSerializer(
|
||||
OnlineMessageSourceToStrangerImpl::class,
|
||||
OnlineMessageSourceToStrangerImpl.serializer()
|
||||
)
|
||||
)
|
||||
add(
|
||||
MessageSerializer(
|
||||
OfflineMessageSourceImplData::class,
|
||||
OfflineMessageSourceImplData.serializer()
|
||||
)
|
||||
)
|
||||
|
||||
add(MessageSerializer(MessageSource::class, MessageSource.serializer()))
|
||||
}
|
||||
|
||||
MessageSerializer.superclassesScope(MessageMetadata::class, SingleMessage::class) {
|
||||
add(MessageSerializer(QuoteReply::class, QuoteReply.serializer()))
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
add(MessageSerializer(ShowImageFlag::class, ShowImageFlag.Serializer))
|
||||
add(MessageSerializer(MessageOrigin::class, MessageOrigin.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
private class Decoder : MessageDecoder {
|
||||
|
@ -20,6 +20,7 @@ import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoder
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Companion.collectGeneralFlags
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.message.runWithBugReport
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.message.data.*
|
||||
@ -45,6 +46,21 @@ internal class RichMessageProtocol : MessageProtocol() {
|
||||
add(LightAppDecoder())
|
||||
|
||||
add(Encoder())
|
||||
|
||||
MessageSerializer.superclassesScope(
|
||||
ServiceMessage::class,
|
||||
RichMessage::class,
|
||||
MessageContent::class,
|
||||
SingleMessage::class
|
||||
) {
|
||||
add(MessageSerializer(SimpleServiceMessage::class, SimpleServiceMessage.serializer()))
|
||||
}
|
||||
|
||||
MessageSerializer.superclassesScope(RichMessage::class, MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(LightApp::class, LightApp.serializer()))
|
||||
}
|
||||
|
||||
add(MessageSerializer(MessageOriginKind::class, MessageOriginKind.serializer(), emptyArray()))
|
||||
}
|
||||
|
||||
private class Encoder : MessageEncoder<RichMessage> {
|
||||
|
@ -23,6 +23,7 @@ import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Companion.CONTACT
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Companion.isForward
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext.Companion.originalMessage
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.read
|
||||
@ -39,6 +40,13 @@ internal class TextProtocol : MessageProtocol() {
|
||||
add(AtAllEncoder())
|
||||
|
||||
add(Decoder())
|
||||
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(PlainText::class, PlainText.serializer(), registerAlsoContextual = true))
|
||||
add(MessageSerializer(At::class, At.serializer(), registerAlsoContextual = true))
|
||||
add(MessageSerializer(AtAll::class, AtAll.serializer(), registerAlsoContextual = true))
|
||||
add(MessageSerializer(Face::class, Face.serializer(), registerAlsoContextual = true))
|
||||
}
|
||||
}
|
||||
|
||||
private class Decoder : MessageDecoder {
|
||||
|
@ -16,12 +16,25 @@ import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoder
|
||||
import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoder
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.message.data.MessageContent
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.message.data.UnsupportedMessage
|
||||
|
||||
internal class UnsupportedMessageProtocol : MessageProtocol(priority = PRIORITY_UNSUPPORTED) {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
add(Decoder())
|
||||
add(Encoder())
|
||||
|
||||
MessageSerializer.superclassesScope(UnsupportedMessage::class, MessageContent::class, SingleMessage::class) {
|
||||
add(
|
||||
MessageSerializer(
|
||||
UnsupportedMessageImpl::class,
|
||||
UnsupportedMessageImpl.serializer()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class Decoder : MessageDecoder {
|
||||
|
@ -15,16 +15,23 @@ import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoder
|
||||
import net.mamoe.mirai.internal.message.protocol.decode.MessageDecoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoder
|
||||
import net.mamoe.mirai.internal.message.protocol.encode.MessageEncoderContext
|
||||
import net.mamoe.mirai.internal.message.protocol.serialization.MessageSerializer
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.HummerCommelem
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.message.data.MessageContent
|
||||
import net.mamoe.mirai.message.data.PlainText
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.message.data.VipFace
|
||||
|
||||
internal class VipFaceProtocol : MessageProtocol() {
|
||||
override fun ProcessorCollector.collectProcessorsImpl() {
|
||||
add(Encoder())
|
||||
add(Decoder())
|
||||
|
||||
MessageSerializer.superclassesScope(MessageContent::class, SingleMessage::class) {
|
||||
add(MessageSerializer(VipFace::class, VipFace.serializer()))
|
||||
}
|
||||
}
|
||||
|
||||
private class Encoder : MessageEncoder<VipFace> {
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.protocol.serialization
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import net.mamoe.mirai.internal.message.protocol.MessageProtocol
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Collectd in [MessageProtocol.collectProcessors]
|
||||
*/
|
||||
internal class MessageSerializer<T : Any>(
|
||||
/**
|
||||
* The exact class the [serializer] is for
|
||||
*/
|
||||
val forClass: KClass<T>,
|
||||
val serializer: KSerializer<T>,
|
||||
/**
|
||||
* Polymorphic base
|
||||
*/
|
||||
val superclasses: Array<out KClass<in T>>,
|
||||
/**
|
||||
* Register also this as contextual
|
||||
*/
|
||||
val registerAlsoContextual: Boolean = superclasses.isEmpty(),
|
||||
) {
|
||||
// This can help native targets, which has no reflection support.
|
||||
|
||||
companion object {
|
||||
fun <T : SingleMessage, R> superclassesScope(
|
||||
vararg superclasses: KClass<in T>,
|
||||
block: SuperclassesScope<T>.() -> R
|
||||
): R {
|
||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||
return block(SuperclassesScope(superclasses))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
internal value class SuperclassesScope<T : SingleMessage>(
|
||||
val superclasses: Array<out KClass<in T>>,
|
||||
)
|
||||
|
||||
@Suppress("FunctionName")
|
||||
internal fun <T : SingleMessage> SuperclassesScope<in T>.MessageSerializer(
|
||||
forClass: KClass<T>,
|
||||
serializer: KSerializer<T>,
|
||||
registerAlsoContextual: Boolean = true,
|
||||
): MessageSerializer<T> = MessageSerializer(forClass, serializer, superclasses, registerAlsoContextual)
|
@ -7,6 +7,7 @@
|
||||
# https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
#
|
||||
|
||||
net.mamoe.mirai.internal.message.protocol.impl.AudioProtocol
|
||||
net.mamoe.mirai.internal.message.protocol.impl.CustomMessageProtocol
|
||||
net.mamoe.mirai.internal.message.protocol.impl.FaceProtocol
|
||||
net.mamoe.mirai.internal.message.protocol.impl.FileMessageProtocol
|
||||
|
@ -11,7 +11,7 @@
|
||||
package net.mamoe.mirai.internal
|
||||
|
||||
import net.mamoe.mirai.Mirai
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.BeforeTest
|
||||
|
||||
internal abstract class AbstractTestWithMiraiImpl : MiraiImpl() {
|
||||
@ -23,7 +23,7 @@ internal abstract class AbstractTestWithMiraiImpl : MiraiImpl() {
|
||||
net.mamoe.mirai._MiraiInstance.set(this)
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@AfterTest
|
||||
fun restoreMiraiImpl() {
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
net.mamoe.mirai._MiraiInstance.set(originalImpl)
|
27
mirai-core/src/commonTest/kotlin/BotFactoryTest.kt
Normal file
27
mirai-core/src/commonTest/kotlin/BotFactoryTest.kt
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.BotFactory
|
||||
import net.mamoe.mirai.internal.test.AbstractTest
|
||||
import kotlin.test.Test
|
||||
|
||||
internal class BotFactoryTest : AbstractTest() {
|
||||
|
||||
@Test
|
||||
fun `inlined newBot in Kotlin`() {
|
||||
runBlocking {
|
||||
BotFactory.newBot(123, "") {
|
||||
inheritCoroutineContext()
|
||||
}.close()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
* 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.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal
|
||||
package net.mamoe.mirai.internal.message.data
|
||||
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.safeCast
|
@ -28,11 +28,7 @@ import net.mamoe.mirai.message.data.buildForwardMessage
|
||||
import net.mamoe.mirai.message.data.toMessageChain
|
||||
import net.mamoe.mirai.utils.Clock
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertIs
|
||||
import kotlin.test.assertSame
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.*
|
||||
|
||||
internal class MessageReceiptTest : AbstractTest(), GroupExtensions {
|
||||
private val bot = MockBot()
|
@ -29,8 +29,8 @@ import net.mamoe.mirai.internal.test.runBlockingUnit
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.message.data.MessageChain.Companion.serializeToJsonString
|
||||
import net.mamoe.mirai.utils.PlatformLogger
|
||||
import net.mamoe.mirai.utils.hexToBytes
|
||||
import net.mamoe.mirai.utils.isSameType
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
@ -41,7 +41,7 @@ open class TM(private val name: String = Random.nextInt().toString()) : SingleMe
|
||||
override fun contentToString(): String = name
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
if (!isSameType(this, other)) return false
|
||||
|
||||
other as TM
|
||||
|
||||
@ -338,7 +338,7 @@ private suspend fun testRecursiveRefine(list: List<ImMsgBody.Elem>, expected: Me
|
||||
}
|
||||
|
||||
private fun assertNodesEquals(excepted: List<ForwardMessage.Node>, actual: List<ForwardMessage.Node>) {
|
||||
assert(excepted.size == actual.size) { "Length not match" }
|
||||
assertEquals(excepted.size, actual.size, "Length not match")
|
||||
for (i in excepted.indices) {
|
||||
val en = excepted[i]
|
||||
val an = actual[i]
|
||||
@ -349,11 +349,30 @@ private fun assertNodesEquals(excepted: List<ForwardMessage.Node>, actual: List<
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
private object Color {
|
||||
const val RESET = "\u001b[0m"
|
||||
const val WHITE = "\u001b[97m"
|
||||
const val RED = "\u001b[31m"
|
||||
const val EMERALD_GREEN = "\u001b[32m"
|
||||
const val GOLD = "\u001b[33m"
|
||||
const val BLUE = "\u001b[34m"
|
||||
const val PURPLE = "\u001b[35m"
|
||||
const val GREEN = "\u001b[36m"
|
||||
const val GRAY = "\u001b[90m"
|
||||
const val LIGHT_RED = "\u001b[91m"
|
||||
const val LIGHT_GREEN = "\u001b[92m"
|
||||
const val LIGHT_YELLOW = "\u001b[93m"
|
||||
const val LIGHT_BLUE = "\u001b[94m"
|
||||
const val LIGHT_PURPLE = "\u001b[95m"
|
||||
const val LIGHT_CYAN = "\u001b[96m"
|
||||
}
|
||||
|
||||
private fun assertMessageChainEquals(expected: MessageChain, actual: MessageChain) {
|
||||
val color = object : PlatformLogger("") {
|
||||
val yellow get() = Color.LIGHT_YELLOW.toString()
|
||||
val green get() = Color.LIGHT_GREEN.toString()
|
||||
val reset get() = Color.RESET.toString()
|
||||
val color = object {
|
||||
val yellow get() = Color.LIGHT_YELLOW
|
||||
val green get() = Color.LIGHT_GREEN
|
||||
val reset get() = Color.RESET
|
||||
}
|
||||
|
||||
fun compare(expected: MessageChain, actual: MessageChain): Boolean {
|
@ -16,16 +16,16 @@ import kotlinx.serialization.json.*
|
||||
import kotlinx.serialization.serializer
|
||||
import net.mamoe.mirai.Mirai
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.test.AbstractTest
|
||||
import net.mamoe.mirai.internal.utils.structureToString
|
||||
import net.mamoe.mirai.message.MessageSerializers
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.cast
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
internal class MessageSerializationTest {
|
||||
internal class MessageSerializationTest : AbstractTest() {
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
private val module
|
||||
get() = MessageSerializers.serializersModule
|
||||
@ -51,7 +51,7 @@ internal class MessageSerializationTest {
|
||||
println("Result: ${serializer.descriptor.serialName} $serialized")
|
||||
serialized.deserialize(serializer)
|
||||
}.getOrElse {
|
||||
throw AssertionError("Failed to serialize $t", it)
|
||||
throw IllegalStateException("Failed to serialize $t", it)
|
||||
}
|
||||
assertEquals(
|
||||
t,
|
||||
@ -113,14 +113,6 @@ internal class MessageSerializationTest {
|
||||
FileMessageImpl("id", 2, "name", 1)
|
||||
)
|
||||
|
||||
companion object {
|
||||
@BeforeAll
|
||||
@JvmStatic
|
||||
fun init() {
|
||||
Mirai
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class W(
|
||||
val m: FileMessage
|
||||
@ -170,10 +162,18 @@ internal class MessageSerializationTest {
|
||||
@Test
|
||||
fun `test contextual serialization`() {
|
||||
for (message in testMessageContentInstances) {
|
||||
testSerialization(message, module.serializer(message.javaClass))
|
||||
testSerialization(
|
||||
message,
|
||||
module.getContextual(message::class)?.cast()
|
||||
?: error("No contextual serializer found for ${message::class}")
|
||||
)
|
||||
}
|
||||
for (message in testConstrainSingleMessageInstances) {
|
||||
testSerialization(message, module.serializer(message.javaClass))
|
||||
testSerialization(
|
||||
message,
|
||||
module.getContextual(message::class)?.cast()
|
||||
?: error("No contextual serializer found for ${message::class}")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ internal class MessageSerializationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test MessageSource serializable from #1273`() {
|
||||
fun `test MessageSource serializable from issue 1273`() {
|
||||
// #1273
|
||||
|
||||
val a = """
|
@ -9,8 +9,14 @@
|
||||
|
||||
package net.mamoe.mirai.internal.message.protocol.impl
|
||||
|
||||
import net.mamoe.mirai.internal.utils.structureToString
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.json.Json
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.utils.structureToStringIfAvailable
|
||||
import net.mamoe.mirai.message.MessageSerializers
|
||||
import net.mamoe.mirai.message.data.MessageChain.Companion.serializeToJsonString
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.message.data.messageChainOf
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.asserter
|
||||
|
||||
@ -74,10 +80,29 @@ internal interface EqualityAsserter {
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> structureToStringOrOrdinaryString(it: T): String =
|
||||
it.structureToString().ifBlank {
|
||||
it.structureToStringIfAvailable() ?: error("structureToString is not available")
|
||||
}
|
||||
private val json = Json {
|
||||
isLenient = true
|
||||
prettyPrint = true
|
||||
serializersModule = MessageSerializers.serializersModule
|
||||
}
|
||||
|
||||
private fun <T> structureToStringOrOrdinaryString(value: T): String {
|
||||
if (value == null) return "null"
|
||||
val valueNotNull: T & Any = value
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return valueNotNull.structureToStringIfAvailable()
|
||||
// fallback for native
|
||||
?: kotlin.run {
|
||||
if (valueNotNull is SingleMessage) {
|
||||
messageChainOf(valueNotNull).serializeToJsonString(json) // use the stable serialization approach
|
||||
} else json.encodeToString(
|
||||
when (valueNotNull) {
|
||||
is ImMsgBody.Elem -> ImMsgBody.Elem.serializer()
|
||||
else -> error("Unsupported type: $valueNotNull")
|
||||
} as KSerializer<Any>, valueNotNull
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object OrdinaryThenStructural : EqualityAsserter {
|
||||
|
@ -14,10 +14,15 @@ package net.mamoe.mirai.internal
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.okhttp.*
|
||||
import io.ktor.client.features.*
|
||||
import kotlinx.atomicfu.atomic
|
||||
import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade
|
||||
|
||||
private val initialized = atomic(false)
|
||||
|
||||
@Suppress("FunctionName")
|
||||
internal actual fun _MiraiImpl_static_init() {
|
||||
// nop
|
||||
if (!initialized.compareAndSet(expect = false, update = true)) return
|
||||
MessageProtocolFacade.INSTANCE // register serializers
|
||||
}
|
||||
|
||||
internal actual fun createDefaultHttpClient(): HttpClient {
|
||||
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2021 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/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.BotFactory
|
||||
import kotlin.test.Test
|
||||
|
||||
internal class BotFactoryTest {
|
||||
|
||||
@Test
|
||||
fun `inlined newBot in Kotlin`() {
|
||||
runBlocking {
|
||||
BotFactory.newBot(123, "") {
|
||||
inheritCoroutineContext()
|
||||
}.close()
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
package net.mamoe.mirai.internal
|
||||
|
||||
import kotlinx.atomicfu.atomic
|
||||
import net.mamoe.mirai.internal.message.protocol.MessageProtocolFacade
|
||||
import net.mamoe.mirai.internal.utils.MiraiCoreServices
|
||||
|
||||
|
||||
@ -24,4 +25,5 @@ private val initialized = atomic(false)
|
||||
internal actual fun _MiraiImpl_static_init() {
|
||||
if (!initialized.compareAndSet(expect = false, update = true)) return
|
||||
MiraiCoreServices.registerAll()
|
||||
MessageProtocolFacade.INSTANCE // register serializers
|
||||
}
|
||||
|
@ -36,6 +36,10 @@ internal object MiraiCoreServices {
|
||||
msgProtocol,
|
||||
"net.mamoe.mirai.internal.message.protocol.impl.CustomMessageProtocol"
|
||||
) { net.mamoe.mirai.internal.message.protocol.impl.CustomMessageProtocol() }
|
||||
Services.register(
|
||||
msgProtocol,
|
||||
"net.mamoe.mirai.internal.message.protocol.impl.AudioProtocol"
|
||||
) { net.mamoe.mirai.internal.message.protocol.impl.AudioProtocol() }
|
||||
Services.register(
|
||||
msgProtocol,
|
||||
"net.mamoe.mirai.internal.message.protocol.impl.FaceProtocol"
|
||||
|
Loading…
Reference in New Issue
Block a user