From 8454d782938249a90a08f391719dd5329aee3c02 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 22 Feb 2020 21:12:32 +0800 Subject: [PATCH] Move `recall` from `Contact` to `Group` --- .../net/mamoe/mirai/qqandroid/ContactImpl.kt | 16 +--- .../net/mamoe/mirai/qqandroid/QQAndroidBot.kt | 22 ++++- .../commonMain/kotlin/net.mamoe.mirai/Bot.kt | 81 +++++++++++++++++++ .../kotlin/net.mamoe.mirai/contact/Group.kt | 60 -------------- 4 files changed, 100 insertions(+), 79 deletions(-) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt index 873725f57..d2b80a21b 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt @@ -22,7 +22,6 @@ import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper import net.mamoe.mirai.qqandroid.network.highway.postImage import net.mamoe.mirai.qqandroid.network.protocol.data.jce.StTroopMemberInfo import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352 -import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.PbMessageSvc import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn @@ -505,25 +504,12 @@ internal class GroupImpl( } } + @MiraiExperimentalAPI override suspend fun quit(): Boolean { check(botPermission != MemberPermission.OWNER) { "An owner cannot quit from a owning group" } TODO("not implemented") } - override suspend fun recall(source: MessageSource) { - if (source.senderId != bot.uin) { - checkBotPermissionOperator() - } - - source.ensureSequenceIdAvailable() - - bot.network.run { - val response = PbMessageSvc.PbMsgWithDraw.Group(bot.client, this@GroupImpl.id, source.sequenceId, source.messageUid.toInt()) - .sendAndExpect() - check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.sequenceId}: $response" } - } - } - @UseExperimental(MiraiExperimentalAPI::class) override fun Member(memberInfo: MemberInfo): Member { return MemberImpl( diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt index 5c6c89699..7b9c2326a 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.kt @@ -12,18 +12,17 @@ package net.mamoe.mirai.qqandroid import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.BotAccount import net.mamoe.mirai.BotImpl -import net.mamoe.mirai.contact.ContactList -import net.mamoe.mirai.contact.Group -import net.mamoe.mirai.contact.QQ -import net.mamoe.mirai.contact.filteringGetOrNull +import net.mamoe.mirai.contact.* import net.mamoe.mirai.data.AddFriendResult import net.mamoe.mirai.data.FriendInfo import net.mamoe.mirai.data.GroupInfo import net.mamoe.mirai.data.MemberInfo import net.mamoe.mirai.message.data.Image +import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler 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.PbMessageSvc import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList import net.mamoe.mirai.utils.* @@ -119,6 +118,21 @@ internal abstract class QQAndroidBotBase constructor( TODO("not implemented") } + override suspend fun recall(source: MessageSource) { + if (source.senderId != uin) { + getGroup(source.groupId).checkBotPermissionOperator() + } + + source.ensureSequenceIdAvailable() + + network.run { + val response: PbMessageSvc.PbMsgWithDraw.Response = + PbMessageSvc.PbMsgWithDraw.Group(bot.client, source.groupId, source.sequenceId, source.messageUid) + .sendAndExpect() + check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.sequenceId}: $response" } + } + } + override suspend fun Image.download(): ByteReadPacket { TODO("not implemented") } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt index 11b5b9460..24ea3516e 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt @@ -11,8 +11,10 @@ package net.mamoe.mirai +import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job +import kotlinx.coroutines.launch import kotlinx.io.OutputStream import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.IoBuffer @@ -23,10 +25,14 @@ import net.mamoe.mirai.data.FriendInfo import net.mamoe.mirai.data.GroupInfo import net.mamoe.mirai.data.MemberInfo import net.mamoe.mirai.message.data.Image +import net.mamoe.mirai.message.data.MessageChain +import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.LoginFailedException import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.io.transferTo +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext import kotlin.jvm.JvmStatic /** @@ -208,12 +214,37 @@ abstract class Bot : CoroutineScope { // region actions + /** + * 撤回这条消息. + * + * [Bot] 撤回自己的消息不需要权限. + * [Bot] 撤回群员的消息需要管理员权限. + * + * @throws PermissionDeniedException 当 [Bot] 无权限操作时 + * @see Bot.recall (扩展函数) 接受参数 [MessageChain] + */// source.groupId, source.sequenceId, source.messageUid + abstract suspend fun recall(source: MessageSource) + + /** + * 撤回这条消息. + * + * [Bot] 撤回自己的消息不需要权限. + * [Bot] 撤回群员的消息需要管理员权限. + * + * @throws PermissionDeniedException 当 [Bot] 无权限操作时 + * @see Bot.recall (扩展函数) 接受参数 [MessageChain] + * @see 更推荐说 + */ + abstract suspend fun recall(groupId: Long, messageSequenceId: Int, messageUid: Int) + @Deprecated("内存使用效率十分低下", ReplaceWith("this.download()"), DeprecationLevel.WARNING) + @MiraiExperimentalAPI("未支持") abstract suspend fun Image.downloadAsByteArray(): ByteArray /** * 将图片下载到内存中 (使用 [IoBuffer.Pool]) */ + @MiraiExperimentalAPI("未支持") abstract suspend fun Image.download(): ByteReadPacket /** @@ -222,11 +253,13 @@ abstract class Bot : CoroutineScope { * @param message 若需要验证请求时的验证消息. * @param remark 好友备注 */ + @MiraiExperimentalAPI("未支持") abstract suspend fun addFriend(id: Long, message: String? = null, remark: String? = null): AddFriendResult /** * 同意来自陌生人的加好友请求 */ + @MiraiExperimentalAPI("未支持") abstract suspend fun approveFriendAddRequest(id: Long, remark: String?) // endregion @@ -252,12 +285,60 @@ abstract class Bot : CoroutineScope { /** * 需要调用者自行 close [output] */ + @MiraiExperimentalAPI("未支持") suspend inline fun Image.downloadTo(output: OutputStream) = download().use { input -> input.transferTo(output) } // endregion } +/** + * 撤回这条消息. + * 根据 [message] 内的 [MessageSource] 进行相关判断. + * + * [Bot] 撤回自己的消息不需要权限. + * [Bot] 撤回群员的消息需要管理员权限. + * + * @throws PermissionDeniedException 当 [Bot] 无权限操作时 + * @see Bot.recall + */ +@MiraiExperimentalAPI +suspend inline fun Bot.recall(message: MessageChain) = this.recall(message[MessageSource]) + +/** + * 在一段时间后撤回这条消息. + * 将根据 [MessageSource.groupId] 判断消息是群消息还是好友消息. + * + * @param millis 延迟的时间, 单位为毫秒 + * @param coroutineContext 额外的 [CoroutineContext] + * @see recall + */ +fun Bot.recallIn( + source: MessageSource, + millis: Long, + coroutineContext: CoroutineContext = EmptyCoroutineContext +): Job = this.launch(coroutineContext + CoroutineName("MessageRecall")) { + kotlinx.coroutines.delay(millis) + recall(source) +} + +/** + * 在一段时间后撤回这条消息. + * + * @param millis 延迟的时间, 单位为毫秒 + * @param coroutineContext 额外的 [CoroutineContext] + * @see recall + */ +@MiraiExperimentalAPI +fun Bot.recallIn( + message: MessageChain, + millis: Long, + coroutineContext: CoroutineContext = EmptyCoroutineContext +): Job = this.launch(coroutineContext + CoroutineName("MessageRecall")) { + kotlinx.coroutines.delay(millis) + recall(message) +} + /** * 关闭这个 [Bot], 停止一切相关活动. 所有引用都会被释放. * diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt index 8b1c1ed42..9b36e5cae 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt @@ -11,10 +11,7 @@ package net.mamoe.mirai.contact -import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch import net.mamoe.mirai.Bot import net.mamoe.mirai.data.MemberInfo import net.mamoe.mirai.event.events.* @@ -22,10 +19,7 @@ import net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.data.MessageChain -import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.utils.MiraiExperimentalAPI -import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.EmptyCoroutineContext import kotlin.jvm.JvmName /** @@ -151,17 +145,6 @@ interface Group : Contact, CoroutineScope { @MiraiExperimentalAPI("还未支持") suspend fun quit(): Boolean - /** - * 撤回这条消息. - * - * [Bot] 撤回自己的消息不需要权限. - * [Bot] 撤回群员的消息需要管理员权限. - * - * @throws PermissionDeniedException 当 [Bot] 无权限操作时 - * @see Group.recall (扩展函数) 接受参数 [MessageChain] - */ - suspend fun recall(source: MessageSource) - /** * 构造一个 [Member]. * 非特殊情况请不要使用这个函数. 优先使用 [get]. @@ -226,49 +209,6 @@ interface Group : Contact, CoroutineScope { fun toFullString(): String = "Group(id=${this.id}, name=$name, owner=${owner.id}, members=${members.idContentString})" } -/** - * 撤回这条消息. - * - * [Bot] 撤回自己的消息不需要权限. - * [Bot] 撤回群员的消息需要管理员权限. - * - * @throws PermissionDeniedException 当 [Bot] 无权限操作时 - * @see Group.recall - */ -suspend inline fun Group.recall(message: MessageChain) = this.recall(message[MessageSource]) - -/** - * 在一段时间后撤回这条消息. - * - * @param millis 延迟的时间, 单位为毫秒 - * @param coroutineContext 额外的 [CoroutineContext] - * @see recall - */ -fun Group.recallIn( - message: MessageSource, - millis: Long, - coroutineContext: CoroutineContext = EmptyCoroutineContext -): Job = this.launch(coroutineContext + CoroutineName("MessageRecall")) { - kotlinx.coroutines.delay(millis) - recall(message) -} - -/** - * 在一段时间后撤回这条消息. - * - * @param millis 延迟的时间, 单位为毫秒 - * @param coroutineContext 额外的 [CoroutineContext] - * @see recall - */ -fun Group.recallIn( - message: MessageChain, - millis: Long, - coroutineContext: CoroutineContext = EmptyCoroutineContext -): Job = this.launch(coroutineContext + CoroutineName("MessageRecall")) { - kotlinx.coroutines.delay(millis) - recall(message) -} - /** * 返回机器人是否正在被禁言 *