Reject sending FileMessage (#1657)

* Reject sending `FileMessage`

* Update docs

* Update mirai-core-api/src/commonMain/kotlin/contact/file/AbsoluteFile.kt

Co-authored-by: Him188 <Him188@mamoe.net>

Co-authored-by: Him188 <Him188@mamoe.net>
This commit is contained in:
Karlatemp 2021-11-07 18:55:02 +08:00 committed by GitHub
parent 76d23c5b0c
commit fa364b4b45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 37 additions and 10 deletions

View File

@ -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

View File

@ -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] 的使用是稳定的, 但自行实现不稳定.

View File

@ -337,7 +337,7 @@ public interface RemoteFile {
public suspend fun listFilesCollection(): List<RemoteFile> = listFiles().toList()
/**
* 得到相应文件消息, 可以发送. [RemoteFile] 表示一个目录或文件不存在时返回 `null`.
* 得到相应文件消息. [RemoteFile] 表示一个目录或文件不存在时返回 `null`.
*/
public suspend fun toMessage(): FileMessage?

View File

@ -331,6 +331,7 @@ private suspend fun <C : Contact> SendMessageHandler<C>.sendMessageImpl(
transformedMessage: MessageChain,
step: SendMessageStep,
): MessageReceipt<C> { // Result cannot be in interface.
transformedMessage.verifySendingValid()
val chain = transformedMessage.convertToLongMessageIfNeeded(step)
chain.findIsInstance<QuoteReply>()?.source?.ensureSequenceIdAvailable()

View File

@ -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 })
}

View File

@ -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 {

View File

@ -41,6 +41,15 @@ internal object IgnoreLengthCheck : MessageMetadata, ConstrainSingle, InternalFl
override fun toString(): String = ""
}
/**
* 代表来自 mirai 内部
*/
internal object MiraiInternalMessageFlag : MessageMetadata, ConstrainSingle, InternalFlagOnlyMessage,
AbstractMessageKey<MiraiInternalMessageFlag>({ it.safeCast() }) {
override val key: MessageKey<MiraiInternalMessageFlag> get() = this
override fun toString(): String = ""
}
/**
* Ignore on transformation
*/

View File

@ -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<Contact> {
@Suppress("DEPRECATION")
return upload(resource).sendTo(contact)
return contact.sendMessage(upload(resource) + MiraiInternalMessageFlag)
}
// compiler bug