mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-06 23:16:55 +08:00
Implement MessagePreSendEvent
and MessagePostSendEvent
.
Deprecate `MessageSendEvent` Fix #339
This commit is contained in:
parent
4c79d4cd18
commit
6f0853e6e4
@ -33,6 +33,7 @@ import net.mamoe.mirai.event.events.ImageUploadEvent
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.OfflineFriendImage
|
||||
import net.mamoe.mirai.message.data.isContentNotEmpty
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.network.highway.postImage
|
||||
@ -87,7 +88,11 @@ internal class FriendImpl(
|
||||
@Suppress("DuplicatedCode")
|
||||
override suspend fun sendMessage(message: Message): MessageReceipt<Friend> {
|
||||
require(message.isContentNotEmpty()) { "message is empty" }
|
||||
return sendMessageImpl(this, message).also {
|
||||
return sendMessageImpl(
|
||||
message,
|
||||
friendReceiptConstructor = { MessageReceipt(it, this, null) },
|
||||
tReceiptConstructor = { MessageReceipt(it, this, null) }
|
||||
).also {
|
||||
logMessageSent(message)
|
||||
}
|
||||
}
|
||||
@ -101,64 +106,63 @@ internal class FriendImpl(
|
||||
if (BeforeImageUploadEvent(this, image).broadcast().isCancelled) {
|
||||
throw EventCancelledException("cancelled by BeforeImageUploadEvent.ToGroup")
|
||||
}
|
||||
bot.network.run {
|
||||
val response = LongConn.OffPicUp(
|
||||
val response = bot.network.run {
|
||||
LongConn.OffPicUp(
|
||||
bot.client, Cmd0x352.TryUpImgReq(
|
||||
srcUin = bot.id.toInt(),
|
||||
dstUin = id.toInt(),
|
||||
fileId = 0,
|
||||
fileMd5 = @Suppress("INVISIBLE_MEMBER") image.md5,
|
||||
fileSize = @Suppress("INVISIBLE_MEMBER")
|
||||
image.input.size.toInt(),
|
||||
fileName = @Suppress("INVISIBLE_MEMBER") image.md5.toUHexString("") + "." + ExternalImage.defaultFormatName,
|
||||
fileMd5 = image.md5,
|
||||
fileSize = image.input.size.toInt(),
|
||||
fileName = image.md5.toUHexString("") + "." + ExternalImage.defaultFormatName,
|
||||
imgOriginal = 1
|
||||
)
|
||||
).sendAndExpect<LongConn.OffPicUp.Response>()
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "DEPRECATION", "INVISIBLE_MEMBER")
|
||||
return when (response) {
|
||||
is LongConn.OffPicUp.Response.FileExists -> net.mamoe.mirai.message.data.OfflineFriendImage(response.resourceId)
|
||||
.also {
|
||||
ImageUploadEvent.Succeed(this@FriendImpl, image, it).broadcast()
|
||||
}
|
||||
is LongConn.OffPicUp.Response.RequireUpload -> {
|
||||
bot.network.logger.verbose {
|
||||
"[Http] Uploading friend image, size=${image.input.size.sizeToString()}"
|
||||
}
|
||||
|
||||
val time = measureTime {
|
||||
MiraiPlatformUtils.Http.postImage(
|
||||
"0x6ff0070",
|
||||
bot.id,
|
||||
null,
|
||||
imageInput = image.input,
|
||||
uKeyHex = response.uKey.toUHexString("")
|
||||
)
|
||||
}
|
||||
|
||||
bot.network.logger.verbose {
|
||||
"[Http] Uploading friend image: succeed at ${(image.input.size.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
|
||||
}
|
||||
|
||||
/*
|
||||
HighwayHelper.uploadImageToServers(
|
||||
bot,
|
||||
response.serverIp.zip(response.serverPort),
|
||||
response.uKey,
|
||||
image,
|
||||
kind = "friend",
|
||||
commandId = 1
|
||||
)*/
|
||||
// 为什么不能 ??
|
||||
|
||||
return net.mamoe.mirai.message.data.OfflineFriendImage(response.resourceId).also {
|
||||
ImageUploadEvent.Succeed(this@FriendImpl, image, it).broadcast()
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST", "DEPRECATION")
|
||||
when (response) {
|
||||
is LongConn.OffPicUp.Response.FileExists -> OfflineFriendImage(response.resourceId)
|
||||
.also {
|
||||
ImageUploadEvent.Succeed(this@FriendImpl, image, it).broadcast()
|
||||
}
|
||||
is LongConn.OffPicUp.Response.Failed -> {
|
||||
ImageUploadEvent.Failed(this@FriendImpl, image, -1, response.message).broadcast()
|
||||
error(response.message)
|
||||
is LongConn.OffPicUp.Response.RequireUpload -> {
|
||||
bot.network.logger.verbose {
|
||||
"[Http] Uploading friend image, size=${image.input.size.sizeToString()}"
|
||||
}
|
||||
|
||||
val time = measureTime {
|
||||
MiraiPlatformUtils.Http.postImage(
|
||||
"0x6ff0070",
|
||||
bot.id,
|
||||
null,
|
||||
imageInput = image.input,
|
||||
uKeyHex = response.uKey.toUHexString("")
|
||||
)
|
||||
}
|
||||
|
||||
bot.network.logger.verbose {
|
||||
"[Http] Uploading friend image: succeed at ${(image.input.size.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
|
||||
}
|
||||
|
||||
/*
|
||||
HighwayHelper.uploadImageToServers(
|
||||
bot,
|
||||
response.serverIp.zip(response.serverPort),
|
||||
response.uKey,
|
||||
image,
|
||||
kind = "friend",
|
||||
commandId = 1
|
||||
)*/
|
||||
// 为什么不能 ??
|
||||
|
||||
OfflineFriendImage(response.resourceId).also {
|
||||
ImageUploadEvent.Succeed(this@FriendImpl, image, it).broadcast()
|
||||
}
|
||||
}
|
||||
is LongConn.OffPicUp.Response.Failed -> {
|
||||
ImageUploadEvent.Failed(this@FriendImpl, image, -1, response.message).broadcast()
|
||||
error(response.message)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
@ -22,7 +22,6 @@ import net.mamoe.mirai.data.GroupInfo
|
||||
import net.mamoe.mirai.data.MemberInfo
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.event.events.*
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
@ -33,6 +32,7 @@ import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
|
||||
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.receive.MessageSvcPbSendMsg
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToGroup
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
|
||||
import net.mamoe.mirai.qqandroid.utils.estimateLength
|
||||
import net.mamoe.mirai.utils.*
|
||||
@ -304,94 +304,92 @@ internal class GroupImpl(
|
||||
check(message.nodeList.size < 200) {
|
||||
throw MessageTooLargeException(
|
||||
this, message, message,
|
||||
"ForwardMessage allows up to 200 nodes, but found ${message.nodeList.size}")
|
||||
"ForwardMessage allows up to 200 nodes, but found ${message.nodeList.size}"
|
||||
)
|
||||
}
|
||||
|
||||
return bot.lowLevelSendGroupLongOrForwardMessage(this.id, message.nodeList, false, message)
|
||||
}
|
||||
|
||||
val msg: MessageChain
|
||||
val msg: MessageChain = if (message !is LongMessage && message !is ForwardMessageInternal) {
|
||||
val chain = kotlin.runCatching {
|
||||
GroupMessagePreSendEvent(this, message).broadcast()
|
||||
}.onSuccess {
|
||||
check(!it.isCancelled) {
|
||||
throw EventCancelledException("cancelled by GroupMessagePreSendEvent")
|
||||
}
|
||||
}.getOrElse {
|
||||
throw EventCancelledException("exception thrown when broadcasting GroupMessagePreSendEvent", it)
|
||||
}.message.asMessageChain()
|
||||
|
||||
if (message !is LongMessage && message !is ForwardMessageInternal) {
|
||||
val event = GroupMessageSendEvent(this, message.asMessageChain()).broadcast()
|
||||
if (event.isCancelled) {
|
||||
throw EventCancelledException("cancelled by GroupMessageSendEvent")
|
||||
}
|
||||
|
||||
val length = event.message.estimateLength(703) // 阈值为700左右,限制到3的倍数
|
||||
val length = chain.estimateLength(703) // 阈值为700左右,限制到3的倍数
|
||||
var imageCnt = 0 // 通过下方逻辑短路延迟计算
|
||||
|
||||
if (length > 5000 || event.message.count { it is Image }.apply { imageCnt = this } > 50) {
|
||||
if (length > 5000 || chain.count { it is Image }.apply { imageCnt = this } > 50) {
|
||||
throw MessageTooLargeException(
|
||||
this,
|
||||
message,
|
||||
event.message,
|
||||
"message(${event.message.joinToString(
|
||||
"",
|
||||
limit = 10
|
||||
)}) is too large. Allow up to 50 images or 5000 chars"
|
||||
this, message, chain,
|
||||
"message(${chain.joinToString("", limit = 10)}) is too large. Allow up to 50 images or 5000 chars"
|
||||
)
|
||||
}
|
||||
|
||||
if (length > 702 || imageCnt > 2) {
|
||||
return bot.lowLevelSendGroupLongOrForwardMessage(this.id,
|
||||
listOf(ForwardMessage.Node(
|
||||
senderId = bot.id,
|
||||
time = currentTimeSeconds.toInt(),
|
||||
message = event.message,
|
||||
senderName = bot.nick)
|
||||
return bot.lowLevelSendGroupLongOrForwardMessage(
|
||||
this.id,
|
||||
listOf(
|
||||
ForwardMessage.Node(
|
||||
senderId = bot.id,
|
||||
time = currentTimeSeconds.toInt(),
|
||||
message = chain,
|
||||
senderName = bot.nick
|
||||
)
|
||||
),
|
||||
true, null)
|
||||
true, null
|
||||
)
|
||||
}
|
||||
chain
|
||||
} else message.asMessageChain()
|
||||
|
||||
msg = event.message
|
||||
} else msg = message.asMessageChain()
|
||||
msg.firstIsInstanceOrNull<QuoteReply>()?.source?.ensureSequenceIdAvailable()
|
||||
|
||||
lateinit var source: MessageSourceToGroupImpl
|
||||
bot.network.run {
|
||||
val response: MessageSvcPbSendMsg.Response = MessageSvcPbSendMsg.createToGroup(
|
||||
|
||||
val result = bot.network.runCatching {
|
||||
val source: MessageSourceToGroupImpl
|
||||
MessageSvcPbSendMsg.createToGroup(
|
||||
bot.client,
|
||||
this@GroupImpl,
|
||||
msg,
|
||||
isForward
|
||||
) {
|
||||
source = it
|
||||
}.sendAndExpect()
|
||||
if (response is MessageSvcPbSendMsg.Response.Failed) {
|
||||
when (response.resultType) {
|
||||
120 -> throw BotIsBeingMutedException(this@GroupImpl)
|
||||
34 -> {
|
||||
kotlin.runCatching { // allow retry once
|
||||
return bot.lowLevelSendGroupLongOrForwardMessage(
|
||||
id, listOf(
|
||||
ForwardMessage.Node(
|
||||
senderId = bot.id,
|
||||
time = currentTimeSeconds.toInt(),
|
||||
message = msg,
|
||||
senderName = bot.nick
|
||||
)
|
||||
), true, null)
|
||||
}.getOrElse {
|
||||
throw IllegalStateException("internal error: send message failed(34)", it)
|
||||
}
|
||||
}
|
||||
else -> error("send message failed: $response")
|
||||
}.sendAndExpect<MessageSvcPbSendMsg.Response>().let {
|
||||
check(it is MessageSvcPbSendMsg.Response.SUCCESS) {
|
||||
"Send temp message failed: $it"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
source.ensureSequenceIdAvailable()
|
||||
} catch (e: Exception) {
|
||||
bot.network.logger.warning {
|
||||
"Timeout awaiting sequenceId for group message(${message.contentToString()
|
||||
.take(10)}). Some features may not work properly"
|
||||
try {
|
||||
source.ensureSequenceIdAvailable()
|
||||
} catch (e: Exception) {
|
||||
bot.network.logger.warning {
|
||||
"Timeout awaiting sequenceId for group message(${message.contentToString()
|
||||
.take(10)}). Some features may not work properly"
|
||||
}
|
||||
bot.network.logger.warning(e)
|
||||
}
|
||||
bot.network.logger.warning(e)
|
||||
|
||||
MessageReceipt(source, this@GroupImpl, botAsMember)
|
||||
}
|
||||
|
||||
return MessageReceipt(source, this, botAsMember)
|
||||
result.fold(
|
||||
onSuccess = {
|
||||
GroupMessagePostSendEvent(this, msg, null, it)
|
||||
},
|
||||
onFailure = {
|
||||
GroupMessagePostSendEvent(this, msg, it, null)
|
||||
}
|
||||
).broadcast()
|
||||
|
||||
return result.getOrThrow()
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
|
@ -28,6 +28,7 @@ import net.mamoe.mirai.qqandroid.message.firstIsInstanceOrNull
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.StTroopMemberInfo
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToTemp
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
import net.mamoe.mirai.utils.getValue
|
||||
@ -54,34 +55,59 @@ internal class MemberImpl constructor(
|
||||
override val id: Long = qq.id
|
||||
override val nick: String = qq.nick
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@JvmSynthetic
|
||||
override suspend fun sendMessage(message: Message): MessageReceipt<Member> {
|
||||
require(message.isContentNotEmpty()) { "message is empty" }
|
||||
|
||||
return (this.asFriendOrNull()?.sendMessageImpl(this, message) ?: sendMessageImpl(message))
|
||||
.also { logMessageSent(message) }
|
||||
val asFriend = this.asFriendOrNull()
|
||||
|
||||
return (asFriend?.sendMessageImpl(
|
||||
message,
|
||||
friendReceiptConstructor = { MessageReceipt(it, asFriend, null) },
|
||||
tReceiptConstructor = { MessageReceipt(it, this, null) }
|
||||
) ?: sendMessageImpl(message)).also { logMessageSent(message) }
|
||||
}
|
||||
|
||||
private suspend fun sendMessageImpl(message: Message): MessageReceipt<Member> {
|
||||
val event = MessageSendEvent.TempMessageSendEvent(this, message.asMessageChain()).broadcast()
|
||||
if (event.isCancelled) {
|
||||
throw EventCancelledException("cancelled by TempMessageSendEvent")
|
||||
}
|
||||
event.message.firstIsInstanceOrNull<QuoteReply>()?.source?.ensureSequenceIdAvailable()
|
||||
val chain = kotlin.runCatching {
|
||||
TempMessagePreSendEvent(this, message).broadcast()
|
||||
}.onSuccess {
|
||||
check(!it.isCancelled) {
|
||||
throw EventCancelledException("cancelled by TempMessagePreSendEvent")
|
||||
}
|
||||
}.getOrElse {
|
||||
throw EventCancelledException("exception thrown when broadcasting TempMessagePreSendEvent", it)
|
||||
}.message.asMessageChain()
|
||||
|
||||
lateinit var source: MessageSourceToTempImpl
|
||||
bot.network.run {
|
||||
check(
|
||||
MessageSvcPbSendMsg.createToTemp(
|
||||
bot.client,
|
||||
this@MemberImpl,
|
||||
message.asMessageChain()
|
||||
) {
|
||||
source = it
|
||||
}.sendAndExpect<MessageSvcPbSendMsg.Response>() is MessageSvcPbSendMsg.Response.SUCCESS
|
||||
) { "send message failed" }
|
||||
chain.firstIsInstanceOrNull<QuoteReply>()?.source?.ensureSequenceIdAvailable()
|
||||
|
||||
val result = bot.network.runCatching {
|
||||
val source: MessageSourceToTempImpl
|
||||
MessageSvcPbSendMsg.createToTemp(
|
||||
bot.client,
|
||||
this@MemberImpl,
|
||||
chain
|
||||
) {
|
||||
source = it
|
||||
}.sendAndExpect<MessageSvcPbSendMsg.Response>().let {
|
||||
check(it is MessageSvcPbSendMsg.Response.SUCCESS) {
|
||||
"Send temp message failed: $it"
|
||||
}
|
||||
}
|
||||
MessageReceipt(source, this@MemberImpl, null)
|
||||
}
|
||||
return MessageReceipt(source, this, null)
|
||||
|
||||
result.fold(
|
||||
onSuccess = {
|
||||
TempMessagePostSendEvent(this, chain, null, it)
|
||||
},
|
||||
onFailure = {
|
||||
TempMessagePostSendEvent(this, chain, it, null)
|
||||
}
|
||||
).broadcast()
|
||||
|
||||
return result.getOrThrow()
|
||||
}
|
||||
|
||||
@JvmSynthetic
|
||||
|
@ -12,40 +12,72 @@ package net.mamoe.mirai.qqandroid.contact
|
||||
|
||||
import net.mamoe.mirai.contact.Contact
|
||||
import net.mamoe.mirai.contact.Friend
|
||||
import net.mamoe.mirai.contact.User
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.event.events.EventCancelledException
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent
|
||||
import net.mamoe.mirai.event.events.FriendMessagePostSendEvent
|
||||
import net.mamoe.mirai.event.events.FriendMessagePreSendEvent
|
||||
import net.mamoe.mirai.message.*
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.QuoteReply
|
||||
import net.mamoe.mirai.message.data.asMessageChain
|
||||
import net.mamoe.mirai.message.data.firstIsInstanceOrNull
|
||||
import net.mamoe.mirai.qqandroid.asQQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.message.MessageSourceToFriendImpl
|
||||
import net.mamoe.mirai.qqandroid.message.ensureSequenceIdAvailable
|
||||
import net.mamoe.mirai.qqandroid.message.firstIsInstanceOrNull
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToFriend
|
||||
import net.mamoe.mirai.utils.verbose
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
internal suspend fun <T : Contact> Friend.sendMessageImpl(generic: T, message: Message): MessageReceipt<T> {
|
||||
val event = MessageSendEvent.FriendMessageSendEvent(this, message.asMessageChain()).broadcast()
|
||||
if (event.isCancelled) {
|
||||
throw EventCancelledException("cancelled by FriendMessageSendEvent")
|
||||
}
|
||||
event.message.firstIsInstanceOrNull<QuoteReply>()?.source?.ensureSequenceIdAvailable()
|
||||
lateinit var source: MessageSourceToFriendImpl
|
||||
internal suspend fun <T : User> Friend.sendMessageImpl(
|
||||
message: Message,
|
||||
friendReceiptConstructor: (MessageSourceToFriendImpl) -> MessageReceipt<Friend>,
|
||||
tReceiptConstructor: (MessageSourceToFriendImpl) -> MessageReceipt<T>
|
||||
): MessageReceipt<T> {
|
||||
contract { callsInPlace(friendReceiptConstructor, InvocationKind.EXACTLY_ONCE) }
|
||||
val bot = bot.asQQAndroidBot()
|
||||
bot.network.run {
|
||||
check(
|
||||
MessageSvcPbSendMsg.createToFriend(
|
||||
bot.asQQAndroidBot().client,
|
||||
this@sendMessageImpl,
|
||||
event.message
|
||||
) {
|
||||
source = it
|
||||
}.sendAndExpect<MessageSvcPbSendMsg.Response>() is MessageSvcPbSendMsg.Response.SUCCESS
|
||||
) { "send message failed" }
|
||||
|
||||
val chain = kotlin.runCatching {
|
||||
FriendMessagePreSendEvent(this, message).broadcast()
|
||||
}.onSuccess {
|
||||
check(!it.isCancelled) {
|
||||
throw EventCancelledException("cancelled by FriendMessagePreSendEvent")
|
||||
}
|
||||
}.getOrElse {
|
||||
throw EventCancelledException("exception thrown when broadcasting FriendMessagePreSendEvent", it)
|
||||
}.message.asMessageChain()
|
||||
|
||||
chain.firstIsInstanceOrNull<QuoteReply>()?.source?.ensureSequenceIdAvailable()
|
||||
|
||||
lateinit var source: MessageSourceToFriendImpl
|
||||
val result = bot.network.runCatching {
|
||||
MessageSvcPbSendMsg.createToFriend(
|
||||
bot.client,
|
||||
this@sendMessageImpl,
|
||||
chain
|
||||
) {
|
||||
source = it
|
||||
}.sendAndExpect<MessageSvcPbSendMsg.Response>().let {
|
||||
check(it is MessageSvcPbSendMsg.Response.SUCCESS) {
|
||||
"Send temp message failed: $it"
|
||||
}
|
||||
}
|
||||
friendReceiptConstructor(source)
|
||||
}
|
||||
return MessageReceipt(source, generic, null)
|
||||
|
||||
result.fold(
|
||||
onSuccess = {
|
||||
FriendMessagePostSendEvent(this, chain, null, it)
|
||||
},
|
||||
onFailure = {
|
||||
FriendMessagePostSendEvent(this, chain, it, null)
|
||||
}
|
||||
).broadcast()
|
||||
|
||||
result.getOrThrow()
|
||||
return tReceiptConstructor(source)
|
||||
}
|
||||
|
||||
internal fun Contact.logMessageSent(message: Message) {
|
||||
|
@ -34,6 +34,8 @@ import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -52,34 +54,11 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
|
||||
}
|
||||
}
|
||||
|
||||
inline fun createToFriend(
|
||||
client: QQAndroidClient,
|
||||
qq: Friend,
|
||||
message: MessageChain,
|
||||
crossinline sourceCallback: (MessageSourceToFriendImpl) -> Unit
|
||||
): OutgoingPacket {
|
||||
val rand = Random.nextInt().absoluteValue
|
||||
val source = MessageSourceToFriendImpl(
|
||||
internalId = rand,
|
||||
sender = client.bot,
|
||||
target = qq,
|
||||
time = currentTimeSeconds.toInt(),
|
||||
sequenceId = client.nextFriendSeq(),
|
||||
originalMessage = message
|
||||
)
|
||||
sourceCallback(source)
|
||||
return createToFriend(
|
||||
client,
|
||||
qq.id,
|
||||
message,
|
||||
source)
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送好友消息
|
||||
*/
|
||||
@Suppress("FunctionName")
|
||||
private fun createToFriend(
|
||||
internal fun createToFriendImpl(
|
||||
client: QQAndroidClient,
|
||||
toUin: Long,
|
||||
message: MessageChain,
|
||||
@ -106,33 +85,10 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
|
||||
}
|
||||
|
||||
|
||||
inline fun createToTemp(
|
||||
client: QQAndroidClient,
|
||||
member: Member,
|
||||
message: MessageChain,
|
||||
sourceCallback: (MessageSourceToTempImpl) -> Unit
|
||||
): OutgoingPacket {
|
||||
val source = MessageSourceToTempImpl(
|
||||
internalId = Random.nextInt().absoluteValue,
|
||||
sender = client.bot,
|
||||
target = member,
|
||||
time = currentTimeSeconds.toInt(),
|
||||
sequenceId = client.atomicNextMessageSequenceId(),
|
||||
originalMessage = message
|
||||
)
|
||||
sourceCallback(source)
|
||||
return createToTemp(
|
||||
client,
|
||||
(member.group as GroupImpl).uin,
|
||||
member.id,
|
||||
message,
|
||||
source)
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送临时消息
|
||||
*/
|
||||
private fun createToTemp(
|
||||
internal fun createToTempImpl(
|
||||
client: QQAndroidClient,
|
||||
groupUin: Long,
|
||||
toUin: Long,
|
||||
@ -158,37 +114,11 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
|
||||
}
|
||||
|
||||
|
||||
inline fun createToGroup(
|
||||
client: QQAndroidClient,
|
||||
group: Group,
|
||||
message: MessageChain,
|
||||
isForward: Boolean,
|
||||
sourceCallback: (MessageSourceToGroupImpl) -> Unit
|
||||
): OutgoingPacket {
|
||||
|
||||
val source = MessageSourceToGroupImpl(
|
||||
group,
|
||||
internalId = Random.nextInt().absoluteValue,
|
||||
sender = client.bot,
|
||||
target = group,
|
||||
time = currentTimeSeconds.toInt(),
|
||||
originalMessage = message//,
|
||||
// sourceMessage = message
|
||||
)
|
||||
sourceCallback(source)
|
||||
return createToGroup(
|
||||
client,
|
||||
group.id,
|
||||
message,
|
||||
isForward,
|
||||
source)
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送群消息
|
||||
*/
|
||||
@Suppress("FunctionName")
|
||||
private fun createToGroup(
|
||||
internal fun createToGroupImpl(
|
||||
client: QQAndroidClient,
|
||||
groupCode: Long,
|
||||
message: MessageChain,
|
||||
@ -231,7 +161,91 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
|
||||
Response.Failed(
|
||||
response.result,
|
||||
response.errtype,
|
||||
response.errmsg)
|
||||
response.errmsg
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun MessageSvcPbSendMsg.createToTemp(
|
||||
client: QQAndroidClient,
|
||||
member: Member,
|
||||
message: MessageChain,
|
||||
crossinline sourceCallback: (MessageSourceToTempImpl) -> Unit
|
||||
): OutgoingPacket {
|
||||
contract {
|
||||
callsInPlace(sourceCallback, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
val source = MessageSourceToTempImpl(
|
||||
internalId = Random.nextInt().absoluteValue,
|
||||
sender = client.bot,
|
||||
target = member,
|
||||
time = currentTimeSeconds.toInt(),
|
||||
sequenceId = client.atomicNextMessageSequenceId(),
|
||||
originalMessage = message
|
||||
)
|
||||
sourceCallback(source)
|
||||
return createToTempImpl(
|
||||
client,
|
||||
(member.group as GroupImpl).uin,
|
||||
member.id,
|
||||
message,
|
||||
source
|
||||
)
|
||||
}
|
||||
|
||||
internal inline fun MessageSvcPbSendMsg.createToFriend(
|
||||
client: QQAndroidClient,
|
||||
qq: Friend,
|
||||
message: MessageChain,
|
||||
crossinline sourceCallback: (MessageSourceToFriendImpl) -> Unit
|
||||
): OutgoingPacket {
|
||||
contract {
|
||||
callsInPlace(sourceCallback, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
val rand = Random.nextInt().absoluteValue
|
||||
val source = MessageSourceToFriendImpl(
|
||||
internalId = rand,
|
||||
sender = client.bot,
|
||||
target = qq,
|
||||
time = currentTimeSeconds.toInt(),
|
||||
sequenceId = client.nextFriendSeq(),
|
||||
originalMessage = message
|
||||
)
|
||||
sourceCallback(source)
|
||||
return createToFriendImpl(
|
||||
client,
|
||||
qq.id,
|
||||
message,
|
||||
source
|
||||
)
|
||||
}
|
||||
|
||||
internal inline fun MessageSvcPbSendMsg.createToGroup(
|
||||
client: QQAndroidClient,
|
||||
group: Group,
|
||||
message: MessageChain,
|
||||
isForward: Boolean,
|
||||
crossinline sourceCallback: (MessageSourceToGroupImpl) -> Unit
|
||||
): OutgoingPacket {
|
||||
contract {
|
||||
callsInPlace(sourceCallback, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
val source = MessageSourceToGroupImpl(
|
||||
group,
|
||||
internalId = Random.nextInt().absoluteValue,
|
||||
sender = client.bot,
|
||||
target = group,
|
||||
time = currentTimeSeconds.toInt(),
|
||||
originalMessage = message//,
|
||||
// sourceMessage = message
|
||||
)
|
||||
sourceCallback(source)
|
||||
return createToGroupImpl(
|
||||
client,
|
||||
group.id,
|
||||
message,
|
||||
isForward,
|
||||
source
|
||||
)
|
||||
}
|
@ -16,13 +16,11 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.JavaFriendlyAPI
|
||||
import net.mamoe.mirai.event.events.BeforeImageUploadEvent
|
||||
import net.mamoe.mirai.event.events.EventCancelledException
|
||||
import net.mamoe.mirai.event.events.ImageUploadEvent
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
|
||||
import net.mamoe.mirai.event.events.*
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.message.quote
|
||||
import net.mamoe.mirai.message.recall
|
||||
import net.mamoe.mirai.recall
|
||||
import net.mamoe.mirai.recallIn
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
@ -57,8 +55,8 @@ abstract class Contact : ContactOrBot, CoroutineScope, ContactJavaFriendlyAPI {
|
||||
*
|
||||
* 单条消息最大可发送 4500 字符或 50 张图片.
|
||||
*
|
||||
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
|
||||
* @see GroupMessageSendEvent 发送群消息事件. cancellable
|
||||
* @see MessagePreSendEvent 发送消息前事件
|
||||
* @see MessagePostSendEvent 发送消息后事件
|
||||
*
|
||||
* @throws EventCancelledException 当发送消息事件被取消时抛出
|
||||
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
|
||||
@ -71,7 +69,7 @@ abstract class Contact : ContactOrBot, CoroutineScope, ContactJavaFriendlyAPI {
|
||||
abstract suspend fun sendMessage(message: Message): MessageReceipt<Contact>
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "VIRTUAL_MEMBER_HIDDEN", "OVERRIDE_BY_INLINE")
|
||||
@kotlin.internal.InlineOnly // purely virtual
|
||||
@kotlin.internal.InlineOnly
|
||||
@JvmSynthetic
|
||||
suspend inline fun sendMessage(message: String): MessageReceipt<Contact> {
|
||||
return sendMessage(message.toMessage())
|
||||
|
@ -14,12 +14,14 @@ package net.mamoe.mirai.contact
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.event.events.EventCancelledException
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
|
||||
import net.mamoe.mirai.event.events.FriendMessagePostSendEvent
|
||||
import net.mamoe.mirai.event.events.FriendMessagePreSendEvent
|
||||
import net.mamoe.mirai.message.FriendMessageEvent
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.isContentEmpty
|
||||
import net.mamoe.mirai.message.data.toMessage
|
||||
import net.mamoe.mirai.message.recall
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
@ -55,8 +57,8 @@ abstract class Friend : User(), CoroutineScope {
|
||||
*
|
||||
* 单条消息最大可发送 4500 字符或 50 张图片.
|
||||
*
|
||||
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
|
||||
* @see GroupMessageSendEvent 发送群消息事件. cancellable
|
||||
* @see FriendMessagePreSendEvent 发送消息前事件
|
||||
* @see FriendMessagePostSendEvent 发送消息后事件
|
||||
*
|
||||
* @throws EventCancelledException 当发送消息事件被取消时抛出
|
||||
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
|
||||
@ -69,7 +71,7 @@ abstract class Friend : User(), CoroutineScope {
|
||||
abstract override suspend fun sendMessage(message: Message): MessageReceipt<Friend>
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "VIRTUAL_MEMBER_HIDDEN", "OVERRIDE_BY_INLINE")
|
||||
@kotlin.internal.InlineOnly // purely virtual
|
||||
@kotlin.internal.InlineOnly
|
||||
@JvmSynthetic
|
||||
suspend inline fun sendMessage(message: String): MessageReceipt<Friend> {
|
||||
return sendMessage(message.toMessage())
|
||||
|
@ -17,12 +17,12 @@ import net.mamoe.mirai.JavaFriendlyAPI
|
||||
import net.mamoe.mirai.LowLevelAPI
|
||||
import net.mamoe.mirai.data.MemberInfo
|
||||
import net.mamoe.mirai.event.events.*
|
||||
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.Image
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.isContentEmpty
|
||||
import net.mamoe.mirai.message.data.toMessage
|
||||
import net.mamoe.mirai.message.recall
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.internal.runBlocking
|
||||
import kotlin.jvm.JvmName
|
||||
@ -137,8 +137,8 @@ abstract class Group : Contact(), CoroutineScope {
|
||||
*
|
||||
* 单条消息最大可发送 4500 字符或 50 张图片.
|
||||
*
|
||||
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
|
||||
* @see GroupMessageSendEvent 发送群消息事件. cancellable
|
||||
* @see GroupMessagePreSendEvent 发送消息前事件
|
||||
* @see GroupMessagePostSendEvent 发送消息后事件
|
||||
*
|
||||
* @throws EventCancelledException 当发送消息事件被取消时抛出
|
||||
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
|
||||
@ -154,7 +154,7 @@ abstract class Group : Contact(), CoroutineScope {
|
||||
* @see sendMessage
|
||||
*/
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "VIRTUAL_MEMBER_HIDDEN", "OVERRIDE_BY_INLINE")
|
||||
@kotlin.internal.InlineOnly // purely virtual
|
||||
@kotlin.internal.InlineOnly
|
||||
@JvmSynthetic
|
||||
suspend inline fun sendMessage(message: String): MessageReceipt<Group> {
|
||||
return sendMessage(message.toMessage())
|
||||
|
@ -17,7 +17,12 @@ import net.mamoe.mirai.event.events.*
|
||||
import net.mamoe.mirai.getFriendOrNull
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.isContentEmpty
|
||||
import net.mamoe.mirai.message.data.toMessage
|
||||
import net.mamoe.mirai.message.recall
|
||||
import net.mamoe.mirai.utils.hoursToSeconds
|
||||
import net.mamoe.mirai.utils.daysToSeconds
|
||||
import net.mamoe.mirai.utils.minutesToSeconds
|
||||
import net.mamoe.mirai.utils.WeakRefProperty
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
import kotlin.time.Duration
|
||||
@ -139,8 +144,11 @@ abstract class Member : MemberJavaFriendlyAPI, User() {
|
||||
*
|
||||
* 单条消息最大可发送 4500 字符或 50 张图片.
|
||||
*
|
||||
* @see MessageSendEvent.FriendMessageSendEvent 发送好友信息事件, cancellable
|
||||
* @see MessageSendEvent.GroupMessageSendEvent 发送群消息事件. cancellable
|
||||
* @see FriendMessagePreSendEvent 当此成员是好友时发送消息前事件
|
||||
* @see FriendMessagePostSendEvent 当此成员是好友时发送消息后事件
|
||||
*
|
||||
* @see TempMessagePreSendEvent 当此成员不是好友时发送消息前事件
|
||||
* @see TempMessagePostSendEvent 当此成员不是好友时发送消息后事件
|
||||
*
|
||||
* @throws EventCancelledException 当发送消息事件被取消时抛出
|
||||
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
|
||||
@ -156,7 +164,7 @@ abstract class Member : MemberJavaFriendlyAPI, User() {
|
||||
* @see sendMessage
|
||||
*/
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "VIRTUAL_MEMBER_HIDDEN", "OVERRIDE_BY_INLINE")
|
||||
@kotlin.internal.InlineOnly // purely virtual
|
||||
@kotlin.internal.InlineOnly
|
||||
@JvmSynthetic
|
||||
suspend inline fun sendMessage(message: String): MessageReceipt<Member> {
|
||||
return sendMessage(message.toMessage())
|
||||
|
@ -13,11 +13,7 @@ package net.mamoe.mirai.contact
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.event.events.BeforeImageUploadEvent
|
||||
import net.mamoe.mirai.event.events.EventCancelledException
|
||||
import net.mamoe.mirai.event.events.ImageUploadEvent
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
|
||||
import net.mamoe.mirai.event.events.*
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
@ -58,8 +54,8 @@ abstract class User : Contact(), CoroutineScope {
|
||||
*
|
||||
* 单条消息最大可发送 4500 字符或 50 张图片.
|
||||
*
|
||||
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
|
||||
* @see GroupMessageSendEvent 发送群消息事件. cancellable
|
||||
* @see UserMessagePreSendEvent 发送消息前事件
|
||||
* @see UserMessagePostSendEvent 发送消息后事件
|
||||
*
|
||||
* @throws EventCancelledException 当发送消息事件被取消时抛出
|
||||
* @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
|
||||
@ -75,7 +71,7 @@ abstract class User : Contact(), CoroutineScope {
|
||||
* @see sendMessage
|
||||
*/
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "VIRTUAL_MEMBER_HIDDEN", "OVERRIDE_BY_INLINE")
|
||||
@kotlin.internal.InlineOnly // purely virtual
|
||||
@kotlin.internal.InlineOnly
|
||||
@JvmSynthetic
|
||||
suspend inline fun sendMessage(message: String): MessageReceipt<User> {
|
||||
return sendMessage(message.toMessage())
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("BotEventsKt")
|
||||
@file:Suppress("unused")
|
||||
@file:Suppress("unused", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "RESULT_CLASS_IN_RETURN_TYPE")
|
||||
|
||||
package net.mamoe.mirai.event.events
|
||||
|
||||
@ -19,41 +19,253 @@ import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.event.CancellableEvent
|
||||
import net.mamoe.mirai.event.events.ImageUploadEvent.Failed
|
||||
import net.mamoe.mirai.event.events.ImageUploadEvent.Succeed
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
import net.mamoe.mirai.qqandroid.network.Packet
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.PlannedRemoval
|
||||
import net.mamoe.mirai.utils.SinceMirai
|
||||
import kotlin.internal.InlineOnly
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
|
||||
// region MessagePreSendEvent
|
||||
|
||||
/**
|
||||
* 主动发送消息
|
||||
* 在发送消息前广播的事件. 可被 [取消][CancellableEvent.cancel].
|
||||
*
|
||||
* 此事件总是在 [MessagePostSendEvent] 之前广播.
|
||||
*
|
||||
* 当 [MessagePreSendEvent] 被 [取消][CancellableEvent.cancel] 后:
|
||||
* - [MessagePostSendEvent] 不会广播
|
||||
* - 消息不会发送.
|
||||
* - [Contact.sendMessage] 会抛出异常 [EventCancelledException]
|
||||
*
|
||||
* @see Contact.sendMessage 发送消息. 为广播这个事件的唯一途径
|
||||
*/
|
||||
sealed class MessageSendEvent : BotEvent, BotActiveEvent, AbstractEvent() {
|
||||
@SinceMirai("1.1.0")
|
||||
sealed class MessagePreSendEvent : BotEvent, BotActiveEvent, AbstractEvent(), CancellableEvent {
|
||||
/** 发信目标. */
|
||||
abstract val target: Contact
|
||||
final override val bot: Bot
|
||||
get() = target.bot
|
||||
final override val bot: Bot get() = target.bot
|
||||
|
||||
data class GroupMessageSendEvent internal constructor(
|
||||
override val target: Group,
|
||||
var message: MessageChain
|
||||
) : MessageSendEvent(), CancellableEvent
|
||||
|
||||
data class FriendMessageSendEvent internal constructor(
|
||||
override val target: Friend,
|
||||
var message: MessageChain
|
||||
) : MessageSendEvent(), CancellableEvent
|
||||
|
||||
data class TempMessageSendEvent internal constructor(
|
||||
override val target: Member,
|
||||
var message: MessageChain
|
||||
) : MessageSendEvent(), CancellableEvent
|
||||
/** 待发送的消息. 修改后将会同时应用于发送. */
|
||||
abstract var message: Message
|
||||
}
|
||||
|
||||
/**
|
||||
* 在发送群消息前广播的事件.
|
||||
* @see MessagePreSendEvent
|
||||
*/
|
||||
@SinceMirai("1.1.0")
|
||||
data class GroupMessagePreSendEvent internal constructor(
|
||||
/** 发信目标. */
|
||||
override val target: Group,
|
||||
/** 待发送的消息. 修改后将会同时应用于发送. */
|
||||
override var message: Message
|
||||
) : MessagePreSendEvent()
|
||||
|
||||
/**
|
||||
* 在发送好友或群临时会话消息前广播的事件.
|
||||
* @see MessagePreSendEvent
|
||||
*/
|
||||
@SinceMirai("1.1.0")
|
||||
sealed class UserMessagePreSendEvent : MessagePreSendEvent() {
|
||||
/** 发信目标. */
|
||||
abstract override val target: User
|
||||
}
|
||||
|
||||
/**
|
||||
* 在发送好友消息前广播的事件.
|
||||
* @see MessagePreSendEvent
|
||||
*/
|
||||
@SinceMirai("1.1.0")
|
||||
data class FriendMessagePreSendEvent internal constructor(
|
||||
/** 发信目标. */
|
||||
override val target: Friend,
|
||||
/** 待发送的消息. 修改后将会同时应用于发送. */
|
||||
override var message: Message
|
||||
) : UserMessagePreSendEvent()
|
||||
|
||||
/**
|
||||
* 在发送群临时会话消息前广播的事件.
|
||||
* @see MessagePreSendEvent
|
||||
*/
|
||||
@SinceMirai("1.1.0")
|
||||
data class TempMessagePreSendEvent internal constructor(
|
||||
/** 发信目标. */
|
||||
override val target: Member,
|
||||
/** 待发送的消息. 修改后将会同时应用于发送. */
|
||||
override var message: Message
|
||||
) : UserMessagePreSendEvent() {
|
||||
val group get() = target.group
|
||||
}
|
||||
|
||||
|
||||
// endregion
|
||||
|
||||
// region MessagePostSendEvent
|
||||
|
||||
/**
|
||||
* 在发送消息后广播的事件, 总是在 [MessagePreSendEvent] 之后广播.
|
||||
*
|
||||
* 只要 [MessagePreSendEvent] 未被 [取消][CancellableEvent.cancel], [MessagePostSendEvent] 就一定会被广播, 并携带 [发送时产生的异常][MessagePostSendEvent.exception] (如果有).
|
||||
*
|
||||
* 在此事件广播前, 消息一定已经发送成功, 或产生一个异常.
|
||||
*
|
||||
* @see Contact.sendMessage 发送消息. 为广播这个事件的唯一途径
|
||||
* @see MessagePreSendEvent
|
||||
*/
|
||||
@SinceMirai("1.1.0")
|
||||
sealed class MessagePostSendEvent<C : Contact> : BotEvent, BotActiveEvent, AbstractEvent() {
|
||||
/** 发信目标. */
|
||||
abstract val target: C
|
||||
final override val bot: Bot get() = target.bot
|
||||
|
||||
/** 待发送的消息. 此为 [MessagePreSendEvent.message] 的最终值. */
|
||||
abstract val message: MessageChain
|
||||
|
||||
/**
|
||||
* 发送消息时抛出的异常. `null` 表示消息成功发送.
|
||||
* @see result
|
||||
*/
|
||||
abstract val exception: Throwable?
|
||||
|
||||
/**
|
||||
* 发送消息成功时的回执. `null` 表示消息发送失败.
|
||||
* @see result
|
||||
*/
|
||||
abstract val receipt: MessageReceipt<C>?
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指代这条已经发送的消息的 [MessageSource]. 若消息发送失败, 返回 `null`
|
||||
* @see MessagePostSendEvent.sourceResult
|
||||
*/
|
||||
@get:JvmSynthetic
|
||||
@SinceMirai("1.1.0")
|
||||
inline val MessagePostSendEvent<*>.source: MessageSource?
|
||||
get() = receipt?.source
|
||||
|
||||
/**
|
||||
* 获取指代这条已经发送的消息的 [MessageSource], 并包装为 [kotlin.Result]
|
||||
* @see MessagePostSendEvent.result
|
||||
*/
|
||||
@get:JvmSynthetic
|
||||
@SinceMirai("1.1.0")
|
||||
inline val MessagePostSendEvent<*>.sourceResult: Result<MessageSource>
|
||||
get() = result.map { it.source }
|
||||
|
||||
/**
|
||||
* 在此消息发送成功时返回 `true`.
|
||||
* @see MessagePostSendEvent.exception
|
||||
* @see MessagePostSendEvent.result
|
||||
*/
|
||||
@get:JvmSynthetic
|
||||
@SinceMirai("1.1.0")
|
||||
inline val MessagePostSendEvent<*>.isSuccess: Boolean
|
||||
get() = exception == null
|
||||
|
||||
/**
|
||||
* 在此消息发送失败时返回 `true`.
|
||||
* @see MessagePostSendEvent.exception
|
||||
* @see MessagePostSendEvent.result
|
||||
*/
|
||||
@get:JvmSynthetic
|
||||
@SinceMirai("1.1.0")
|
||||
inline val MessagePostSendEvent<*>.isFailure: Boolean
|
||||
get() = exception != null
|
||||
|
||||
/**
|
||||
* 将 [MessagePostSendEvent.exception] 与 [MessagePostSendEvent.receipt] 表示为 [Result]
|
||||
*/
|
||||
@InlineOnly
|
||||
@SinceMirai("1.1.0")
|
||||
inline val <C : Contact> MessagePostSendEvent<C>.result: Result<MessageReceipt<C>>
|
||||
get() = exception.let { exception -> if (exception != null) Result.failure(exception) else Result.success(receipt!!) }
|
||||
|
||||
/**
|
||||
* 在群消息发送后广播的事件.
|
||||
* @see MessagePostSendEvent
|
||||
*/
|
||||
@SinceMirai("1.1.0")
|
||||
data class GroupMessagePostSendEvent internal constructor(
|
||||
/** 发信目标. */
|
||||
override val target: Group,
|
||||
/** 待发送的消息. 此为 [MessagePreSendEvent.message] 的最终值. */
|
||||
override val message: MessageChain,
|
||||
/**
|
||||
* 发送消息时抛出的异常. `null` 表示消息成功发送.
|
||||
* @see result
|
||||
*/
|
||||
override val exception: Throwable?,
|
||||
/**
|
||||
* 发送消息成功时的回执. `null` 表示消息发送失败.
|
||||
* @see result
|
||||
*/
|
||||
override val receipt: MessageReceipt<Group>?
|
||||
) : MessagePostSendEvent<Group>()
|
||||
|
||||
/**
|
||||
* 在好友或群临时会话消息发送后广播的事件.
|
||||
* @see MessagePostSendEvent
|
||||
*/
|
||||
@SinceMirai("1.1.0")
|
||||
sealed class UserMessagePostSendEvent<C : User> : MessagePostSendEvent<C>()
|
||||
|
||||
/**
|
||||
* 在好友消息发送后广播的事件.
|
||||
* @see MessagePostSendEvent
|
||||
*/
|
||||
@SinceMirai("1.1.0")
|
||||
data class FriendMessagePostSendEvent internal constructor(
|
||||
/** 发信目标. */
|
||||
override val target: Friend,
|
||||
/** 待发送的消息. 此为 [MessagePreSendEvent.message] 的最终值. */
|
||||
override val message: MessageChain,
|
||||
/**
|
||||
* 发送消息时抛出的异常. `null` 表示消息成功发送.
|
||||
* @see result
|
||||
*/
|
||||
override val exception: Throwable?,
|
||||
/**
|
||||
* 发送消息成功时的回执. `null` 表示消息发送失败.
|
||||
* @see result
|
||||
*/
|
||||
override val receipt: MessageReceipt<Friend>?
|
||||
) : UserMessagePostSendEvent<Friend>()
|
||||
|
||||
/**
|
||||
* 在群临时会话消息发送后广播的事件.
|
||||
* @see MessagePostSendEvent
|
||||
*/
|
||||
@SinceMirai("1.1.0")
|
||||
data class TempMessagePostSendEvent internal constructor(
|
||||
/** 发信目标. */
|
||||
override val target: Member,
|
||||
/** 待发送的消息. 此为 [MessagePreSendEvent.message] 的最终值. */
|
||||
override val message: MessageChain,
|
||||
/**
|
||||
* 发送消息时抛出的异常. `null` 表示消息成功发送.
|
||||
* @see result
|
||||
*/
|
||||
override val exception: Throwable?,
|
||||
/**
|
||||
* 发送消息成功时的回执. `null` 表示消息发送失败.
|
||||
* @see result
|
||||
*/
|
||||
override val receipt: MessageReceipt<Member>?
|
||||
) : UserMessagePostSendEvent<Member>() {
|
||||
val group get() = target.group
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* 消息撤回事件. 可是任意消息被任意人撤回.
|
||||
*
|
||||
@ -177,3 +389,65 @@ sealed class ImageUploadEvent : BotEvent, BotActiveEvent, AbstractEvent() {
|
||||
) : ImageUploadEvent()
|
||||
}
|
||||
|
||||
|
||||
// region deprecated
|
||||
|
||||
/**
|
||||
* 主动发送消息
|
||||
*
|
||||
* @see Contact.sendMessage 发送消息. 为广播这个事件的唯一途径
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
@PlannedRemoval("1.3.0") // arise deprecation level to ERROR in 1.2.0.
|
||||
@Deprecated(
|
||||
message = """
|
||||
以 MessagePreSendEvent 和 MessagePostSendEvent 替换.
|
||||
""",
|
||||
replaceWith = ReplaceWith("MessagePreSendEvent", "net.mamoe.mirai.event.events.MessagePreSendEvent"),
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
sealed class MessageSendEvent : BotEvent, BotActiveEvent, AbstractEvent() {
|
||||
abstract val target: Contact
|
||||
final override val bot: Bot
|
||||
get() = target.bot
|
||||
|
||||
@Deprecated(
|
||||
message = """
|
||||
以 GroupMessagePreSendEvent 和 GroupMessagePostSendEvent 替换.
|
||||
""",
|
||||
replaceWith = ReplaceWith("GroupMessagePreSendEvent", "net.mamoe.mirai.event.events.GroupMessagePreSendEvent"),
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
data class GroupMessageSendEvent internal constructor(
|
||||
override val target: Group,
|
||||
var message: MessageChain
|
||||
) : MessageSendEvent(), CancellableEvent
|
||||
|
||||
@Deprecated(
|
||||
message = """
|
||||
以 FriendMessagePreSendEvent 和 FriendMessagePostSendEvent 替换.
|
||||
""",
|
||||
replaceWith = ReplaceWith(
|
||||
"FriendMessagePreSendEvent",
|
||||
"net.mamoe.mirai.event.events.FriendMessagePreSendEvent"
|
||||
),
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
data class FriendMessageSendEvent internal constructor(
|
||||
override val target: Friend,
|
||||
var message: MessageChain
|
||||
) : MessageSendEvent(), CancellableEvent
|
||||
|
||||
@Deprecated(
|
||||
message = """
|
||||
以 TempMessagePreSendEvent 和 TempMessagePostSendEvent 替换.
|
||||
""",
|
||||
replaceWith = ReplaceWith("TempMessagePreSendEvent", "net.mamoe.mirai.event.events.TempMessagePreSendEvent"),
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
data class TempMessageSendEvent internal constructor(
|
||||
override val target: Member,
|
||||
var message: MessageChain
|
||||
) : MessageSendEvent(), CancellableEvent
|
||||
}
|
||||
// endregion
|
Loading…
Reference in New Issue
Block a user