Multiple MessageSource.id and MessageSource.internalId for split sources now, and split messages in the future. Close #618

This commit is contained in:
Him188 2020-12-02 10:46:06 +08:00
parent 8fdfe830fe
commit 64bd63d7a0
19 changed files with 370 additions and 256 deletions

View File

@ -107,8 +107,8 @@ public interface IMirai : LowLevelApiAccessor {
/** /**
* 构造一个 [OfflineMessageSource] * 构造一个 [OfflineMessageSource]
* *
* @param id [MessageSource.id] * @param ids [MessageSource.ids]
* @param internalId [MessageSource.internalId] * @param internalIds [MessageSource.internalIds]
* *
* @param fromUin 为用户时为 [Friend.id], 为群时需使用 [Group.calculateGroupUinByGroupCode] 计算 * @param fromUin 为用户时为 [Friend.id], 为群时需使用 [Group.calculateGroupUinByGroupCode] 计算
* @param targetUin 为用户时为 [Friend.id], 为群时需使用 [Group.calculateGroupUinByGroupCode] 计算 * @param targetUin 为用户时为 [Friend.id], 为群时需使用 [Group.calculateGroupUinByGroupCode] 计算
@ -118,7 +118,7 @@ public interface IMirai : LowLevelApiAccessor {
bot: Bot, bot: Bot,
kind: OfflineMessageSource.Kind, kind: OfflineMessageSource.Kind,
fromUin: Long, targetUin: Long, fromUin: Long, targetUin: Long,
id: Int, time: Int, internalId: Int, ids: IntArray, time: Int, internalIds: IntArray,
originalMessage: MessageChain originalMessage: MessageChain
): OfflineMessageSource ): OfflineMessageSource

View File

@ -259,16 +259,16 @@ public sealed class MessageRecallEvent : BotEvent, AbstractEvent() {
public abstract val authorId: Long public abstract val authorId: Long
/** /**
* 消息 id. * 消息 ids.
* @see MessageSource.id * @see MessageSource.ids
*/ */
public abstract val messageId: Int public abstract val messageIds: IntArray
/** /**
* 消息内部 id. * 消息内部 ids.
* @see MessageSource.id * @see MessageSource.ids
*/ */
public abstract val messageInternalId: Int public abstract val messageInternalIds: IntArray
/** /**
* 原发送时间 * 原发送时间
@ -280,8 +280,8 @@ public sealed class MessageRecallEvent : BotEvent, AbstractEvent() {
*/ */
public data class FriendRecall internal constructor( public data class FriendRecall internal constructor(
public override val bot: Bot, public override val bot: Bot,
public override val messageId: Int, public override val messageIds: IntArray,
public override val messageInternalId: Int, public override val messageInternalIds: IntArray,
public override val messageTime: Int, public override val messageTime: Int,
/** /**
* 撤回操作人, 好友的 [User.id] * 撤回操作人, 好友的 [User.id]
@ -290,6 +290,30 @@ public sealed class MessageRecallEvent : BotEvent, AbstractEvent() {
) : MessageRecallEvent(), Packet { ) : MessageRecallEvent(), Packet {
public override val authorId: Long public override val authorId: Long
get() = bot.id get() = bot.id
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as FriendRecall
if (bot != other.bot) return false
if (!messageIds.contentEquals(other.messageIds)) return false
if (!messageInternalIds.contentEquals(other.messageInternalIds)) return false
if (messageTime != other.messageTime) return false
if (operator != other.operator) return false
return true
}
override fun hashCode(): Int {
var result = bot.hashCode()
result = 31 * result + messageIds.contentHashCode()
result = 31 * result + messageInternalIds.contentHashCode()
result = 31 * result + messageTime
result = 31 * result + operator.hashCode()
return result
}
} }
/** /**
@ -298,15 +322,43 @@ public sealed class MessageRecallEvent : BotEvent, AbstractEvent() {
public data class GroupRecall @PublishedApi internal constructor( public data class GroupRecall @PublishedApi internal constructor(
public override val bot: Bot, public override val bot: Bot,
public override val authorId: Long, public override val authorId: Long,
public override val messageId: Int, public override val messageIds: IntArray,
public override val messageInternalId: Int, public override val messageInternalIds: IntArray,
public override val messageTime: Int, public override val messageTime: Int,
/** /**
* 操作人. null 时则为 [Bot] 操作. * 操作人. null 时则为 [Bot] 操作.
*/ */
public override val operator: Member?, public override val operator: Member?,
public override val group: Group public override val group: Group
) : MessageRecallEvent(), GroupOperableEvent, Packet ) : MessageRecallEvent(), GroupOperableEvent, Packet {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as GroupRecall
if (bot != other.bot) return false
if (authorId != other.authorId) return false
if (!messageIds.contentEquals(other.messageIds)) return false
if (!messageInternalIds.contentEquals(other.messageInternalIds)) return false
if (messageTime != other.messageTime) return false
if (operator != other.operator) return false
if (group != other.group) return false
return true
}
override fun hashCode(): Int {
var result = bot.hashCode()
result = 31 * result + authorId.hashCode()
result = 31 * result + messageIds.contentHashCode()
result = 31 * result + messageInternalIds.contentHashCode()
result = 31 * result + messageTime
result = 31 * result + (operator?.hashCode() ?: 0)
result = 31 * result + group.hashCode()
return result
}
}
} }
public val MessageRecallEvent.GroupRecall.author: Member public val MessageRecallEvent.GroupRecall.author: Member

View File

@ -78,7 +78,7 @@ public abstract class MessageEvent : ContactMessage(),
/** /**
* 消息内容. * 消息内容.
* *
* 第一个元素一定为 [MessageSource], 存储此消息的发送人, 发送时间, 收信人, 消息 id 等数据. * 第一个元素一定为 [MessageSource], 存储此消息的发送人, 发送时间, 收信人, 消息 ids 等数据.
* 随后的元素为拥有顺序的真实消息内容. * 随后的元素为拥有顺序的真实消息内容.
*/ */
public abstract override val message: MessageChain public abstract override val message: MessageChain

View File

