mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-10 04:00:08 +08:00
Fix serialization
This commit is contained in:
parent
5196cc410a
commit
eacdfed97a
@ -12,6 +12,7 @@ package net.mamoe.mirai.message
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.modules.PolymorphicModuleBuilder
|
||||
@ -21,6 +22,7 @@ import kotlinx.serialization.modules.polymorphic
|
||||
import net.mamoe.mirai.Mirai
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||
import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@MiraiExperimentalApi
|
||||
@ -34,9 +36,12 @@ public interface MessageSerializer {
|
||||
public fun clearRegisteredSerializers()
|
||||
}
|
||||
|
||||
internal object MessageSourceSerializer : KSerializer<MessageSource> {
|
||||
@MiraiInternalApi
|
||||
public open class MessageSourceSerializerImpl(serialName: String) : KSerializer<MessageSource> {
|
||||
public companion object : MessageSourceSerializerImpl("net.mamoe.mirai.message.data.MessageSource")
|
||||
|
||||
@Serializable
|
||||
class SerialData(
|
||||
internal class SerialData(
|
||||
val kind: MessageSourceKind,
|
||||
val bot: Long,
|
||||
val ids: IntArray,
|
||||
@ -47,7 +52,17 @@ internal object MessageSourceSerializer : KSerializer<MessageSource> {
|
||||
val originalMessage: MessageChain,
|
||||
)
|
||||
|
||||
override val descriptor: SerialDescriptor = SerialData.serializer().descriptor
|
||||
override val descriptor: SerialDescriptor = buildClassSerialDescriptor(serialName) {
|
||||
val desc = SerialData.serializer().descriptor
|
||||
repeat(SerialData.serializer().descriptor.elementsCount) { index ->
|
||||
element(
|
||||
desc.getElementName(index),
|
||||
desc.getElementDescriptor(index),
|
||||
desc.getElementAnnotations(index),
|
||||
desc.isElementOptional(index)
|
||||
)
|
||||
}
|
||||
}
|
||||
// buildClassSerialDescriptor("MessageSource") {
|
||||
// element("bot", Long.serializer().descriptor)
|
||||
// element("ids", ArraySerializer(Int.serializer()).descriptor)
|
||||
@ -96,7 +111,6 @@ private val builtInSerializersModule by lazy {
|
||||
contextual(CustomMessage::class, CustomMessage.serializer())
|
||||
contextual(CustomMessageMetadata::class, CustomMessageMetadata.serializer())
|
||||
contextual(Face::class, Face.serializer())
|
||||
contextual(MessageSource::class, MessageSource.serializer())
|
||||
contextual(Image::class, Image.Serializer)
|
||||
contextual(PlainText::class, PlainText.serializer())
|
||||
contextual(QuoteReply::class, QuoteReply.serializer())
|
||||
@ -117,8 +131,12 @@ private val builtInSerializersModule by lazy {
|
||||
contextual(FlashImage::class, FlashImage.serializer())
|
||||
|
||||
fun PolymorphicModuleBuilder<SingleMessage>.singleMessageSubclasses() {
|
||||
// subclass(MessageSource::class, MessageSource.serializer())
|
||||
}
|
||||
|
||||
// contextual(MessageSource::class, MessageSource.serializer())
|
||||
polymorphicDefault(MessageSource::class) { MessageSource.serializer() }
|
||||
|
||||
fun PolymorphicModuleBuilder<MessageMetadata>.messageMetadataSubclasses() {
|
||||
subclass(MessageSource::class, MessageSource.serializer())
|
||||
subclass(QuoteReply::class, QuoteReply.serializer())
|
||||
@ -148,7 +166,14 @@ private val builtInSerializersModule by lazy {
|
||||
subclass(FlashImage::class, FlashImage.serializer())
|
||||
}
|
||||
|
||||
contextual(Message::class, Message.Serializer)
|
||||
// contextual(SingleMessage::class, SingleMessage.Serializer)
|
||||
contextual(MessageChain::class, MessageChain.Serializer)
|
||||
contextual(MessageChainImpl::class, MessageChainImpl.serializer())
|
||||
|
||||
polymorphic(MessageChain::class) {
|
||||
subclass(MessageChainImpl::class, MessageChainImpl.serializer())
|
||||
}
|
||||
polymorphicDefault(MessageChain::class) { MessageChainImpl.serializer() }
|
||||
|
||||
polymorphic(AbstractServiceMessage::class) {
|
||||
@ -156,9 +181,15 @@ private val builtInSerializersModule by lazy {
|
||||
subclass(ForwardMessageInternal::class, ForwardMessageInternal.serializer())
|
||||
}
|
||||
|
||||
// polymorphic(SingleMessage::class) {
|
||||
// subclass(MessageSource::class, MessageSource.serializer())
|
||||
// default {
|
||||
// Message.Serializer.serializersModule.getPolymorphic(Message::class, it)
|
||||
// }
|
||||
// }
|
||||
|
||||
polymorphicDefault(Image::class) { Image.Serializer }
|
||||
|
||||
contextual(Message::class, Message.Serializer)
|
||||
// polymorphic(Message::class) {
|
||||
// subclass(PlainText::class, PlainText.serializer())
|
||||
// }
|
||||
@ -166,6 +197,7 @@ private val builtInSerializersModule by lazy {
|
||||
messageContentSubclasses()
|
||||
messageMetadataSubclasses()
|
||||
singleMessageSubclasses()
|
||||
subclass(MessageChainImpl::class, MessageChainImpl.serializer())
|
||||
}
|
||||
|
||||
//contextual(SingleMessage::class, SingleMessage.Serializer)
|
||||
|
@ -209,8 +209,12 @@ public interface Message { // must be interface. Don't consider any changes.
|
||||
*/
|
||||
@JvmOverloads
|
||||
@JvmStatic
|
||||
public fun deserializeFromJsonString(string: String, json: Json = Json.Default): Message =
|
||||
json.decodeFromString(Serializer, string)
|
||||
public fun deserializeFromJsonString(
|
||||
string: String,
|
||||
json: Json = Json { serializersModule = Serializer.serializersModule }
|
||||
): Message {
|
||||
return json.decodeFromString(Serializer, string)
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 [Message] 序列化为 JSON 字符串.
|
||||
@ -218,8 +222,9 @@ public interface Message { // must be interface. Don't consider any changes.
|
||||
*/
|
||||
@JvmOverloads
|
||||
@JvmStatic
|
||||
public fun Message.serializeToJsonString(json: Json = Json.Default): String =
|
||||
json.encodeToString(Serializer, this)
|
||||
public fun Message.serializeToJsonString(
|
||||
json: Json = Json { serializersModule = Serializer.serializersModule }
|
||||
): String = json.encodeToString(Serializer, this)
|
||||
|
||||
/**
|
||||
* 将 [Message] 序列化为指定格式的字符串.
|
||||
@ -320,9 +325,10 @@ public inline operator fun Message.times(count: Int): MessageChain = this.repeat
|
||||
/**
|
||||
* 单个消息元素. 与之相对的是 [MessageChain], 是多个 [SingleMessage] 的集合.
|
||||
*/
|
||||
@Serializable(SingleMessage.Serializer::class)
|
||||
// @Serializable(SingleMessage.Serializer::class)
|
||||
public interface SingleMessage : Message {
|
||||
public object Serializer : KSerializer<SingleMessage> by PolymorphicSerializer(SingleMessage::class)
|
||||
// @kotlinx.serialization.Serializer(forClass = SingleMessage::class)
|
||||
// public object Serializer : KSerializer<SingleMessage> by PolymorphicSerializer(SingleMessage::class)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,12 +13,12 @@
|
||||
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.Json
|
||||
import net.mamoe.mirai.event.events.MessageEvent
|
||||
import net.mamoe.mirai.message.code.CodableMessage
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.quote
|
||||
@ -104,6 +104,42 @@ public interface MessageChain : Message, List<SingleMessage>, RandomAccess, Coda
|
||||
override fun appendMiraiCode(builder: StringBuilder) {
|
||||
forEach { it.safeCast<CodableMessage>()?.appendMiraiCode(builder) }
|
||||
}
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* 从 JSON 字符串解析 [MessageChain]
|
||||
* @see serializeToJsonString
|
||||
*/
|
||||
@JvmOverloads
|
||||
@JvmStatic
|
||||
public fun deserializeFromJsonString(
|
||||
string: String,
|
||||
json: Json = Json { serializersModule = Message.Serializer.serializersModule }
|
||||
): MessageChain {
|
||||
return json.decodeFromString(Serializer, string)
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 [MessageChain] 序列化为 JSON 字符串.
|
||||
* @see deserializeFromJsonString
|
||||
*/
|
||||
@JvmOverloads
|
||||
@JvmStatic
|
||||
public fun MessageChain.serializeToJsonString(
|
||||
json: Json = Json { serializersModule = Message.Serializer.serializersModule }
|
||||
): String = json.encodeToString(Message.Serializer, this)
|
||||
|
||||
/**
|
||||
* 将 [MessageChain] 序列化为指定格式的字符串.
|
||||
*
|
||||
* @see serializeToJsonString
|
||||
* @see StringFormat.encodeToString
|
||||
*/
|
||||
@ExperimentalSerializationApi
|
||||
@JvmStatic
|
||||
public fun MessageChain.serializeToString(format: StringFormat): String =
|
||||
format.encodeToString(Serializer, this)
|
||||
}
|
||||
}
|
||||
|
||||
// region accessors
|
||||
|
@ -25,7 +25,7 @@ import net.mamoe.mirai.contact.*
|
||||
import net.mamoe.mirai.event.events.MessageEvent
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.MessageReceipt.Companion.recall
|
||||
import net.mamoe.mirai.message.MessageSourceSerializer
|
||||
import net.mamoe.mirai.message.MessageSourceSerializerImpl
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.isAboutFriend
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.isAboutGroup
|
||||
import net.mamoe.mirai.message.data.MessageSource.Key.isAboutTemp
|
||||
@ -69,7 +69,7 @@ import net.mamoe.mirai.utils.safeCast
|
||||
*
|
||||
* @see buildMessageSource 构造一个 [OfflineMessageSource]
|
||||
*/
|
||||
@Serializable(MessageSourceSerializer::class)
|
||||
@Serializable(MessageSourceSerializerImpl.Companion::class)
|
||||
public sealed class MessageSource : Message, MessageMetadata, ConstrainSingle {
|
||||
@ExperimentalMessageKey
|
||||
public final override val key: MessageKey<MessageSource>
|
||||
|
@ -25,7 +25,6 @@ import net.mamoe.mirai.internal.contact.*
|
||||
import net.mamoe.mirai.internal.message.*
|
||||
import net.mamoe.mirai.internal.network.highway.HighwayHelper
|
||||
import net.mamoe.mirai.internal.network.protocol.data.jce.SvcDevLoginInfo
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.LongMsg
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.voice.PttStore
|
||||
@ -40,7 +39,6 @@ import net.mamoe.mirai.message.data.Image.Key.FRIEND_IMAGE_ID_REGEX_2
|
||||
import net.mamoe.mirai.message.data.Image.Key.GROUP_IMAGE_ID_REGEX
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -54,6 +52,15 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
|
||||
Message.Serializer.registerSerializer(OfflineGroupImage::class, OfflineGroupImage.serializer())
|
||||
Message.Serializer.registerSerializer(OfflineFriendImage::class, OfflineFriendImage.serializer())
|
||||
Message.Serializer.registerSerializer(MarketFaceImpl::class, MarketFaceImpl.serializer())
|
||||
Message.Serializer.registerSerializer(
|
||||
OfflineMessageSourceImplData::class,
|
||||
OfflineMessageSourceImplData.serializer()
|
||||
)
|
||||
|
||||
Message.Serializer.registerSerializer(
|
||||
MessageSourceFromGroupImpl::class,
|
||||
MessageSourceFromGroupImpl.serializer()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -843,38 +850,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
|
||||
time: Int,
|
||||
internalIds: IntArray,
|
||||
originalMessage: MessageChain
|
||||
): OfflineMessageSource {
|
||||
return object : OfflineMessageSource(), MessageSourceInternal {
|
||||
override val kind: MessageSourceKind get() = kind
|
||||
override val ids: IntArray get() = ids
|
||||
override val botId: Long get() = botId
|
||||
override val time: Int get() = time
|
||||
override val fromId: Long get() = fromUin
|
||||
override val targetId: Long get() = targetUin
|
||||
override val originalMessage: MessageChain get() = originalMessage
|
||||
override val sequenceIds: IntArray = ids
|
||||
override val internalIds: IntArray = internalIds
|
||||
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
|
||||
|
||||
override fun toJceData(): ImMsgBody.SourceMsg {
|
||||
return ImMsgBody.SourceMsg(
|
||||
origSeqs = sequenceIds,
|
||||
senderUin = fromUin,
|
||||
toUin = 0,
|
||||
flag = 1,
|
||||
elems = originalMessage.toRichTextElems(
|
||||
null, //forGroup = kind == MessageSourceKind.GROUP,
|
||||
withGeneralFlags = false
|
||||
),
|
||||
type = 0,
|
||||
time = time,
|
||||
pbReserve = EMPTY_BYTE_ARRAY,
|
||||
srcMsg = EMPTY_BYTE_ARRAY
|
||||
): OfflineMessageSource = OfflineMessageSourceImplData(
|
||||
kind, ids, botId, time, fromUin, targetUin, originalMessage, internalIds
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -11,6 +11,8 @@
|
||||
|
||||
package net.mamoe.mirai.internal.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.Friend
|
||||
import net.mamoe.mirai.contact.Member
|
||||
@ -22,6 +24,7 @@ import net.mamoe.mirai.internal.network.protocol.data.proto.SourceMsg
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.EMPTY_BYTE_ARRAY
|
||||
import net.mamoe.mirai.internal.utils._miraiContentToString
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.message.MessageSourceSerializerImpl
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
@ -32,12 +35,17 @@ import net.mamoe.mirai.utils.mapToIntArray
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
internal interface MessageSourceInternal {
|
||||
@Transient
|
||||
val sequenceIds: IntArray
|
||||
|
||||
@Transient
|
||||
val internalIds: IntArray // randomId
|
||||
|
||||
@Deprecated("don't use this internally. Use sequenceId or random instead.", level = DeprecationLevel.ERROR)
|
||||
@Transient
|
||||
val ids: IntArray
|
||||
|
||||
@Transient
|
||||
val isRecalledOrPlanned: AtomicBoolean
|
||||
|
||||
fun toJceData(): ImMsgBody.SourceMsg
|
||||
@ -148,10 +156,14 @@ internal class MessageSourceFromTempImpl(
|
||||
override fun toJceData(): ImMsgBody.SourceMsg = jceData
|
||||
}
|
||||
|
||||
@Serializable(MessageSourceFromGroupImpl.Serializer::class)
|
||||
internal data class MessageSourceFromGroupImpl(
|
||||
override val bot: Bot,
|
||||
private val msg: List<MsgComm.Msg>
|
||||
) : OnlineMessageSource.Incoming.FromGroup(), MessageSourceInternal {
|
||||
object Serializer : MessageSourceSerializerImpl("net.mamoe.mirai.internal.message.MessageSourceFromGroupImpl")
|
||||
|
||||
@Transient
|
||||
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
|
||||
override val sequenceIds: IntArray get() = msg.mapToIntArray { it.msgHead.msgSeq }
|
||||
override val internalIds: IntArray get() = msg.mapToIntArray { it.msgBody.richText.attr!!.random }
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
package net.mamoe.mirai.internal.message
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
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.network.protocol.data.proto.SourceMsg
|
||||
@ -22,6 +24,70 @@ import net.mamoe.mirai.message.data.OfflineMessageSource
|
||||
import net.mamoe.mirai.utils.mapToIntArray
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
@Serializable
|
||||
internal data class OfflineMessageSourceImplData(
|
||||
override val kind: MessageSourceKind,
|
||||
override val ids: IntArray,
|
||||
override val botId: Long,
|
||||
override val time: Int,
|
||||
override val fromId: Long,
|
||||
override val targetId: Long,
|
||||
override val originalMessage: MessageChain,
|
||||
override val internalIds: IntArray,
|
||||
) : OfflineMessageSource(), MessageSourceInternal {
|
||||
override val sequenceIds: IntArray get() = ids
|
||||
|
||||
@Transient
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
|
||||
|
||||
override fun toJceData(): ImMsgBody.SourceMsg {
|
||||
return ImMsgBody.SourceMsg(
|
||||
origSeqs = sequenceIds,
|
||||
senderUin = fromId,
|
||||
toUin = 0,
|
||||
flag = 1,
|
||||
elems = originalMessage.toRichTextElems(
|
||||
null, //forGroup = kind == MessageSourceKind.GROUP,
|
||||
withGeneralFlags = false
|
||||
),
|
||||
type = 0,
|
||||
time = time,
|
||||
pbReserve = net.mamoe.mirai.internal.EMPTY_BYTE_ARRAY,
|
||||
srcMsg = net.mamoe.mirai.internal.EMPTY_BYTE_ARRAY
|
||||
)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as OfflineMessageSourceImplData
|
||||
|
||||
if (kind != other.kind) return false
|
||||
if (!ids.contentEquals(other.ids)) return false
|
||||
if (botId != other.botId) return false
|
||||
if (time != other.time) return false
|
||||
if (fromId != other.fromId) return false
|
||||
if (targetId != other.targetId) return false
|
||||
if (originalMessage != other.originalMessage) return false
|
||||
if (!internalIds.contentEquals(other.internalIds)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = kind.hashCode()
|
||||
result = 31 * result + ids.contentHashCode()
|
||||
result = 31 * result + botId.hashCode()
|
||||
result = 31 * result + time
|
||||
result = 31 * result + fromId.hashCode()
|
||||
result = 31 * result + targetId.hashCode()
|
||||
result = 31 * result + originalMessage.hashCode()
|
||||
result = 31 * result + internalIds.contentHashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
internal class OfflineMessageSourceImplByMsg(
|
||||
// from other sources' originalMessage
|
||||
|
@ -563,7 +563,7 @@ internal class ImMsgBody : ProtoBuf {
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
internal class MarketFace(
|
||||
internal data class MarketFace(
|
||||
@ProtoNumber(1) @JvmField val faceName: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@ProtoNumber(2) @JvmField val itemType: Int = 0,
|
||||
@ProtoNumber(3) @JvmField val faceInfo: Int = 0,
|
||||
@ -577,7 +577,48 @@ internal class ImMsgBody : ProtoBuf {
|
||||
@ProtoNumber(11) @JvmField val imageHeight: Int = 0,
|
||||
@ProtoNumber(12) @JvmField val mobileParam: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@ProtoNumber(13) @JvmField val pbReserve: ByteArray = EMPTY_BYTE_ARRAY
|
||||
) : ProtoBuf
|
||||
) : ProtoBuf {
|
||||
@Suppress("DuplicatedCode")
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as MarketFace
|
||||
|
||||
if (!faceName.contentEquals(other.faceName)) return false
|
||||
if (itemType != other.itemType) return false
|
||||
if (faceInfo != other.faceInfo) return false
|
||||
if (!faceId.contentEquals(other.faceId)) return false
|
||||
if (tabId != other.tabId) return false
|
||||
if (subType != other.subType) return false
|
||||
if (!key.contentEquals(other.key)) return false
|
||||
if (!param.contentEquals(other.param)) return false
|
||||
if (mediaType != other.mediaType) return false
|
||||
if (imageWidth != other.imageWidth) return false
|
||||
if (imageHeight != other.imageHeight) return false
|
||||
if (!mobileParam.contentEquals(other.mobileParam)) return false
|
||||
if (!pbReserve.contentEquals(other.pbReserve)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = faceName.contentHashCode()
|
||||
result = 31 * result + itemType
|
||||
result = 31 * result + faceInfo
|
||||
result = 31 * result + faceId.contentHashCode()
|
||||
result = 31 * result + tabId
|
||||
result = 31 * result + subType
|
||||
result = 31 * result + key.contentHashCode()
|
||||
result = 31 * result + param.contentHashCode()
|
||||
result = 31 * result + mediaType
|
||||
result = 31 * result + imageWidth
|
||||
result = 31 * result + imageHeight
|
||||
result = 31 * result + mobileParam.contentHashCode()
|
||||
result = 31 * result + pbReserve.contentHashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
internal class MarketTrans(
|
||||
|
@ -13,16 +13,19 @@ import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.serializer
|
||||
import net.mamoe.mirai.Mirai
|
||||
import net.mamoe.mirai.internal.message.MarketFaceImpl
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
internal class MessageSerializationTest {
|
||||
private val module = Message.Serializer.serializersModule
|
||||
private val format = Json {
|
||||
private val module get() = Message.Serializer.serializersModule
|
||||
private val format
|
||||
get() = Json {
|
||||
serializersModule = module
|
||||
useArrayPolymorphism = false
|
||||
useArrayPolymorphism = false // ?
|
||||
}
|
||||
|
||||
private inline fun <reified T : Any> T.serialize(serializer: KSerializer<T> = module.serializer()): String {
|
||||
@ -34,23 +37,57 @@ internal class MessageSerializationTest {
|
||||
}
|
||||
|
||||
private inline fun <reified T : Any> testSerialization(t: T, serializer: KSerializer<T> = module.serializer()) {
|
||||
val deserialized = t.serialize(serializer).deserialize(serializer)
|
||||
assertEquals(
|
||||
t,
|
||||
t.serialize(serializer).deserialize(serializer),
|
||||
message = "serialized string: ${t.serialize(serializer)}"
|
||||
deserialized,
|
||||
message = "serialized string: ${t.serialize(serializer)}\ndeserialized string: ${
|
||||
deserialized.serialize(
|
||||
serializer
|
||||
)
|
||||
}\n"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private val image = Image("{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.mirai")
|
||||
private val testMessageContentInstances: Array<out MessageContent> = arrayOf(
|
||||
PlainText("test"),
|
||||
At(123456),
|
||||
AtAll,
|
||||
Image("{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.mirai"),
|
||||
image,
|
||||
image.toForwardMessage(1L, "test"),
|
||||
VipFace(VipFace.AiXin, 1),
|
||||
PokeMessage.BaoBeiQiu,
|
||||
Face(Face.AI_NI),
|
||||
MarketFaceImpl(ImMsgBody.MarketFace()),
|
||||
image.flash(),
|
||||
)
|
||||
|
||||
private val emptySource = Mirai.constructMessageSource(
|
||||
1L,
|
||||
MessageSourceKind.FRIEND,
|
||||
1,
|
||||
2,
|
||||
intArrayOf(1),
|
||||
1,
|
||||
intArrayOf(1),
|
||||
messageChainOf()
|
||||
)
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
private val testConstrainSingleMessageInstances: Array<out ConstrainSingle> = arrayOf(
|
||||
LongMessage("content", "resId")
|
||||
LongMessage("content", "resId"),
|
||||
Mirai.constructMessageSource(
|
||||
1L,
|
||||
MessageSourceKind.FRIEND,
|
||||
1,
|
||||
2,
|
||||
intArrayOf(1),
|
||||
1,
|
||||
intArrayOf(1),
|
||||
messageChainOf(emptySource, image)
|
||||
),
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
Loading…
Reference in New Issue
Block a user