Rewrite recall and MessageSource.id

This commit is contained in:
Him188 2020-02-22 21:47:02 +08:00
parent cb3b2cdc17
commit b70bf5e042
10 changed files with 141 additions and 44 deletions

View File

@ -99,7 +99,7 @@ fun MessageChain.toDTOChain() = mutableListOf(this[MessageSource].toDTO()).apply
fun MessageChainDTO.toMessageChain(contact: Contact) = fun MessageChainDTO.toMessageChain(contact: Contact) =
MessageChain().apply { this@toMessageChain.forEach { add(it.toMessage(contact)) } } MessageChain().apply { this@toMessageChain.forEach { add(it.toMessage(contact)) } }
internal fun MessageSource.calMessageId() = (messageUid.toLong() shl 32) or (sequenceId.toLong() and 0xFFFFFFFF) internal fun MessageSource.calMessageId() = (messageRandom.toLong() shl 32) or (sequenceId.toLong() and 0xFFFFFFFF)
@UseExperimental(ExperimentalUnsignedTypes::class) @UseExperimental(ExperimentalUnsignedTypes::class)
fun Message.toDTO() = when (this) { fun Message.toDTO() = when (this) {

View File

@ -79,7 +79,7 @@ internal class QQImpl(
) { source = it }.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS ) { source = it }.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS
) { "send message failed" } ) { "send message failed" }
} }
return MessageReceipt(message, source, this) return MessageReceipt(source, this)
} }
override suspend fun uploadImage(image: ExternalImage): Image = try { override suspend fun uploadImage(image: ExternalImage): Image = try {
@ -553,7 +553,7 @@ internal class GroupImpl(
source.startWaitingSequenceId(this) source.startWaitingSequenceId(this)
return MessageReceipt(message, source, this) return MessageReceipt(source, this)
} }
override suspend fun uploadImage(image: ExternalImage): Image = try { override suspend fun uploadImage(image: ExternalImage): Image = try {

View File

@ -19,6 +19,8 @@ import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.data.MemberInfo import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.message.data.Image import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.message.data.messageRandom
import net.mamoe.mirai.message.data.sequenceId
import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler
import net.mamoe.mirai.qqandroid.network.QQAndroidClient import net.mamoe.mirai.qqandroid.network.QQAndroidClient
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl
@ -127,12 +129,27 @@ internal abstract class QQAndroidBotBase constructor(
network.run { network.run {
val response: PbMessageSvc.PbMsgWithDraw.Response = val response: PbMessageSvc.PbMsgWithDraw.Response =
PbMessageSvc.PbMsgWithDraw.Group(bot.client, source.groupId, source.sequenceId, source.messageUid) PbMessageSvc.PbMsgWithDraw.Group(bot.client, source.groupId, source.sequenceId, source.messageRandom)
.sendAndExpect() .sendAndExpect()
check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.sequenceId}: $response" } check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.sequenceId}: $response" }
} }
} }
override suspend fun recall(groupId: Long, senderId: Long, messageId: Long) {
if (senderId != uin) {
getGroup(groupId).checkBotPermissionOperator()
}
val sequenceId = (messageId shr 32).toInt()
network.run {
val response: PbMessageSvc.PbMsgWithDraw.Response =
PbMessageSvc.PbMsgWithDraw.Group(bot.client, groupId, sequenceId, messageId.toInt())
.sendAndExpect()
check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #$sequenceId: $response" }
}
}
override suspend fun Image.download(): ByteReadPacket { override suspend fun Image.download(): ByteReadPacket {
TODO("not implemented") TODO("not implemented")
} }

View File