@ -16,7 +16,6 @@ import net.mamoe.mirai.Mirai
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.*
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.MiraiExperimentalApi import net.mamoe.mirai.utils.MiraiExperimentalApi
import kotlin.jvm.JvmSynthetic
/** /**
* 发送消息后得到的回执. 可用于撤回, 引用回复等. * 发送消息后得到的回执. 可用于撤回, 引用回复等.
@ -32,7 +31,7 @@ import kotlin.jvm.JvmSynthetic
* @see User.sendMessage 发送群消息, 返回回执此对象 * @see User.sendMessage 发送群消息, 返回回执此对象
* @see Member.sendMessage 发送临时消息, 返回回执此对象 * @see Member.sendMessage 发送临时消息, 返回回执此对象
* *
* @see MessageReceipt.sourceId id * @see MessageReceipt.sourceIds ids
* @see MessageReceipt.sourceTime 源时间 * @see MessageReceipt.sourceTime 源时间
*/ */
public open class MessageReceipt<out C : Contact> @MiraiExperimentalApi("The constructor is subject to change.") constructor( public open class MessageReceipt<out C : Contact> @MiraiExperimentalApi("The constructor is subject to change.") constructor(
@ -95,23 +94,23 @@ public suspend inline fun <C : Contact> MessageReceipt<C>.quoteReply(message: St
/** /**
* 获取源消息 [MessageSource.id] * 获取源消息 [MessageSource.ids]
* *
* @see MessageSource.id * @see MessageSource.ids
*/ */
@get:JvmSynthetic @get:JvmSynthetic
public inline val MessageReceipt<*>.sourceId: Int public inline val MessageReceipt<*>.sourceIds: IntArray
get() = this.source.id get() = this.source.ids
/** /**
* 获取源消息 [MessageSource.internalId] * 获取源消息 [MessageSource.internalIds]
* *
* @see MessageSource.id * @see MessageSource.ids
*/ */
@get:JvmSynthetic @get:JvmSynthetic
public inline val MessageReceipt<*>.sourceInternalId: Int public inline val MessageReceipt<*>.sourceInternalIds: IntArray
get() = this.source.internalId get() = this.source.internalIds
/** /**
* 获取源消息 [MessageSource.time] * 获取源消息 [MessageSource.time]

View File

@ -22,9 +22,6 @@ import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.quote import net.mamoe.mirai.message.quote
import net.mamoe.mirai.message.recall import net.mamoe.mirai.message.recall
import net.mamoe.mirai.utils.LazyProperty import net.mamoe.mirai.utils.LazyProperty
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**
* 消息源. 消息源存在于 [MessageChain] , 用于表示这个消息的来源, 也可以用来分辨 [MessageChain]. * 消息源. 消息源存在于 [MessageChain] , 用于表示这个消息的来源, 也可以用来分辨 [MessageChain].
@ -36,8 +33,8 @@ import kotlin.jvm.JvmSynthetic
* [MessageSource] metadata (元数据), form & target, content 组成 * [MessageSource] metadata (元数据), form & target, content 组成
* *
* #### metadata * #### metadata
* - [id] 消息 id (序列号) * - [ids] 消息 ids (序列号)
* - [internalId] 消息内部 id * - [internalIds] 消息内部 ids
* - [time] 时间 * - [time] 时间
* *
* 官方客户端通过 metadata 这三个数据定位消息, 撤回和引用回复都是如此. * 官方客户端通过 metadata 这三个数据定位消息, 撤回和引用回复都是如此.
@ -51,9 +48,9 @@ import kotlin.jvm.JvmSynthetic
* *
* ### 使用 * ### 使用
* *
* 消息源可用于 [引用回复][QuoteReply] [撤回][Bot.recall]. * 消息源可用于 [引用回复][QuoteReply] [撤回][IMirai.recall].
* *
* @see Bot.recall 撤回一条消息 * @see IMirai.recall 撤回一条消息
* @see MessageSource.quote 引用这条消息, 创建 [MessageChain] * @see MessageSource.quote 引用这条消息, 创建 [MessageChain]
* *
* @see OnlineMessageSource 在线消息的 [MessageSource] * @see OnlineMessageSource 在线消息的 [MessageSource]
@ -74,28 +71,28 @@ public sealed class MessageSource : Message, MessageMetadata, ConstrainSingle<Me
public abstract val bot: Bot public abstract val bot: Bot
/** /**
* 消息 id (序列号). 在获取失败时 (概率很低) `-1`. * 消息 ids (序列号). 在获取失败时 (概率很低) `-1`.
** **
* #### 值域 * #### 值域
* 值的范围约为 [UShort] 的范围. * 值的范围约为 [UShort] 的范围.
* *
* #### 顺序 * #### 顺序
* 群消息的 id 由服务器维护. 好友消息的 id mirai 维护. * 群消息的 ids 由服务器维护. 好友消息的 ids mirai 维护.
* id 不一定从 0 开始. * ids 不一定从 0 开始.
* *
* - 在同一个群的消息中此值随每条消息递增 1, 但此行为由服务器决定, mirai 不保证自增顺序. * - 在同一个群的消息中此值随每条消息递增 1, 但此行为由服务器决定, mirai 不保证自增顺序.
* - 在好友消息中无法保证每次都递增 1. 也可能会产生大幅跳过的情况. * - 在好友消息中无法保证每次都递增 1. 也可能会产生大幅跳过的情况.
*/ */
public abstract val id: Int public abstract val ids: IntArray
/** /**
* 内部 id. **仅用于协议模块使用** * 内部 ids. **仅用于协议模块使用**
* *
* 值没有顺序, 也可能为 0, 取决于服务器是否提供. * 值没有顺序, 也可能为 0, 取决于服务器是否提供.
* *
* 在事件中和在引用中无法保证同一条消息的 [internalId] 相同. * 在事件中和在引用中无法保证同一条消息的 [internalIds] 相同.
*/ */
public abstract val internalId: Int public abstract val internalIds: IntArray
/** /**
* 发送时间时间戳, 单位为秒. * 发送时间时间戳, 单位为秒.
@ -131,9 +128,9 @@ public sealed class MessageSource : Message, MessageMetadata, ConstrainSingle<Me
public abstract val originalMessage: MessageChain public abstract val originalMessage: MessageChain
/** /**
* 返回 `"[mirai:source:$id,$internalId]"` * 返回 `"[mirai:source:$ids,$internalIds]"`
*/ */
public final override fun toString(): String = "[mirai:source:$id,$internalId]" public final override fun toString(): String = "[mirai:source:$ids,$internalIds]"
} }
@ -206,7 +203,7 @@ public sealed class OnlineMessageSource : MessageSource() {
public abstract override val target: Friend public abstract override val target: Friend
public final override val subject: Friend get() = target public final override val subject: Friend get() = target
// final override fun toString(): String = "OnlineMessageSource.ToFriend(target=${target.id})" // final override fun toString(): String = "OnlineMessageSource.ToFriend(target=${target.ids})"
} }
public abstract class ToTemp : Outgoing() { public abstract class ToTemp : Outgoing() {
@ -250,7 +247,7 @@ public sealed class OnlineMessageSource : MessageSource() {
public abstract override val sender: Friend public abstract override val sender: Friend
public final override val subject: Friend get() = sender public final override val subject: Friend get() = sender
public final override val target: Bot get() = sender.bot public final override val target: Bot get() = sender.bot
// final override fun toString(): String = "OnlineMessageSource.FromFriend(from=${sender.id})" // final override fun toString(): String = "OnlineMessageSource.FromFriend(from=${sender.ids})"
} }
public abstract class FromTemp : Incoming() { public abstract class FromTemp : Incoming() {
@ -367,44 +364,44 @@ public suspend inline fun MessageSource.recall(): Unit = Mirai.recall(bot, this)
// For MessageChain // For MessageChain
/** /**
* 消息 id. * 消息 ids.
* *
* 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取消息源. * 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取消息源.
* *
* @see MessageSource.id * @see MessageSource.ids
*/ */
@get:JvmSynthetic @get:JvmSynthetic
public val MessageChain.id: Int public val MessageChain.ids: IntArray
get() = this.source.id get() = this.source.ids
/** /**
* 消息内部 id. * 消息内部 ids.
* *
* 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取消息源. * 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取消息源.
* *
* @see MessageSource.id * @see MessageSource.ids
*/ */
@get:JvmSynthetic @get:JvmSynthetic
public val MessageChain.internalId: Int public val MessageChain.internalId: IntArray
get() = this.source.internalId get() = this.source.internalIds
/** /**
* 消息时间. * 消息时间.
* *
* 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取消息源. * 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取消息源.
* *
* @see MessageSource.id * @see MessageSource.ids
*/ */
@get:JvmSynthetic @get:JvmSynthetic
public val MessageChain.time: Int public val MessageChain.time: Int
get() = this.source.time get() = this.source.time
/** /**
* 消息内部 id. * 消息内部 ids.
* *
* 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取. 否则将抛出异常 [NoSuchElementException] * 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取. 否则将抛出异常 [NoSuchElementException]
* *
* @see MessageSource.id * @see MessageSource.ids
*/ */
@get:JvmSynthetic @get:JvmSynthetic
public val MessageChain.bot: Bot public val MessageChain.bot: Bot
@ -414,11 +411,24 @@ public val MessageChain.bot: Bot
* 获取这条消息的 [消息源][MessageSource]. * 获取这条消息的 [消息源][MessageSource].
* *
* 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取消息源, 否则将抛出异常 [NoSuchElementException] * 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取消息源, 否则将抛出异常 [NoSuchElementException]
*
* @see sourceOrNull
*/ */
@get:JvmSynthetic @get:JvmSynthetic
public val MessageChain.source: MessageSource public val MessageChain.source: MessageSource
get() = this.getOrFail(MessageSource) get() = this.getOrFail(MessageSource)
/**
* 获取这条消息的 [消息源][MessageSource].
*
* 仅从服务器接收的消息 (即来自 [MessageEvent.message]), 或手动添加了 [MessageSource] 元素的 [MessageChain] 才可以获取消息源, 否则返回 `null`
*
* @see source
*/
@get:JvmSynthetic
public val MessageChain.sourceOrNull: MessageSource?
get() = this[MessageSource]
/** /**
* 撤回这条消息. 可撤回自己 2 分钟内发出的消息, 和任意时间的群成员的消息. * 撤回这条消息. 可撤回自己 2 分钟内发出的消息, 和任意时间的群成员的消息.
* *

View File

@ -52,16 +52,16 @@ public interface MessageSourceAmender {
public var kind: OfflineMessageSource.Kind public var kind: OfflineMessageSource.Kind
public var fromUin: Long public var fromUin: Long
public var targetUin: Long public var targetUin: Long
public var id: Int public var ids: IntArray
public var time: Int public var time: Int
public var internalId: Int public var internalIds: IntArray
public var originalMessage: MessageChain public var originalMessage: MessageChain
/** 从另一个 [MessageSource] 中复制 [id], [internalId], [time]*/ /** 从另一个 [MessageSource] 中复制 [ids], [internalIds], [time]*/
public fun metadataFrom(another: MessageSource) { public fun metadataFrom(another: MessageSource) {
this.id = another.id this.ids = another.ids
this.internalId = another.internalId this.internalIds = another.internalIds
this.time = another.time this.time = another.time
} }
} }
@ -78,9 +78,9 @@ public interface MessageSourceAmender {
* ### 参数 * ### 参数
* 一个 [OfflineMessageSource] 须要以下参数: * 一个 [OfflineMessageSource] 须要以下参数:
* - 发送人和发送目标: 通过 [MessageSourceBuilder.sendTo] 设置 * - 发送人和发送目标: 通过 [MessageSourceBuilder.sendTo] 设置
* - 消息元数据 ( [MessageSource.id], [MessageSource.internalId], [MessageSource.time]) * - 消息元数据 ( [MessageSource.ids], [MessageSource.internalIds], [MessageSource.time])
* 元数据用于 [撤回][MessageSource.recall], [引用回复][MessageSource.quote], 和官方客户端定位原消息. * 元数据用于 [撤回][MessageSource.recall], [引用回复][MessageSource.quote], 和官方客户端定位原消息.
* 可通过 [MessageSourceBuilder.id], [MessageSourceBuilder.time], [MessageSourceBuilder.internalId] 设置 * 可通过 [MessageSourceBuilder.ids], [MessageSourceBuilder.time], [MessageSourceBuilder.internalIds] 设置
* 可通过 [MessageSourceBuilder.metadata] 从另一个 [MessageSource] 复制 * 可通过 [MessageSourceBuilder.metadata] 从另一个 [MessageSource] 复制
* - 消息内容: 通过 [MessageSourceBuilder.messages] 设置 * - 消息内容: 通过 [MessageSourceBuilder.messages] 设置
* *
@ -92,7 +92,7 @@ public interface MessageSourceAmender {
* ``` * ```
* bot.buildMessageSource { * bot.buildMessageSource {
* bot sendTo target // 指定发送人和发送目标 * bot sendTo target // 指定发送人和发送目标
* metadata(source) // 从另一个消息源复制 id, internalId, time * metadata(source) // 从另一个消息源复制 ids, internalIds, time
* *
* messages { // 指定消息内容 * messages { // 指定消息内容
* +"hi" * +"hi"
@ -109,9 +109,9 @@ public fun Bot.buildMessageSource(block: MessageSourceBuilder.() -> Unit): Messa
builder.kind ?: error("You must call `Contact.sendTo(Contact)` when `buildMessageSource`"), builder.kind ?: error("You must call `Contact.sendTo(Contact)` when `buildMessageSource`"),
builder.fromUin, builder.fromUin,
builder.targetUin, builder.targetUin,
builder.id, builder.ids,
builder.time, builder.time,
builder.internalId, builder.internalIds,
builder.originalMessages.build() builder.originalMessages.build()
) )
} }
@ -124,9 +124,9 @@ public abstract class MessageSourceBuilder {
internal abstract var fromUin: Long internal abstract var fromUin: Long
internal abstract var targetUin: Long internal abstract var targetUin: Long
internal abstract var id: Int internal abstract var ids: IntArray
internal abstract var time: Int internal abstract var time: Int
internal abstract var internalId: Int internal abstract var internalIds: IntArray
@PublishedApi @PublishedApi
internal val originalMessages: MessageChainBuilder = MessageChainBuilder() internal val originalMessages: MessageChainBuilder = MessageChainBuilder()
@ -135,15 +135,15 @@ public abstract class MessageSourceBuilder {
public val now: Int get() = currentTimeSeconds.toInt() public val now: Int get() = currentTimeSeconds.toInt()
public fun time(value: Int): MessageSourceBuilder = apply { this.time = value } public fun time(value: Int): MessageSourceBuilder = apply { this.time = value }
public fun internalId(from: MessageSource): MessageSourceBuilder = apply { this.internalId = from.internalId } public fun internalId(from: MessageSource): MessageSourceBuilder = apply { this.internalIds = from.internalIds }
public fun internalId(value: Int): MessageSourceBuilder = apply { this.internalId = value } public fun internalId(vararg value: Int): MessageSourceBuilder = apply { this.internalIds = value }
public fun id(from: MessageSource): MessageSourceBuilder = apply { this.id = from.id } public fun id(from: MessageSource): MessageSourceBuilder = apply { this.ids = from.ids }
public fun id(value: Int): MessageSourceBuilder = apply { this.id = value } public fun id(vararg value: Int): MessageSourceBuilder = apply { this.ids = value }
/** /**
* 从另一个 [MessageSource] 复制 [id], [time], [internalId]. * 从另一个 [MessageSource] 复制 [ids], [time], [internalIds].
* 这三个数据决定官方客户端能 "定位" 到的原消息 * 这三个数据决定官方客户端能 "定位" 到的原消息
*/ */
public fun metadata(from: MessageSource): MessageSourceBuilder = apply { public fun metadata(from: MessageSource): MessageSourceBuilder = apply {
@ -157,11 +157,11 @@ public abstract class MessageSourceBuilder {
*/ */
public fun allFrom(source: MessageSource): MessageSourceBuilder { public fun allFrom(source: MessageSource): MessageSourceBuilder {
this.kind = determineKind(source) this.kind = determineKind(source)
this.id = source.id this.ids = source.ids
this.time = source.time this.time = source.time
this.fromUin = source.fromId this.fromUin = source.fromId
this.targetUin = source.targetId this.targetUin = source.targetId
this.internalId = source.internalId this.internalIds = source.internalIds
this.originalMessages.addAll(source.originalMessage) this.originalMessages.addAll(source.originalMessage)
return this return this
} }
@ -212,9 +212,9 @@ internal class MessageSourceBuilderImpl : MessageSourceBuilder() {
override var fromUin: Long = 0 override var fromUin: Long = 0
override var targetUin: Long = 0 override var targetUin: Long = 0
override var id: Int = 0 override var ids: IntArray = intArrayOf()
override var time: Int = currentTimeSeconds.toInt() override var time: Int = currentTimeSeconds.toInt()
override var internalId: Int = 0 override var internalIds: IntArray = intArrayOf()
@JvmSynthetic @JvmSynthetic
override fun ContactOrBot.sendTo(target: ContactOrBot): MessageSourceBuilder { override fun ContactOrBot.sendTo(target: ContactOrBot): MessageSourceBuilder {
@ -259,8 +259,8 @@ internal class MutableOfflineMessageSourceByOnline(
targetId = value targetId = value
} }
override var bot: Bot = origin.bot override var bot: Bot = origin.bot
override var id: Int = origin.id override var ids: IntArray = origin.ids
override var internalId: Int = origin.internalId override var internalIds: IntArray = origin.internalIds
override var time: Int = origin.time override var time: Int = origin.time
override var fromId: Long = origin.fromId override var fromId: Long = origin.fromId
override var targetId: Long = origin.targetId override var targetId: Long = origin.targetId
@ -287,8 +287,8 @@ internal class OfflineMessageSourceByOnline(
else -> error("stub") else -> error("stub")
} }
override val bot: Bot get() = onlineMessageSource.bot override val bot: Bot get() = onlineMessageSource.bot
override val id: Int get() = onlineMessageSource.id override val ids: IntArray get() = onlineMessageSource.ids
override val internalId: Int get() = onlineMessageSource.internalId override val internalIds: IntArray get() = onlineMessageSource.internalIds
override val time: Int get() = onlineMessageSource.time override val time: Int get() = onlineMessageSource.time
override val fromId: Long get() = onlineMessageSource.fromId override val fromId: Long get() = onlineMessageSource.fromId
override val targetId: Long get() = onlineMessageSource.targetId override val targetId: Long get() = onlineMessageSource.targetId

View File

@ -14,9 +14,6 @@
package net.mamoe.mirai.message.data package net.mamoe.mirai.message.data
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**
@ -35,7 +32,7 @@ import kotlin.jvm.JvmSynthetic
* 引用回复的原消息内容完全由 [source] [MessageSource.originalMessage] 控制, 客户端不会自行寻找原消息. * 引用回复的原消息内容完全由 [source] [MessageSource.originalMessage] 控制, 客户端不会自行寻找原消息.
* *
* #### 客户端内跳转 * #### 客户端内跳转
* 客户端在跳转原消息时, 会通过 [MessageSource.id] metadata * 客户端在跳转原消息时, 会通过 [MessageSource.ids] metadata
* *
* @see MessageSource 获取有关消息源的更多信息 * @see MessageSource 获取有关消息源的更多信息
*/ */
@ -47,7 +44,8 @@ public class QuoteReply(public val source: MessageSource) : Message, MessageMeta
public override val key: Message.Key<QuoteReply> get() = Key public override val key: Message.Key<QuoteReply> get() = Key
public override fun toString(): String = "[mirai:quote:${source.id},${source.internalId}]" // TODO: 2020/12/2 QuoteReply.toString
public override fun toString(): String = "[mirai:quote:${source.ids},${source.internalIds}]"
public override fun equals(other: Any?): Boolean = other is QuoteReply && other.source == this.source public override fun equals(other: Any?): Boolean = other is QuoteReply && other.source == this.source
public override fun hashCode(): Int = source.hashCode() public override fun hashCode(): Int = source.hashCode()
} }

View File

@ -7,7 +7,31 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:JvmMultifileClass
@file:JvmName("MiraiUtils") @file:JvmName("MiraiUtils")
package net.mamoe.mirai.utils package net.mamoe.mirai.utils
public inline fun <A, reified B> Array<A>.mapToArray(block: (element: A) -> B): Array<B> {
val result = arrayOfNulls<B>(size)
this.forEachIndexed { index, element ->
result[index] = block(element)
}
return result.cast()
}
public inline fun <A, reified B> Collection<A>.mapToArray(block: (element: A) -> B): Array<B> {
val result = arrayOfNulls<B>(size)
this.forEachIndexed { index, element ->
result[index] = block(element)
}
return result.cast()
}
public inline fun <A> Collection<A>.mapToIntArray(block: (element: A) -> Int): IntArray {
val result = IntArray(size)
this.forEachIndexed { index, element ->
result[index] = block(element)
}
return result.cast()
}

View File

@ -0,0 +1,15 @@
/*
* Copyright 2020 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
*/
@file:JvmMultifileClass
@file:JvmName("MiraiUtils")
package net.mamoe.mirai.utils
public fun Int.toLongUnsigned(): Long = this.toLong().and(0xFFFF_FFFF)

View File

@ -7,12 +7,13 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:JvmMultifileClass
@file:JvmName("MiraiUtils") @file:JvmName("MiraiUtils")
package net.mamoe.mirai.utils package net.mamoe.mirai.utils
inline fun <reified T> Any?.cast(): T = this as T public inline fun <reified T> Any?.cast(): T = this as T
inline fun <reified T> Any?.safeCast(): T? = this as? T public inline fun <reified T> Any?.safeCast(): T? = this as? T
inline fun <reified T> Any?.castOrNull(): T? = this as? T public inline fun <reified T> Any?.castOrNull(): T? = this as? T

View File

@ -280,8 +280,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
MessageRecallEvent.GroupRecall( MessageRecallEvent.GroupRecall(
bot, bot,
source.fromId, source.fromId,
source.id, source.ids,
source.internalId, source.internalIds,
source.time, source.time,
null, null,
group group
@ -291,8 +291,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
PbMessageSvc.PbMsgWithDraw.createForGroupMessage( PbMessageSvc.PbMsgWithDraw.createForGroupMessage(
bot.asQQAndroidBot().client, bot.asQQAndroidBot().client,
group.id, group.id,
source.sequenceId, source.sequenceIds,
source.internalId source.internalIds
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>() ).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
} }
} }
@ -305,8 +305,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
PbMessageSvc.PbMsgWithDraw.createForFriendMessage( PbMessageSvc.PbMsgWithDraw.createForFriendMessage(
bot.client, bot.client,
source.targetId, source.targetId,
source.sequenceId, source.sequenceIds,
source.internalId, source.internalIds,
source.time source.time
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>() ).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
} }
@ -321,8 +321,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
bot.client, bot.client,
(source.target.group as GroupImpl).uin, (source.target.group as GroupImpl).uin,
source.targetId, source.targetId,
source.sequenceId, source.sequenceIds,
source.internalId, source.internalIds,
source.time source.time
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>() ).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
} }
@ -335,8 +335,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
PbMessageSvc.PbMsgWithDraw.createForFriendMessage( PbMessageSvc.PbMsgWithDraw.createForFriendMessage(
bot.client, bot.client,
source.targetId, source.targetId,
source.sequenceId, source.sequenceIds,
source.internalId, source.internalIds,
source.time source.time
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>() ).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
} }
@ -348,8 +348,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
bot.client, bot.client,
source.targetId, // groupUin source.targetId, // groupUin
source.targetId, // memberUin source.targetId, // memberUin
source.sequenceId, source.sequenceIds,
source.internalId, source.internalIds,
source.time source.time
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>() ).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
} }
@ -357,8 +357,8 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
PbMessageSvc.PbMsgWithDraw.createForGroupMessage( PbMessageSvc.PbMsgWithDraw.createForGroupMessage(
bot.client, bot.client,
source.targetId, source.targetId,
source.sequenceId, source.sequenceIds,
source.internalId source.internalIds
).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>() ).sendAndExpect<PbMessageSvc.PbMsgWithDraw.Response>()
} }
} }
@ -370,7 +370,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
// 1001: No message meets the requirements (实际上是没权限, 管理员在尝试撤回群主的消息) // 1001: No message meets the requirements (实际上是没权限, 管理员在尝试撤回群主的消息)
// 154: timeout // 154: timeout
// 3: <no message> // 3: <no message>
check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.id}: $response" } check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.ids}: $response" }
} }
@LowLevelApi @LowLevelApi
@ -813,28 +813,28 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
kind: OfflineMessageSource.Kind, kind: OfflineMessageSource.Kind,
fromUin: Long, fromUin: Long,
targetUin: Long, targetUin: Long,
id: Int, ids: IntArray,
time: Int, time: Int,
internalId: Int, internalIds: IntArray,
originalMessage: MessageChain originalMessage: MessageChain
): OfflineMessageSource { ): OfflineMessageSource {
return object : OfflineMessageSource(), MessageSourceInternal { return object : OfflineMessageSource(), MessageSourceInternal {
override val kind: Kind get() = kind override val kind: Kind get() = kind
override val id: Int get() = id override val ids: IntArray get() = ids
override val bot: Bot get() = bot override val bot: Bot get() = bot
override val time: Int get() = time override val time: Int get() = time
override val fromId: Long get() = fromUin override val fromId: Long get() = fromUin
override val targetId: Long get() = targetUin override val targetId: Long get() = targetUin
override val originalMessage: MessageChain get() = originalMessage override val originalMessage: MessageChain get() = originalMessage
override val sequenceId: Int = id override val sequenceIds: IntArray = ids
override val internalId: Int = internalId override val internalIds: IntArray = internalIds
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") @Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false) override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
override fun toJceData(): ImMsgBody.SourceMsg { override fun toJceData(): ImMsgBody.SourceMsg {
return ImMsgBody.SourceMsg( return ImMsgBody.SourceMsg(
origSeqs = listOf(sequenceId), origSeqs = sequenceIds,
senderUin = fromUin, senderUin = fromUin,
toUin = 0, toUin = 0,
flag = 1, flag = 1,

View File

@ -29,11 +29,11 @@ import net.mamoe.mirai.message.data.OnlineMessageSource
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
internal interface MessageSourceInternal { internal interface MessageSourceInternal {
val sequenceId: Int val sequenceIds: IntArray
val internalId: Int // randomId val internalIds: IntArray // randomId
@Deprecated("don't use this internally. Use sequenceId or random instead.", level = DeprecationLevel.ERROR) @Deprecated("don't use this internally. Use sequenceId or random instead.", level = DeprecationLevel.ERROR)
val id: Int val ids: IntArray
val isRecalledOrPlanned: AtomicBoolean val isRecalledOrPlanned: AtomicBoolean
@ -66,25 +66,25 @@ internal class MessageSourceFromFriendImpl(
override val bot: Bot, override val bot: Bot,
val msg: MsgComm.Msg val msg: MsgComm.Msg
) : OnlineMessageSource.Incoming.FromFriend(), MessageSourceInternal { ) : OnlineMessageSource.Incoming.FromFriend(), MessageSourceInternal {
override val sequenceId: Int get() = msg.msgHead.msgSeq override val sequenceIds: IntArray get() = intArrayOf(msg.msgHead.msgSeq)
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false) override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
override val id: Int get() = sequenceId// msg.msgBody.richText.attr!!.random override val ids: IntArray get() = sequenceIds// msg.msgBody.richText.attr!!.random
override val internalId: Int get() = msg.msgBody.richText.attr!!.random override val internalIds: IntArray get() = intArrayOf(msg.msgBody.richText.attr!!.random)
override val time: Int get() = msg.msgHead.msgTime override val time: Int get() = msg.msgHead.msgTime
override val originalMessage: MessageChain by lazy { msg.toMessageChain(bot, 0, false) } override val originalMessage: MessageChain by lazy { msg.toMessageChain(bot, 0, false) }
override val sender: Friend get() = bot.getFriend(msg.msgHead.fromUin) override val sender: Friend get() = bot.getFriend(msg.msgHead.fromUin)
private val jceData by lazy { msg.toJceDataFriendOrTemp(internalId) } private val jceData by lazy { msg.toJceDataFriendOrTemp(internalIds) }
override fun toJceData(): ImMsgBody.SourceMsg = jceData override fun toJceData(): ImMsgBody.SourceMsg = jceData
} }
private fun MsgComm.Msg.toJceDataFriendOrTemp(id: Int): ImMsgBody.SourceMsg { private fun MsgComm.Msg.toJceDataFriendOrTemp(ids: IntArray): ImMsgBody.SourceMsg {
val elements = msgBody.richText.elems.toMutableList().also { val elements = msgBody.richText.elems.toMutableList().also {
if (it.last().elemFlags2 == null) it.add(ImMsgBody.Elem(elemFlags2 = ImMsgBody.ElemFlags2())) if (it.last().elemFlags2 == null) it.add(ImMsgBody.Elem(elemFlags2 = ImMsgBody.ElemFlags2()))
} }
return ImMsgBody.SourceMsg( return ImMsgBody.SourceMsg(
origSeqs = listOf(this.msgHead.msgSeq), origSeqs = intArrayOf(this.msgHead.msgSeq),
senderUin = this.msgHead.fromUin, senderUin = this.msgHead.fromUin,
toUin = this.msgHead.toUin, toUin = this.msgHead.toUin,
flag = 1, flag = 1,
@ -92,7 +92,7 @@ private fun MsgComm.Msg.toJceDataFriendOrTemp(id: Int): ImMsgBody.SourceMsg {
type = 0, type = 0,
time = this.msgHead.msgTime, time = this.msgHead.msgTime,
pbReserve = SourceMsg.ResvAttr( pbReserve = SourceMsg.ResvAttr(
origUids = id.toLong() and 0xFFFF_FFFF origUids = ids.map { it.toLong() and 0xFFFF_FFFF }
).toByteArray(SourceMsg.ResvAttr.serializer()), ).toByteArray(SourceMsg.ResvAttr.serializer()),
srcMsg = MsgComm.Msg( srcMsg = MsgComm.Msg(
msgHead = MsgComm.MsgHead( msgHead = MsgComm.MsgHead(
@ -102,7 +102,7 @@ private fun MsgComm.Msg.toJceDataFriendOrTemp(id: Int): ImMsgBody.SourceMsg {
c2cCmd = this.msgHead.c2cCmd, c2cCmd = this.msgHead.c2cCmd,
msgSeq = this.msgHead.msgSeq, msgSeq = this.msgHead.msgSeq,
msgTime = this.msgHead.msgTime, msgTime = this.msgHead.msgTime,
msgUid = id.toLong() and 0xFFFF_FFFF, // ok msgUid = ids.single().toLong() and 0xFFFF_FFFF, // ok
// groupInfo = MsgComm.GroupInfo(groupCode = this.msgHead.groupInfo.groupCode), // groupInfo = MsgComm.GroupInfo(groupCode = this.msgHead.groupInfo.groupCode),
isSrcMsg = true isSrcMsg = true
), ),
@ -119,15 +119,15 @@ internal class MessageSourceFromTempImpl(
override val bot: Bot, override val bot: Bot,
private val msg: MsgComm.Msg private val msg: MsgComm.Msg
) : OnlineMessageSource.Incoming.FromTemp(), MessageSourceInternal { ) : OnlineMessageSource.Incoming.FromTemp(), MessageSourceInternal {
override val sequenceId: Int get() = msg.msgHead.msgSeq override val sequenceIds: IntArray get() = intArrayOf(msg.msgHead.msgSeq)
override val internalId: Int get() = msg.msgBody.richText.attr!!.random override val internalIds: IntArray get() = intArrayOf(msg.msgBody.richText.attr!!.random)
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false) override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
override val id: Int get() = sequenceId// override val ids: IntArray get() = sequenceIds//
override val time: Int get() = msg.msgHead.msgTime override val time: Int get() = msg.msgHead.msgTime
override val originalMessage: MessageChain by lazy { msg.toMessageChain(bot, 0, false) } override val originalMessage: MessageChain by lazy { msg.toMessageChain(bot, 0, false) }
override val sender: Member get() = with(msg.msgHead) { bot.getGroup(c2cTmpMsgHead!!.groupUin)[fromUin] } override val sender: Member get() = with(msg.msgHead) { bot.getGroup(c2cTmpMsgHead!!.groupUin)[fromUin] }
private val jceData by lazy { msg.toJceDataFriendOrTemp(internalId) } private val jceData by lazy { msg.toJceDataFriendOrTemp(internalIds) }
override fun toJceData(): ImMsgBody.SourceMsg = jceData override fun toJceData(): ImMsgBody.SourceMsg = jceData
} }
@ -136,9 +136,9 @@ internal data class MessageSourceFromGroupImpl(
private val msg: MsgComm.Msg private val msg: MsgComm.Msg
) : OnlineMessageSource.Incoming.FromGroup(), MessageSourceInternal { ) : OnlineMessageSource.Incoming.FromGroup(), MessageSourceInternal {
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false) override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
override val sequenceId: Int get() = msg.msgHead.msgSeq override val sequenceIds: IntArray get() = intArrayOf(msg.msgHead.msgSeq)
override val internalId: Int get() = msg.msgBody.richText.attr!!.random override val internalIds: IntArray get() = intArrayOf(msg.msgBody.richText.attr!!.random)
override val id: Int get() = sequenceId override val ids: IntArray get() = sequenceIds
override val time: Int get() = msg.msgHead.msgTime override val time: Int get() = msg.msgHead.msgTime
override val originalMessage: MessageChain by lazy { override val originalMessage: MessageChain by lazy {
msg.toMessageChain(bot, groupIdOrZero = group.id, onlineSource = false) msg.toMessageChain(bot, groupIdOrZero = group.id, onlineSource = false)
@ -159,7 +159,7 @@ internal data class MessageSourceFromGroupImpl(
override fun toJceData(): ImMsgBody.SourceMsg { override fun toJceData(): ImMsgBody.SourceMsg {
return ImMsgBody.SourceMsg( return ImMsgBody.SourceMsg(
origSeqs = listOf(msg.msgHead.msgSeq), origSeqs = intArrayOf(msg.msgHead.msgSeq),
senderUin = msg.msgHead.fromUin, senderUin = msg.msgHead.fromUin,
toUin = 0, toUin = 0,
flag = 1, flag = 1,

View File

@ -19,6 +19,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.EMPTY_BYTE_ARRAY
import net.mamoe.mirai.internal.utils.io.serialization.loadAs import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.OfflineMessageSource import net.mamoe.mirai.message.data.OfflineMessageSource
import net.mamoe.mirai.utils.mapToIntArray
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
@ -28,9 +29,8 @@ internal class OfflineMessageSourceImplByMsg(
override val bot: Bot override val bot: Bot
) : OfflineMessageSource(), MessageSourceInternal { ) : OfflineMessageSource(), MessageSourceInternal {
override val kind: Kind = if (delegate.msgHead.groupInfo != null) Kind.GROUP else Kind.FRIEND override val kind: Kind = if (delegate.msgHead.groupInfo != null) Kind.GROUP else Kind.FRIEND
override val id: Int get() = sequenceId override val ids: IntArray get() = sequenceIds
override val internalId: Int override val internalIds: IntArray = intArrayOf(delegate.msgHead.msgUid.toInt())
get() = delegate.msgHead.msgUid.toInt()
override val time: Int override val time: Int
get() = delegate.msgHead.msgTime get() = delegate.msgHead.msgTime
override val fromId: Long override val fromId: Long
@ -38,20 +38,20 @@ internal class OfflineMessageSourceImplByMsg(
override val targetId: Long override val targetId: Long
get() = delegate.msgHead.groupInfo?.groupCode ?: delegate.msgHead.toUin get() = delegate.msgHead.groupInfo?.groupCode ?: delegate.msgHead.toUin
override val originalMessage: MessageChain by lazy { override val originalMessage: MessageChain by lazy {
delegate.toMessageChain(bot, delegate.toMessageChain(
bot,
groupIdOrZero = delegate.msgHead.groupInfo?.groupCode ?: 0, groupIdOrZero = delegate.msgHead.groupInfo?.groupCode ?: 0,
onlineSource = false, onlineSource = false,
isTemp = delegate.msgHead.c2cTmpMsgHead != null isTemp = delegate.msgHead.c2cTmpMsgHead != null
) )
} }
override val sequenceId: Int override val sequenceIds: IntArray = intArrayOf(delegate.msgHead.msgSeq)
get() = delegate.msgHead.msgSeq
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false) override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
override fun toJceData(): ImMsgBody.SourceMsg { override fun toJceData(): ImMsgBody.SourceMsg {
return ImMsgBody.SourceMsg( return ImMsgBody.SourceMsg(
origSeqs = listOf(delegate.msgHead.msgSeq), origSeqs = intArrayOf(delegate.msgHead.msgSeq),
senderUin = delegate.msgHead.fromUin, senderUin = delegate.msgHead.fromUin,
toUin = 0, toUin = 0,
flag = 1, flag = 1,
@ -73,20 +73,19 @@ internal class OfflineMessageSourceImplBySourceMsg(
override val kind: Kind get() = if (delegate.srcMsg == null) Kind.GROUP else Kind.FRIEND override val kind: Kind get() = if (delegate.srcMsg == null) Kind.GROUP else Kind.FRIEND
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false) override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
override val sequenceId: Int override val sequenceIds: IntArray = delegate.origSeqs
get() = delegate.origSeqs.firstOrNull() ?: error("cannot find sequenceId") override val internalIds: IntArray = delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer())
override val internalId: Int .origUids?.mapToIntArray { it.toInt() } ?: intArrayOf()
get() = delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids?.toInt() ?: 0
override val time: Int get() = delegate.time override val time: Int get() = delegate.time
override val originalMessage: MessageChain by lazy { delegate.toMessageChain(bot, groupIdOrZero) } override val originalMessage: MessageChain by lazy { delegate.toMessageChain(bot, groupIdOrZero) }
/* /*
override val id: Long override val ids: Long
get() = (delegate.origSeqs?.firstOrNull() get() = (delegate.origSeqs?.firstOrNull()
?: error("cannot find sequenceId from ImMsgBody.SourceMsg")).toLong().shl(32) or ?: error("cannot find sequenceId from ImMsgBody.SourceMsg")).toLong().shl(32) or
delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids!!.and(0xFFFFFFFF) delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids!!.and(0xFFFFFFFF)
*/ */
override val id: Int get() = sequenceId override val ids: IntArray get() = sequenceIds
// delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids?.toInt() // delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids?.toInt()
// ?: 0 // ?: 0

View File

@ -24,6 +24,7 @@ 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.MsgComm
import net.mamoe.mirai.internal.network.protocol.data.proto.SourceMsg import net.mamoe.mirai.internal.network.protocol.data.proto.SourceMsg
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.OnlinePushPbPushGroupMsg.SendGroupMessageReceipt import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.OnlinePushPbPushGroupMsg.SendGroupMessageReceipt
import net.mamoe.mirai.internal.network.protocol.packet.chat.toLongUnsigned
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
@ -35,27 +36,30 @@ private fun <T> T.toJceDataImpl(): ImMsgBody.SourceMsg
where T : MessageSourceInternal, T : MessageSource { where T : MessageSourceInternal, T : MessageSource {
val elements = originalMessage.toRichTextElems(forGroup = false, withGeneralFlags = true) val elements = originalMessage.toRichTextElems(forGroup = false, withGeneralFlags = true)
val messageUid: Long = sequenceId.toLong().shl(32) or internalId.toLong().and(0xffFFffFF)
val pdReserve = SourceMsg.ResvAttr(
origUids = sequenceIds.zip(internalIds)
.map { (seq, internal) -> seq.toLong().shl(32) or internal.toLongUnsigned() }
)
return ImMsgBody.SourceMsg( return ImMsgBody.SourceMsg(
origSeqs = listOf(sequenceId), origSeqs = sequenceIds,
senderUin = fromId, senderUin = fromId,
toUin = targetId, toUin = targetId,
flag = 1, flag = 1,
elems = elements, elems = elements,
type = 0, type = 0,
time = time, time = time,
pbReserve = SourceMsg.ResvAttr( pbReserve = pdReserve.toByteArray(SourceMsg.ResvAttr.serializer()),
origUids = messageUid
).toByteArray(SourceMsg.ResvAttr.serializer()),
srcMsg = MsgComm.Msg( srcMsg = MsgComm.Msg(
msgHead = MsgComm.MsgHead( msgHead = MsgComm.MsgHead(
fromUin = fromId, // qq fromUin = fromId, // qq
toUin = targetId, // group toUin = targetId, // group
msgType = 9, // 82? msgType = 9, // 82?
c2cCmd = 11, c2cCmd = 11,
msgSeq = sequenceId, msgSeq = sequenceIds.single(), // TODO !!
msgTime = time, msgTime = time,
msgUid = messageUid, // ok msgUid = pdReserve.origUids!!.single(), // TODO !!
// groupInfo = MsgComm.GroupInfo(groupCode = delegate.msgHead.groupInfo.groupCode), // groupInfo = MsgComm.GroupInfo(groupCode = delegate.msgHead.groupInfo.groupCode),
isSrcMsg = true isSrcMsg = true
), ),
@ -71,8 +75,8 @@ private fun <T> T.toJceDataImpl(): ImMsgBody.SourceMsg
} }
internal class MessageSourceToFriendImpl( internal class MessageSourceToFriendImpl(
override val sequenceId: Int, override val sequenceIds: IntArray,
override val internalId: Int, override val internalIds: IntArray,
override val time: Int, override val time: Int,
override val originalMessage: MessageChain, override val originalMessage: MessageChain,
override val sender: Bot, override val sender: Bot,
@ -80,16 +84,16 @@ internal class MessageSourceToFriendImpl(
) : OnlineMessageSource.Outgoing.ToFriend(), MessageSourceInternal { ) : OnlineMessageSource.Outgoing.ToFriend(), MessageSourceInternal {
override val bot: Bot override val bot: Bot
get() = sender get() = sender
override val id: Int override val ids: IntArray
get() = sequenceId get() = sequenceIds
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false) override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
private val jceData by lazy { toJceDataImpl() } private val jceData by lazy { toJceDataImpl() }
override fun toJceData(): ImMsgBody.SourceMsg = jceData override fun toJceData(): ImMsgBody.SourceMsg = jceData
} }
internal class MessageSourceToTempImpl( internal class MessageSourceToTempImpl(
override val sequenceId: Int, override val sequenceIds: IntArray,
override val internalId: Int, override val internalIds: IntArray,
override val time: Int, override val time: Int,
override val originalMessage: MessageChain, override val originalMessage: MessageChain,
override val sender: Bot, override val sender: Bot,
@ -97,8 +101,8 @@ internal class MessageSourceToTempImpl(
) : OnlineMessageSource.Outgoing.ToTemp(), MessageSourceInternal { ) : OnlineMessageSource.Outgoing.ToTemp(), MessageSourceInternal {
override val bot: Bot override val bot: Bot
get() = sender get() = sender
override val id: Int override val ids: IntArray
get() = sequenceId get() = sequenceIds
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false) override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
private val jceData by lazy { toJceDataImpl() } private val jceData by lazy { toJceDataImpl() }
override fun toJceData(): ImMsgBody.SourceMsg = jceData override fun toJceData(): ImMsgBody.SourceMsg = jceData
@ -106,14 +110,14 @@ internal class MessageSourceToTempImpl(
internal class MessageSourceToGroupImpl( internal class MessageSourceToGroupImpl(
coroutineScope: CoroutineScope, coroutineScope: CoroutineScope,
override val internalId: Int, override val internalIds: IntArray,
override val time: Int, override val time: Int,
override val originalMessage: MessageChain, override val originalMessage: MessageChain,
override val sender: Bot, override val sender: Bot,
override val target: Group override val target: Group
) : OnlineMessageSource.Outgoing.ToGroup(), MessageSourceInternal { ) : OnlineMessageSource.Outgoing.ToGroup(), MessageSourceInternal {
override val id: Int override val ids: IntArray
get() = sequenceId get() = sequenceIds
override val bot: Bot override val bot: Bot
get() = sender get() = sender
override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false) override var isRecalledOrPlanned: AtomicBoolean = AtomicBoolean(false)
@ -122,25 +126,27 @@ internal class MessageSourceToGroupImpl(
coroutineScope.asyncFromEventOrNull<SendGroupMessageReceipt, Int>( coroutineScope.asyncFromEventOrNull<SendGroupMessageReceipt, Int>(
timeoutMillis = 3000 timeoutMillis = 3000
) { ) {
if (it.messageRandom == this@MessageSourceToGroupImpl.internalId) { if (it.messageRandom in this@MessageSourceToGroupImpl.internalIds) {
it.sequenceId it.sequenceId
} else null } else null
} }
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
override val sequenceId: Int override val sequenceIds: IntArray
get() = when { get() = intArrayOf(
sequenceIdDeferred.isCompleted -> sequenceIdDeferred.getCompleted() ?: -1 when {
!sequenceIdDeferred.isActive -> -1 sequenceIdDeferred.isCompleted -> sequenceIdDeferred.getCompleted() ?: -1
else -> error("sequenceId not yet available") !sequenceIdDeferred.isActive -> -1
} else -> error("sequenceIds not yet available")
}
)
suspend fun ensureSequenceIdAvailable() = kotlin.run { sequenceIdDeferred.await() } suspend fun ensureSequenceIdAvailable() = kotlin.run { sequenceIdDeferred.await() }
private val jceData by lazy { private val jceData by lazy {
val elements = originalMessage.toRichTextElems(forGroup = false, withGeneralFlags = true) val elements = originalMessage.toRichTextElems(forGroup = false, withGeneralFlags = true)
ImMsgBody.SourceMsg( ImMsgBody.SourceMsg(
origSeqs = listOf(sequenceId), origSeqs = sequenceIds,
senderUin = fromId, senderUin = fromId,
toUin = Mirai.calculateGroupUinByGroupCode(targetId), toUin = Mirai.calculateGroupUinByGroupCode(targetId),
flag = 1, flag = 1,
@ -148,7 +154,7 @@ internal class MessageSourceToGroupImpl(
type = 0, type = 0,
time = time, time = time,
pbReserve = SourceMsg.ResvAttr( pbReserve = SourceMsg.ResvAttr(
origUids = internalId.toLong() and 0xffFFffFF // id is actually messageRandom origUids = internalIds.map { it.toLongUnsigned() } // ids is actually messageRandom
).toByteArray(SourceMsg.ResvAttr.serializer()), ).toByteArray(SourceMsg.ResvAttr.serializer()),
srcMsg = MsgComm.Msg( srcMsg = MsgComm.Msg(
msgHead = MsgComm.MsgHead( msgHead = MsgComm.MsgHead(
@ -156,9 +162,9 @@ internal class MessageSourceToGroupImpl(
toUin = Mirai.calculateGroupUinByGroupCode(targetId), // group toUin = Mirai.calculateGroupUinByGroupCode(targetId), // group
msgType = 82, // 82? msgType = 82, // 82?
c2cCmd = 1, c2cCmd = 1,
msgSeq = sequenceId, msgSeq = sequenceIds.single(), // TODO !!
msgTime = time, msgTime = time,
msgUid = internalId.toLong() and 0xffFFffFF, // ok msgUid = internalIds.single().toLongUnsigned(), // TODO !!
groupInfo = MsgComm.GroupInfo(groupCode = targetId), groupInfo = MsgComm.GroupInfo(groupCode = targetId),
isSrcMsg = true isSrcMsg = true
), ),

View File

@ -16,7 +16,6 @@ import kotlinx.serialization.protobuf.ProtoType
import net.mamoe.mirai.internal.network.protocol.packet.EMPTY_BYTE_ARRAY import net.mamoe.mirai.internal.network.protocol.packet.EMPTY_BYTE_ARRAY
import net.mamoe.mirai.internal.utils.io.ProtoBuf import net.mamoe.mirai.internal.utils.io.ProtoBuf
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
import kotlin.jvm.JvmField
@Serializable @Serializable
internal class ImCommon : ProtoBuf { internal class ImCommon : ProtoBuf {
@ -879,7 +878,7 @@ internal class ImMsgBody : ProtoBuf {
@Serializable @Serializable
internal class SourceMsg( internal class SourceMsg(
@ProtoNumber(1) @JvmField val origSeqs: List<Int> = emptyList(), @ProtoNumber(1) @JvmField val origSeqs: IntArray = intArrayOf(),
@ProtoNumber(2) @JvmField val senderUin: Long = 0L, @ProtoNumber(2) @JvmField val senderUin: Long = 0L,
@ProtoNumber(3) @JvmField val time: Int = 0, @ProtoNumber(3) @JvmField val time: Int = 0,
@ProtoNumber(4) @JvmField val flag: Int = 0, @ProtoNumber(4) @JvmField val flag: Int = 0,

View File

@ -13,7 +13,6 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import net.mamoe.mirai.internal.network.protocol.packet.EMPTY_BYTE_ARRAY import net.mamoe.mirai.internal.network.protocol.packet.EMPTY_BYTE_ARRAY
import net.mamoe.mirai.internal.utils.io.ProtoBuf import net.mamoe.mirai.internal.utils.io.ProtoBuf
import kotlin.jvm.JvmField
internal class Generalflags : ProtoBuf { internal class Generalflags : ProtoBuf {
@Serializable @Serializable
@ -117,7 +116,7 @@ internal class SourceMsg : ProtoBuf {
internal class ResvAttr( internal class ResvAttr(
@ProtoNumber(1) @JvmField val richMsg2: ByteArray? = null, @ProtoNumber(1) @JvmField val richMsg2: ByteArray? = null,
@ProtoNumber(2) @JvmField val oriMsgtype: Int? = null, @ProtoNumber(2) @JvmField val oriMsgtype: Int? = null,
@ProtoNumber(3) @JvmField val origUids: Long? = null // 原来是 list @ProtoNumber(3) @JvmField val origUids: List<Long>? = null
) : ProtoBuf ) : ProtoBuf
} }

View File

@ -46,66 +46,74 @@ internal class PbMessageSvc {
fun createForGroupMessage( fun createForGroupMessage(
client: QQAndroidClient, client: QQAndroidClient,
groupCode: Long, groupCode: Long,
messageSequenceId: Int, // 56639 messageSequenceId: IntArray, // 56639
messageRandom: Int, // 921878719 messageRandom: IntArray, // 921878719
messageType: Int = 0 messageType: Int = 0
): OutgoingPacket = buildOutgoingUniPacket(client) { ): OutgoingPacket {
writeProtoBuf( require(messageSequenceId.size == messageRandom.size)
MsgSvc.PbMsgWithDrawReq.serializer(),
MsgSvc.PbMsgWithDrawReq( return buildOutgoingUniPacket(client) {
groupWithDraw = listOf( writeProtoBuf(
MsgSvc.PbGroupMsgWithDrawReq( MsgSvc.PbMsgWithDrawReq.serializer(),
subCmd = 1, MsgSvc.PbMsgWithDrawReq(
groupType = 0, // 普通群 groupWithDraw = listOf(
groupCode = groupCode, MsgSvc.PbGroupMsgWithDrawReq(
msgList = listOf( subCmd = 1,
MsgSvc.PbGroupMsgWithDrawReq.MessageInfo( groupType = 0, // 普通群
msgSeq = messageSequenceId, groupCode = groupCode,
msgRandom = messageRandom, msgList = messageSequenceId.zip(messageRandom).map { (seq, random) ->
msgType = messageType MsgSvc.PbGroupMsgWithDrawReq.MessageInfo(
) msgSeq = seq,
), msgRandom = random,
userdef = MsgRevokeUserDef.MsgInfoUserDef( msgType = messageType
longMessageFlag = 0 )
).toByteArray(MsgRevokeUserDef.MsgInfoUserDef.serializer()) },
userdef = MsgRevokeUserDef.MsgInfoUserDef(
longMessageFlag = 0
).toByteArray(MsgRevokeUserDef.MsgInfoUserDef.serializer())
)
) )
) )
) )
) }
} }
fun createForTempMessage( fun createForTempMessage(
client: QQAndroidClient, client: QQAndroidClient,
groupUin: Long, groupUin: Long,
toUin: Long, toUin: Long,
messageSequenceId: Int, // 56639 messageSequenceId: IntArray, // 56639
messageRandom: Int, // 921878719 messageRandom: IntArray, // 921878719
time: Int time: Int
): OutgoingPacket = buildOutgoingUniPacket(client) { ): OutgoingPacket {
writeProtoBuf( require(messageSequenceId.size == messageRandom.size)
MsgSvc.PbMsgWithDrawReq.serializer(),
MsgSvc.PbMsgWithDrawReq( return buildOutgoingUniPacket(client) {
c2cWithDraw = listOf( writeProtoBuf(
MsgSvc.PbC2CMsgWithDrawReq( MsgSvc.PbMsgWithDrawReq.serializer(),
subCmd = 1, MsgSvc.PbMsgWithDrawReq(
msgInfo = listOf( c2cWithDraw = listOf(
MsgSvc.PbC2CMsgWithDrawReq.MsgInfo( MsgSvc.PbC2CMsgWithDrawReq(
fromUin = client.bot.id, subCmd = 1,
toUin = toUin, msgInfo = messageSequenceId.zip(messageRandom).map { (seq, random) ->
msgSeq = messageSequenceId, MsgSvc.PbC2CMsgWithDrawReq.MsgInfo(
msgRandom = messageRandom, fromUin = client.bot.id,
msgUid = 0x0100000000000000 or (messageRandom.toLong() and 0xFFFFFFFF), toUin = toUin,
msgTime = time.toLong(), msgSeq = seq,
routingHead = MsgSvc.RoutingHead( msgRandom = random,
grpTmp = MsgSvc.GrpTmp(groupUin, toUin) msgUid = 0x0100000000000000 or random.toLongUnsigned(),
msgTime = time.toLong(),
routingHead = MsgSvc.RoutingHead(
grpTmp = MsgSvc.GrpTmp(groupUin, toUin)
)
) )
) },
), reserved = RESERVED_TEMP
reserved = RESERVED_TEMP )
) )
) )
) )
) }
} }
private val RESERVED_TEMP = "08 01 10 E3 E9 D6 80 02".hexToBytes() private val RESERVED_TEMP = "08 01 10 E3 E9 D6 80 02".hexToBytes()
@ -113,36 +121,40 @@ internal class PbMessageSvc {
fun createForFriendMessage( fun createForFriendMessage(
client: QQAndroidClient, client: QQAndroidClient,
toUin: Long, toUin: Long,
messageSequenceId: Int, // 56639 messageSequenceId: IntArray, // 56639
messageRandom: Int, // 921878719 messageRandom: IntArray, // 921878719
time: Int time: Int
): OutgoingPacket = buildOutgoingUniPacket(client) { ): OutgoingPacket {
writeProtoBuf( require(messageSequenceId.size == messageRandom.size)
MsgSvc.PbMsgWithDrawReq.serializer(),
MsgSvc.PbMsgWithDrawReq( return buildOutgoingUniPacket(client) {
c2cWithDraw = listOf( writeProtoBuf(
MsgSvc.PbC2CMsgWithDrawReq( MsgSvc.PbMsgWithDrawReq.serializer(),
subCmd = 1, MsgSvc.PbMsgWithDrawReq(
msgInfo = listOf( c2cWithDraw = listOf(
MsgSvc.PbC2CMsgWithDrawReq.MsgInfo( MsgSvc.PbC2CMsgWithDrawReq(
fromUin = client.bot.id, subCmd = 1,
toUin = toUin, msgInfo = messageSequenceId.zip(messageRandom).map { (seq, random) ->
msgSeq = messageSequenceId, MsgSvc.PbC2CMsgWithDrawReq.MsgInfo(
msgRandom = messageRandom, fromUin = client.bot.id,
msgUid = 0x0100000000000000 or (messageRandom.toLong() and 0xFFFFFFFF), toUin = toUin,
msgTime = time.toLong(), msgSeq = seq,
routingHead = MsgSvc.RoutingHead( msgRandom = random,
c2c = MsgSvc.C2C( msgUid = 0x0100000000000000 or random.toLongUnsigned(),
toUin = toUin msgTime = time.toLong(),
routingHead = MsgSvc.RoutingHead(
c2c = MsgSvc.C2C(
toUin = toUin
)
) )
) )
) },
), reserved = byteArrayOf(0x08, 0x00)
reserved = byteArrayOf(0x08, 0x00) )
) )
) )
) )
) }
} }
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response { override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {

View File

@ -78,8 +78,8 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
elems = message.toRichTextElems(forGroup = false, withGeneralFlags = true) elems = message.toRichTextElems(forGroup = false, withGeneralFlags = true)
) )
), ),
msgSeq = source.sequenceId, msgSeq = source.sequenceIds.single(),
msgRand = source.internalId, msgRand = source.internalIds.single(),
syncCookie = client.syncingController.syncCookie ?: byteArrayOf() syncCookie = client.syncingController.syncCookie ?: byteArrayOf()
// msgVia = 1 // msgVia = 1
) )
@ -108,8 +108,8 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
elems = message.toRichTextElems(forGroup = false, withGeneralFlags = true) elems = message.toRichTextElems(forGroup = false, withGeneralFlags = true)
) )
), ),
msgSeq = source.sequenceId, msgSeq = source.sequenceIds.single(),
msgRand = source.internalId, msgRand = source.internalIds.single(),
syncCookie = client.syncingController.syncCookie ?: byteArrayOf() syncCookie = client.syncingController.syncCookie ?: byteArrayOf()
) )
) )
@ -152,7 +152,7 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
) )
), ),
msgSeq = client.atomicNextMessageSequenceId(), msgSeq = client.atomicNextMessageSequenceId(),
msgRand = source.internalId, msgRand = source.internalIds.single(),
syncCookie = EMPTY_BYTE_ARRAY, syncCookie = EMPTY_BYTE_ARRAY,
msgVia = 1, msgVia = 1,
msgCtrl = if (isForward) MsgCtrl.MsgCtrl( msgCtrl = if (isForward) MsgCtrl.MsgCtrl(
@ -186,11 +186,11 @@ internal inline fun MessageSvcPbSendMsg.createToTemp(
callsInPlace(sourceCallback, InvocationKind.EXACTLY_ONCE) callsInPlace(sourceCallback, InvocationKind.EXACTLY_ONCE)
} }
val source = MessageSourceToTempImpl( val source = MessageSourceToTempImpl(
internalId = Random.nextInt().absoluteValue, internalIds = intArrayOf(Random.nextInt().absoluteValue),
sender = client.bot, sender = client.bot,
target = member, target = member,
time = currentTimeSeconds.toInt(), time = currentTimeSeconds.toInt(),
sequenceId = client.atomicNextMessageSequenceId(), sequenceIds = intArrayOf(client.atomicNextMessageSequenceId()),
originalMessage = message originalMessage = message
) )
sourceCallback(source) sourceCallback(source)
@ -214,11 +214,11 @@ internal inline fun MessageSvcPbSendMsg.createToFriend(
} }
val rand = Random.nextInt().absoluteValue val rand = Random.nextInt().absoluteValue
val source = MessageSourceToFriendImpl( val source = MessageSourceToFriendImpl(
internalId = rand, internalIds = intArrayOf(rand),
sender = client.bot, sender = client.bot,
target = qq, target = qq,
time = currentTimeSeconds.toInt(), time = currentTimeSeconds.toInt(),
sequenceId = client.nextFriendSeq(), sequenceIds = intArrayOf(client.nextFriendSeq()),
originalMessage = message originalMessage = message
) )
sourceCallback(source) sourceCallback(source)
@ -242,7 +242,7 @@ internal inline fun MessageSvcPbSendMsg.createToGroup(
} }
val source = MessageSourceToGroupImpl( val source = MessageSourceToGroupImpl(
group, group,
internalId = Random.nextInt().absoluteValue, internalIds = intArrayOf(Random.nextInt().absoluteValue),
sender = client.bot, sender = client.bot,
target = group, target = group,
time = currentTimeSeconds.toInt(), time = currentTimeSeconds.toInt(),

View File

@ -367,8 +367,8 @@ private object Transformers732 : Map<Int, Lambda732> by mapOf(
MessageRecallEvent.GroupRecall( MessageRecallEvent.GroupRecall(
bot, bot,
pkg.authorUin, pkg.authorUin,
pkg.seq, intArrayOf(pkg.seq),
pkg.msgRandom, intArrayOf(pkg.msgRandom),
pkg.time, pkg.time,
operator, operator,
group group
@ -440,8 +440,8 @@ internal object Transformers528 : Map<Long, Lambda528> by mapOf(
.filter { it.botUin == bot.id }.map { .filter { it.botUin == bot.id }.map {
MessageRecallEvent.FriendRecall( MessageRecallEvent.FriendRecall(
bot = bot, bot = bot,
messageId = it.srcId, messageIds = intArrayOf(it.srcId),
messageInternalId = it.srcInternalId, messageInternalIds = intArrayOf(it.srcInternalId),
messageTime = it.time, messageTime = it.time,
operator = it.fromUin operator = it.fromUin
) )