mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-02 22:21:32 +08:00
Rewrite recall
and MessageSource.id
This commit is contained in:
parent
cb3b2cdc17
commit
b70bf5e042
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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("未支持")
|
||||||
|
@ -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())
|
@ -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)"
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user