@ -11,6 +11,7 @@ package net.mamoe.mirai.qqandroid.message
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.message.data.messageRandom
import net.mamoe.mirai.qqandroid.io.serialization.loadAs import net.mamoe.mirai.qqandroid.io.serialization.loadAs
import net.mamoe.mirai.qqandroid.io.serialization.toByteArray import net.mamoe.mirai.qqandroid.io.serialization.toByteArray
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
@ -21,13 +22,16 @@ internal inline class MessageSourceFromServer(
val delegate: ImMsgBody.SourceMsg val delegate: ImMsgBody.SourceMsg
) : MessageSource { ) : MessageSource {
override val time: Long get() = delegate.time.toLong() and 0xFFFFFFFF override val time: Long get() = delegate.time.toLong() and 0xFFFFFFFF
override val sequenceId: Int get() = delegate.origSeqs?.firstOrNull() ?: error("cannot find sequenceId from ImMsgBody.SourceMsg")
override val id: Long
get() = (delegate.origSeqs?.firstOrNull() ?: error("cannot find sequenceId from ImMsgBody.SourceMsg")).toLong().shl(32) or
(delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids!!.toInt()).toLong().and(0xFFFFFFFF)
override suspend fun ensureSequenceIdAvailable() { override suspend fun ensureSequenceIdAvailable() {
// nothing to do // nothing to do
} }
override val messageUid: Int get() = delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids!!.toInt()
// override val sourceMessage: MessageChain get() = delegate.toMessageChain() // override val sourceMessage: MessageChain get() = delegate.toMessageChain()
override val senderId: Long get() = delegate.senderUin override val senderId: Long get() = delegate.senderUin
override val groupId: Long get() = Group.calculateGroupCodeByGroupUin(delegate.toUin) override val groupId: Long get() = Group.calculateGroupCodeByGroupUin(delegate.toUin)
@ -39,12 +43,14 @@ internal inline class MessageSourceFromMsg(
val delegate: MsgComm.Msg val delegate: MsgComm.Msg
) : MessageSource { ) : MessageSource {
override val time: Long get() = delegate.msgHead.msgTime.toLong() and 0xFFFFFFFF override val time: Long get() = delegate.msgHead.msgTime.toLong() and 0xFFFFFFFF
override val sequenceId: Int get() = delegate.msgHead.msgSeq override val id: Long
get() = delegate.msgHead.msgSeq.toLong().shl(32) or
delegate.msgBody.richText.attr!!.random.toLong().and(0xFFFFFFFF)
override suspend fun ensureSequenceIdAvailable() { override suspend fun ensureSequenceIdAvailable() {
// nothing to do // nothing to do
} }
override val messageUid: Int get() = delegate.msgBody.richText.attr!!.random
// override val sourceMessage: MessageChain get() = delegate.toMessageChain() // override val sourceMessage: MessageChain get() = delegate.toMessageChain()
override val senderId: Long get() = delegate.msgHead.fromUin override val senderId: Long get() = delegate.msgHead.fromUin
override val groupId: Long get() = delegate.msgHead.groupInfo!!.groupCode override val groupId: Long get() = delegate.msgHead.groupInfo!!.groupCode
@ -62,7 +68,7 @@ internal inline class MessageSourceFromMsg(
type = 0, type = 0,
time = delegate.msgHead.msgTime, time = delegate.msgHead.msgTime,
pbReserve = SourceMsg.ResvAttr( pbReserve = SourceMsg.ResvAttr(
origUids = messageUid.toLong() and 0xffFFffFF origUids = messageRandom.toLong() and 0xffFFffFF
).toByteArray(SourceMsg.ResvAttr.serializer()), ).toByteArray(SourceMsg.ResvAttr.serializer()),
srcMsg = MsgComm.Msg( srcMsg = MsgComm.Msg(
msgHead = MsgComm.MsgHead( msgHead = MsgComm.MsgHead(
@ -72,7 +78,7 @@ internal inline class MessageSourceFromMsg(
c2cCmd = delegate.msgHead.c2cCmd, c2cCmd = delegate.msgHead.c2cCmd,
msgSeq = delegate.msgHead.msgSeq, msgSeq = delegate.msgHead.msgSeq,
msgTime = delegate.msgHead.msgTime, msgTime = delegate.msgHead.msgTime,
msgUid = messageUid.toLong() and 0xffFFffFF msgUid = messageRandom.toLong() and 0xffFFffFF
, // ok , // ok
groupInfo = MsgComm.GroupInfo(groupCode = delegate.msgHead.groupInfo.groupCode), groupInfo = MsgComm.GroupInfo(groupCode = delegate.msgHead.groupInfo.groupCode),
isSrcMsg = true isSrcMsg = true

View File

@ -272,7 +272,7 @@ internal class MessageSvc {
} }
internal class MessageSourceFromSend( internal class MessageSourceFromSend(
override val messageUid: Int, val messageRandom: Int,
override val time: Long, override val time: Long,
override val senderId: Long, override val senderId: Long,
override val groupId: Long// , override val groupId: Long// ,
@ -280,19 +280,20 @@ internal class MessageSvc {
) : MessageSource { ) : MessageSource {
private lateinit var sequenceIdDeferred: Deferred<Int> private lateinit var sequenceIdDeferred: Deferred<Int>
@UseExperimental(ExperimentalCoroutinesApi::class)
override val id: Long
get() = sequenceIdDeferred.getCompleted().toLong().shl(32) or
messageRandom.toLong().and(0xFFFFFFFF)
@UseExperimental(MiraiExperimentalAPI::class) @UseExperimental(MiraiExperimentalAPI::class)
fun startWaitingSequenceId(contact: Contact) { fun startWaitingSequenceId(contact: Contact) {
sequenceIdDeferred = contact.subscribingGetAsync<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt, Int> { sequenceIdDeferred = contact.subscribingGetAsync<OnlinePush.PbPushGroupMsg.SendGroupMessageReceipt, Int> {
if (it.messageRandom == messageUid) { if (it.messageRandom == this@MessageSourceFromSend.messageRandom) {
it.sequenceId it.sequenceId
} else null } else null
} }
} }
@UseExperimental(ExperimentalCoroutinesApi::class)
override val sequenceId: Int
get() = sequenceIdDeferred.getCompleted()
override suspend fun ensureSequenceIdAvailable() { override suspend fun ensureSequenceIdAvailable() {
sequenceIdDeferred.join() sequenceIdDeferred.join()
} }
@ -309,7 +310,7 @@ internal class MessageSvc {
crossinline sourceCallback: (MessageSource) -> Unit crossinline sourceCallback: (MessageSource) -> Unit
): OutgoingPacket { ): OutgoingPacket {
val source = MessageSourceFromSend( val source = MessageSourceFromSend(
messageUid = Random.nextInt().absoluteValue, messageRandom = Random.nextInt().absoluteValue,
senderId = client.uin, senderId = client.uin,
time = currentTimeSeconds + client.timeDifference, time = currentTimeSeconds + client.timeDifference,
groupId = 0// groupId = 0//
@ -327,7 +328,7 @@ internal class MessageSvc {
client: QQAndroidClient, client: QQAndroidClient,
toUin: Long, toUin: Long,
message: MessageChain, message: MessageChain,
source: MessageSource source: MessageSourceFromSend
): OutgoingPacket = buildOutgoingUniPacket(client) { ): OutgoingPacket = buildOutgoingUniPacket(client) {
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes()) ///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
@ -342,7 +343,7 @@ internal class MessageSvc {
) )
), ),
msgSeq = client.atomicNextMessageSequenceId(), msgSeq = client.atomicNextMessageSequenceId(),
msgRand = source.messageUid, msgRand = source.messageRandom,
syncCookie = SyncCookie(time = source.time).toByteArray(SyncCookie.serializer()) syncCookie = SyncCookie(time = source.time).toByteArray(SyncCookie.serializer())
// msgVia = 1 // msgVia = 1
) )
@ -358,7 +359,7 @@ internal class MessageSvc {
): OutgoingPacket { ): OutgoingPacket {
val source = MessageSourceFromSend( val source = MessageSourceFromSend(
messageUid = Random.nextInt().absoluteValue, messageRandom = Random.nextInt().absoluteValue,
senderId = client.uin, senderId = client.uin,
time = currentTimeSeconds + client.timeDifference, time = currentTimeSeconds + client.timeDifference,
groupId = groupCode//, groupId = groupCode//,
@ -372,11 +373,11 @@ internal class MessageSvc {
* 发送群消息 * 发送群消息
*/ */
@Suppress("FunctionName") @Suppress("FunctionName")
fun ToGroup( private fun ToGroup(
client: QQAndroidClient, client: QQAndroidClient,
groupCode: Long, groupCode: Long,
message: MessageChain, message: MessageChain,
source: MessageSource source: MessageSourceFromSend
): OutgoingPacket = buildOutgoingUniPacket(client) { ): OutgoingPacket = buildOutgoingUniPacket(client) {
///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes()) ///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes())
@ -393,7 +394,7 @@ internal class MessageSvc {
) )
), ),
msgSeq = client.atomicNextMessageSequenceId(), msgSeq = client.atomicNextMessageSequenceId(),
msgRand = source.messageUid, msgRand = source.messageRandom,
syncCookie = EMPTY_BYTE_ARRAY, syncCookie = EMPTY_BYTE_ARRAY,
msgVia = 1 msgVia = 1
) )

View File

@ -231,11 +231,13 @@ abstract class Bot : CoroutineScope {
* [Bot] 撤回自己的消息不需要权限. * [Bot] 撤回自己的消息不需要权限.
* [Bot] 撤回群员的消息需要管理员权限. * [Bot] 撤回群员的消息需要管理员权限.
* *
* @param messageId [MessageSource.id]
*
* @throws PermissionDeniedException [Bot] 无权限操作时 * @throws PermissionDeniedException [Bot] 无权限操作时
* @see Bot.recall (扩展函数) 接受参数 [MessageChain] * @see Bot.recall (扩展函数) 接受参数 [MessageChain]
* @see 更推荐说 * @see recall 请优先使用这个函数
*/ */
abstract suspend fun recall(groupId: Long, messageSequenceId: Int, messageUid: Int) abstract suspend fun recall(groupId: Long, senderId: Long, messageId: Long)
@Deprecated("内存使用效率十分低下", ReplaceWith("this.download()"), DeprecationLevel.WARNING) @Deprecated("内存使用效率十分低下", ReplaceWith("this.download()"), DeprecationLevel.WARNING)
@MiraiExperimentalAPI("未支持") @MiraiExperimentalAPI("未支持")

View File

@ -12,6 +12,7 @@
package net.mamoe.mirai.contact package net.mamoe.mirai.contact
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.BeforeImageUploadEvent import net.mamoe.mirai.event.events.BeforeImageUploadEvent
import net.mamoe.mirai.event.events.EventCancelledException import net.mamoe.mirai.event.events.EventCancelledException
@ -20,8 +21,13 @@ import net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.recall
import net.mamoe.mirai.recallIn
import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.WeakRefProperty import net.mamoe.mirai.utils.WeakRefProperty
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/** /**
@ -92,8 +98,44 @@ interface Contact : CoroutineScope {
override fun toString(): String override fun toString(): String
} }
/**
* @see Bot.recall
*/
@MiraiExperimentalAPI
suspend inline fun Contact.recall(source: MessageChain) = this.bot.recall(source)
/**
* @see Bot.recall
*/
suspend inline fun Contact.recall(source: MessageSource) = this.bot.recall(source)
/**
* @see Bot.recallIn
*/
@MiraiExperimentalAPI
fun Contact.recallIn(
message: MessageChain,
millis: Long,
coroutineContext: CoroutineContext = EmptyCoroutineContext
): Job = this.bot.recallIn(message, millis, coroutineContext)
/**
* @see Bot.recallIn
*/
fun Contact.recallIn(
source: MessageSource,
millis: Long,
coroutineContext: CoroutineContext = EmptyCoroutineContext
): Job = this.bot.recallIn(source, millis, coroutineContext)
/**
* @see Contact.sendMessage
*/
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
suspend inline fun <C : Contact> C.sendMessage(message: Message): MessageReceipt<C> = suspend inline fun <C : Contact> C.sendMessage(message: Message): MessageReceipt<C> =
sendMessage(message.toChain()) as? MessageReceipt<C> ?: error("Internal class cast mistake") sendMessage(message.toChain()) as? MessageReceipt<C> ?: error("Internal class cast mistake")
/**
* @see Contact.sendMessage
*/
suspend inline fun <C : Contact> C.sendMessage(plain: String): MessageReceipt<C> = sendMessage(plain.toMessage()) suspend inline fun <C : Contact> C.sendMessage(plain: String): MessageReceipt<C> = sendMessage(plain.toMessage())

View File

@ -11,11 +11,16 @@ package net.mamoe.mirai.message
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.Event import net.mamoe.mirai.event.Event
import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.Message
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
import net.mamoe.mirai.recall
import net.mamoe.mirai.recallIn
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.getValue import net.mamoe.mirai.utils.getValue
import net.mamoe.mirai.utils.unsafeWeakRef import net.mamoe.mirai.utils.unsafeWeakRef
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
@ -59,10 +64,13 @@ class GroupMessage(
@JvmName("reply2") @JvmName("reply2")
suspend inline fun MessageChain.quoteReply(): MessageReceipt<Group> = quoteReply(this) suspend inline fun MessageChain.quoteReply(): MessageReceipt<Group> = quoteReply(this)
suspend inline fun MessageChain.recall() = group.recall(this) @MiraiExperimentalAPI
suspend inline fun MessageSource.recall() = group.recall(this) suspend inline fun MessageChain.recall() = bot.recall(this)
inline fun MessageSource.recallIn(delay: Long): Job = group.recallIn(this, delay)
inline fun MessageChain.recallIn(delay: Long): Job = group.recallIn(this, delay) suspend inline fun MessageSource.recall() = bot.recall(this)
inline fun MessageSource.recallIn(delay: Long): Job = bot.recallIn(this, delay)
@MiraiExperimentalAPI
inline fun MessageChain.recallIn(delay: Long): Job = bot.recallIn(this, delay)
override fun toString(): String = override fun toString(): String =
"GroupMessage(group=${group.id}, senderName=$senderName, sender=${sender.id}, permission=${permission.name}, message=$message)" "GroupMessage(group=${group.id}, senderName=$senderName, sender=${sender.id}, permission=${permission.name}, message=$message)"

View File

@ -12,8 +12,11 @@ package net.mamoe.mirai.message
import kotlinx.atomicfu.atomic import kotlinx.atomicfu.atomic
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.recallIn
import net.mamoe.mirai.utils.MiraiExperimentalAPI import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.getValue import net.mamoe.mirai.utils.getValue
import net.mamoe.mirai.utils.unsafeWeakRef import net.mamoe.mirai.utils.unsafeWeakRef
@ -27,7 +30,6 @@ import net.mamoe.mirai.utils.unsafeWeakRef
* @see QQ.sendMessage 发送群消息, 返回回执此对象 * @see QQ.sendMessage 发送群消息, 返回回执此对象
*/ */
open class MessageReceipt<C : Contact>( open class MessageReceipt<C : Contact>(
val originalMessage: MessageChain,
private val source: MessageSource, private val source: MessageSource,
target: C target: C
) { ) {
@ -54,7 +56,7 @@ open class MessageReceipt<C : Contact>(
if (_isRecalled.compareAndSet(false, true)) { if (_isRecalled.compareAndSet(false, true)) {
when (val contact = target) { when (val contact = target) {
is Group -> { is Group -> {
contact.recall(source) contact.bot.recall(source)
} }
is QQ -> { is QQ -> {
TODO() TODO()
@ -77,7 +79,7 @@ open class MessageReceipt<C : Contact>(
if (_isRecalled.compareAndSet(false, true)) { if (_isRecalled.compareAndSet(false, true)) {
when (val contact = target) { when (val contact = target) {
is Group -> { is Group -> {
return contact.recallIn(source, millis) return contact.bot.recallIn(source, millis)
} }
is QQ -> { is QQ -> {
TODO() TODO()

View File

@ -27,9 +27,11 @@ interface MessageSource : Message {
companion object Key : Message.Key<MessageSource> companion object Key : Message.Key<MessageSource>
/** /**
* 序列号. 若是机器人发出去的消息, 请先 [确保 sequenceId 可用][ensureSequenceIdAvailable] * Mirai 中使用的 id.
* 32 位为 [sequenceId],
* 32 位为 [messageRandom]
*/ */
val sequenceId: Int val id: Long
/** /**
* 等待 [sequenceId] 获取, 确保其可用. * 等待 [sequenceId] 获取, 确保其可用.
@ -38,11 +40,6 @@ interface MessageSource : Message {
*/ */
suspend fun ensureSequenceIdAvailable() suspend fun ensureSequenceIdAvailable()
/**
* 实际上是个随机数, 但服务器确实是用它当做 uid
*/
val messageUid: Int
/** /**
* 发送时间, 单位为秒 * 发送时间, 单位为秒
*/ */
@ -65,11 +62,33 @@ interface MessageSource : Message {
} }
/** /**
* 消息唯一标识符. 实际上是个随机数, 但服务器确实是用它当做 uid * 序列号. 若是机器人发出去的消息, 请先 [确保 sequenceId 可用][MessageSource.ensureSequenceIdAvailable]
* @see MessageSource.id
*/ */
val MessageChain.messageUid get() = this[MessageSource].messageUid val MessageSource.sequenceId: Int get() = (this.id shr 32).toInt()
/**
* 消息随机数. 由服务器或客户端指定后不能更改. 它是消息 id 的一部分.
* @see MessageSource.id
*/
val MessageSource.messageRandom: Int get() = this.id.toInt()
// For MessageChain
/**
* 消息 id.
* @see MessageSource.id
*/
val MessageChain.id: Long get() = this[MessageSource].id
/** /**
* 消息序列号, 可能来自服务器也可以发送时赋值, 不唯一. * 消息序列号, 可能来自服务器也可以发送时赋值, 不唯一.
* @see MessageSource.id
*/ */
val MessageChain.sequenceId get() = this[MessageSource].sequenceId val MessageChain.sequenceId: Int get() = this[MessageSource].sequenceId
/**
* 消息随机数. 由服务器或客户端指定后不能更改. 它是消息 id 的一部分.
* @see MessageSource.id
*/
val MessageChain.messageRandom: Int get() = this[MessageSource].messageRandom