diff --git a/mirai-core-api/src/commonMain/kotlin/contact/file/AbsoluteFile.kt b/mirai-core-api/src/commonMain/kotlin/contact/file/AbsoluteFile.kt index fe3a9bbb5..50bb566b1 100644 --- a/mirai-core-api/src/commonMain/kotlin/contact/file/AbsoluteFile.kt +++ b/mirai-core-api/src/commonMain/kotlin/contact/file/AbsoluteFile.kt @@ -65,9 +65,9 @@ public interface AbsoluteFile : AbsoluteFileFolder { public suspend fun getUrl(): String? /** - * 得到表示远程文件的可以发送的 [FileMessage]. + * 得到 [AbsoluteFile] 所对应的 [FileMessage]. * - * 在 [上传文件][RemoteFiles.uploadNewFile] 时就已经发送了文件消息. [toMessage] 可供之后再次发送使用. + * 注: 在 [上传文件][RemoteFiles.uploadNewFile] 时就已经发送了文件消息, [FileMessage] 不可手动发送 */ public fun toMessage(): FileMessage diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/FileMessage.kt b/mirai-core-api/src/commonMain/kotlin/message/data/FileMessage.kt index 91a440d13..a42bd0b7b 100644 --- a/mirai-core-api/src/commonMain/kotlin/message/data/FileMessage.kt +++ b/mirai-core-api/src/commonMain/kotlin/message/data/FileMessage.kt @@ -30,10 +30,12 @@ import net.mamoe.mirai.utils.* * * [name] 与 [size] 只供本地使用, 发送消息时只会使用 [id] 和 [internalId]. * - * ### 文件操作 - * 要下载这个文件, 可通过 [toRemoteFile] 获取到 [RemoteFile] 然后操作. + * 注: [FileMessage] 不可二次发送 * - * 要获取到 [FileMessage], 可以通过 [MessageEvent.message] 获取, 或通过 [RemoteFile.upload] 上传. + * ### 文件操作 + * 要下载这个文件, 可通过 [toAbsoluteFile] 获取到 [AbsoluteFile] 然后操作. + * + * 要获取到 [FileMessage], 可以通过 [MessageEvent.message] 获取, 或通过 [AbsoluteFile.toMessage] 得到. * * @since 2.5 * @suppress [FileMessage] 的使用是稳定的, 但自行实现不稳定. diff --git a/mirai-core-api/src/commonMain/kotlin/utils/RemoteFile.kt b/mirai-core-api/src/commonMain/kotlin/utils/RemoteFile.kt index 572597499..39114f386 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/RemoteFile.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/RemoteFile.kt @@ -337,7 +337,7 @@ public interface RemoteFile { public suspend fun listFilesCollection(): List = listFiles().toList() /** - * 得到相应文件消息, 可以发送. 当 [RemoteFile] 表示一个目录或文件不存在时返回 `null`. + * 得到相应文件消息. 当 [RemoteFile] 表示一个目录或文件不存在时返回 `null`. */ public suspend fun toMessage(): FileMessage? diff --git a/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt b/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt index f65a2c1fc..d8c228fb2 100644 --- a/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt +++ b/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt @@ -331,6 +331,7 @@ private suspend fun SendMessageHandler.sendMessageImpl( transformedMessage: MessageChain, step: SendMessageStep, ): MessageReceipt { // Result cannot be in interface. + transformedMessage.verifySendingValid() val chain = transformedMessage.convertToLongMessageIfNeeded(step) chain.findIsInstance()?.source?.ensureSequenceIdAvailable() diff --git a/mirai-core/src/commonMain/kotlin/contact/file/AbsoluteFolderImpl.kt b/mirai-core/src/commonMain/kotlin/contact/file/AbsoluteFolderImpl.kt index b478f2ce9..3ab2f3afd 100644 --- a/mirai-core/src/commonMain/kotlin/contact/file/AbsoluteFolderImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/file/AbsoluteFolderImpl.kt @@ -18,6 +18,7 @@ import net.mamoe.mirai.contact.file.AbsoluteFolder import net.mamoe.mirai.contact.isOperator import net.mamoe.mirai.internal.contact.GroupImpl import net.mamoe.mirai.internal.contact.file.RemoteFilesImpl.Companion.findFileByPath +import net.mamoe.mirai.internal.message.MiraiInternalMessageFlag import net.mamoe.mirai.internal.network.QQAndroidClient import net.mamoe.mirai.internal.network.components.ClockHolder.Companion.clock import net.mamoe.mirai.internal.network.highway.Highway @@ -171,7 +172,7 @@ internal class AbsoluteFolderImpl( // 当为 true 时跳过上传, 但仍然需要完成 `sendMessage(FileMessage)` 才是正常逻辑 callback?.onBegin(file, content) val result = kotlin.runCatching { - folder.contact.sendMessage(file.toMessage()) + folder.contact.sendMessage(file.toMessage() + MiraiInternalMessageFlag) }.map { content.size } callback?.onFinished(file, content, result) return file @@ -235,7 +236,7 @@ internal class AbsoluteFolderImpl( ) }.let { result0 -> val result = result0.onSuccessCatching { - folder.contact.sendMessage(file.toMessage()) + folder.contact.sendMessage(file.toMessage() + MiraiInternalMessageFlag) } callback?.onFinished(file, content, result.map { content.size }) } diff --git a/mirai-core/src/commonMain/kotlin/contact/util.kt b/mirai-core/src/commonMain/kotlin/contact/util.kt index 2f9a8793c..3d0f24540 100644 --- a/mirai-core/src/commonMain/kotlin/contact/util.kt +++ b/mirai-core/src/commonMain/kotlin/contact/util.kt @@ -14,6 +14,7 @@ package net.mamoe.mirai.internal.contact import net.mamoe.mirai.Bot import net.mamoe.mirai.contact.* import net.mamoe.mirai.internal.message.LongMessageInternal +import net.mamoe.mirai.internal.message.MiraiInternalMessageFlag import net.mamoe.mirai.internal.utils.estimateLength import net.mamoe.mirai.message.data.* import net.mamoe.mirai.utils.cast @@ -33,6 +34,19 @@ internal fun Contact.logMessageSent(message: Message) { internal fun MessageChain.countImages(): Int = this.count { it is Image } +internal fun Message.verifySendingValid() { + fun fail(msg: String): Nothing = throw IllegalArgumentException(msg) + when (this) { + is MessageChain -> { + if (contains(MiraiInternalMessageFlag)) { + return + } + this.forEach { it.verifySendingValid() } + } + is FileMessage -> fail("Sending FileMessage is not in support") + } +} + internal fun MessageChain.verifyLength( originalMessage: Message, target: Contact, ): Int { diff --git a/mirai-core/src/commonMain/kotlin/message/ForceAsLongMessage.kt b/mirai-core/src/commonMain/kotlin/message/ForceAsLongMessage.kt index f8f426917..d78794359 100644 --- a/mirai-core/src/commonMain/kotlin/message/ForceAsLongMessage.kt +++ b/mirai-core/src/commonMain/kotlin/message/ForceAsLongMessage.kt @@ -41,6 +41,15 @@ internal object IgnoreLengthCheck : MessageMetadata, ConstrainSingle, InternalFl override fun toString(): String = "" } +/** + * 代表来自 mirai 内部 + */ +internal object MiraiInternalMessageFlag : MessageMetadata, ConstrainSingle, InternalFlagOnlyMessage, + AbstractMessageKey({ it.safeCast() }) { + override val key: MessageKey get() = this + override fun toString(): String = "" +} + /** * Ignore on transformation */ diff --git a/mirai-core/src/commonMain/kotlin/utils/RemoteFileImpl.kt b/mirai-core/src/commonMain/kotlin/utils/RemoteFileImpl.kt index a7b779400..bff53a6dc 100644 --- a/mirai-core/src/commonMain/kotlin/utils/RemoteFileImpl.kt +++ b/mirai-core/src/commonMain/kotlin/utils/RemoteFileImpl.kt @@ -19,6 +19,7 @@ import net.mamoe.mirai.contact.isOperator import net.mamoe.mirai.internal.asQQAndroidBot import net.mamoe.mirai.internal.contact.groupCode import net.mamoe.mirai.internal.message.FileMessageImpl +import net.mamoe.mirai.internal.message.MiraiInternalMessageFlag import net.mamoe.mirai.internal.network.highway.Highway import net.mamoe.mirai.internal.network.highway.ResourceKind import net.mamoe.mirai.internal.network.protocol @@ -29,7 +30,6 @@ import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect import net.mamoe.mirai.internal.utils.io.serialization.toByteArray import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.data.FileMessage -import net.mamoe.mirai.message.data.sendTo import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource import net.mamoe.mirai.utils.RemoteFile.Companion.ROOT_PATH @@ -560,7 +560,7 @@ internal class RemoteFileImpl( override suspend fun uploadAndSend(resource: ExternalResource): MessageReceipt { @Suppress("DEPRECATION") - return upload(resource).sendTo(contact) + return contact.sendMessage(upload(resource) + MiraiInternalMessageFlag) } // compiler bug