mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-09 09:50:16 +08:00
Improve SendMessageHandler; Fix image not display in some group; #939
This commit is contained in:
parent
8c88f0e44f
commit
af034a0a00
@ -156,6 +156,7 @@ internal class GroupImpl(
|
||||
is ImgStore.GroupPicUp.Response.FileExists -> {
|
||||
val resourceId = resource.calculateResourceId()
|
||||
return OfflineGroupImage(imageId = resourceId)
|
||||
.also { it.fileId = response.fileId.toInt() }
|
||||
.also { ImageUploadEvent.Succeed(this@GroupImpl, resource, it).broadcast() }
|
||||
}
|
||||
is ImgStore.GroupPicUp.Response.RequireUpload -> {
|
||||
@ -169,6 +170,7 @@ internal class GroupImpl(
|
||||
)
|
||||
|
||||
return OfflineGroupImage(imageId = resource.calculateResourceId())
|
||||
.also { it.fileId = response.fileId.toInt() }
|
||||
.also { ImageUploadEvent.Succeed(this@GroupImpl, resource, it).broadcast() }
|
||||
}
|
||||
}
|
||||
|
@ -25,11 +25,11 @@ import net.mamoe.mirai.internal.network.protocol.packet.chat.image.ImgStore
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.*
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.createToFriend
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.createToGroup
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.sendAndExpect
|
||||
import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.castOrNull
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
/**
|
||||
* 通用处理器
|
||||
@ -105,7 +105,7 @@ internal abstract class SendMessageHandler<C : Contact> {
|
||||
*/
|
||||
suspend fun sendMessagePacket(
|
||||
originalMessage: Message,
|
||||
transformedMessage: Message,
|
||||
transformedMessage: MessageChain,
|
||||
finalMessage: MessageChain,
|
||||
step: SendMessageStep,
|
||||
): MessageReceipt<C> {
|
||||
@ -125,10 +125,10 @@ internal abstract class SendMessageHandler<C : Contact> {
|
||||
if (resp is MessageSvcPbSendMsg.Response.MessageTooLarge) {
|
||||
return when (step) {
|
||||
SendMessageStep.FIRST -> {
|
||||
sendMessage(originalMessage, transformedMessage, SendMessageStep.LONG_MESSAGE)
|
||||
sendMessageImpl(originalMessage, transformedMessage, SendMessageStep.LONG_MESSAGE)
|
||||
}
|
||||
SendMessageStep.LONG_MESSAGE -> {
|
||||
sendMessage(originalMessage, transformedMessage, SendMessageStep.FRAGMENTED)
|
||||
sendMessageImpl(originalMessage, transformedMessage, SendMessageStep.FRAGMENTED)
|
||||
|
||||
}
|
||||
else -> {
|
||||
@ -219,6 +219,8 @@ internal abstract class SendMessageHandler<C : Contact> {
|
||||
)
|
||||
}
|
||||
|
||||
open suspend fun preConversionTransformedMessage(message: Message): Message = message
|
||||
open suspend fun conversionMessageChain(chain: MessageChain): MessageChain = chain
|
||||
|
||||
open suspend fun postTransformActions(chain: MessageChain) {
|
||||
|
||||
@ -255,15 +257,33 @@ internal suspend fun <C : Contact> SendMessageHandler<C>.transformSpecialMessage
|
||||
}
|
||||
|
||||
/**
|
||||
* Might be recalled with [transformedMessage] `is` [LongMessageInternal] if length estimation failed (sendMessagePacket)
|
||||
* Send a message, and covert messages
|
||||
*
|
||||
* Don't recall this function.
|
||||
*/
|
||||
internal suspend fun <C : Contact> SendMessageHandler<C>.sendMessage(
|
||||
originalMessage: Message,
|
||||
transformedMessage: Message,
|
||||
step: SendMessageStep,
|
||||
): MessageReceipt<C> = sendMessageImpl(
|
||||
originalMessage,
|
||||
conversionMessageChain(
|
||||
transformSpecialMessages(
|
||||
preConversionTransformedMessage(transformedMessage)
|
||||
)
|
||||
),
|
||||
step
|
||||
)
|
||||
|
||||
/**
|
||||
* Might be recalled with [transformedMessage] `is` [LongMessageInternal] if length estimation failed (sendMessagePacket)
|
||||
*/
|
||||
internal suspend fun <C : Contact> SendMessageHandler<C>.sendMessageImpl(
|
||||
originalMessage: Message,
|
||||
transformedMessage: MessageChain,
|
||||
step: SendMessageStep,
|
||||
): MessageReceipt<C> { // Result cannot be in interface.
|
||||
val chain = transformSpecialMessages(transformedMessage)
|
||||
.convertToLongMessageIfNeeded(step)
|
||||
val chain = transformedMessage.convertToLongMessageIfNeeded(step)
|
||||
|
||||
chain.findIsInstance<QuoteReply>()?.source?.ensureSequenceIdAvailable()
|
||||
|
||||
@ -314,11 +334,19 @@ internal class GroupSendMessageHandler(
|
||||
override val senderName: String
|
||||
get() = contact.botAsMember.nameCardOrNick
|
||||
|
||||
override suspend fun postTransformActions(chain: MessageChain) {
|
||||
chain.asSequence().filterIsInstance<FriendImage>().forEach { image ->
|
||||
contact.updateFriendImageForGroupMessage(image)
|
||||
override suspend fun conversionMessageChain(chain: MessageChain): MessageChain = chain.map { element ->
|
||||
when (element) {
|
||||
is OfflineGroupImage -> {
|
||||
contact.fixImageFileId(element)
|
||||
element
|
||||
}
|
||||
is FriendImage -> {
|
||||
contact.updateFriendImageForGroupMessage(element)
|
||||
}
|
||||
else -> element
|
||||
}
|
||||
}
|
||||
}.toMessageChain()
|
||||
|
||||
|
||||
override suspend fun constructSourceFromMusicShareResponse(
|
||||
finalMessage: MessageChain,
|
||||
@ -341,18 +369,55 @@ internal class GroupSendMessageHandler(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private suspend fun GroupImpl.fixImageFileId(image: OfflineGroupImage) {
|
||||
if (image.fileId == null) {
|
||||
val response: ImgStore.GroupPicUp.Response = ImgStore.GroupPicUp(
|
||||
bot.client,
|
||||
uin = bot.id,
|
||||
groupCode = this.id,
|
||||
md5 = image.md5,
|
||||
size = 1,
|
||||
).sendAndExpect(bot)
|
||||
|
||||
when (response) {
|
||||
is ImgStore.GroupPicUp.Response.Failed -> {
|
||||
image.fileId = 0 // Failed
|
||||
}
|
||||
is ImgStore.GroupPicUp.Response.FileExists -> {
|
||||
image.fileId = response.fileId.toInt()
|
||||
}
|
||||
is ImgStore.GroupPicUp.Response.RequireUpload -> {
|
||||
image.fileId = response.fileId.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures server holds the cache
|
||||
*/
|
||||
private suspend fun GroupImpl.updateFriendImageForGroupMessage(image: FriendImage) {
|
||||
private suspend fun GroupImpl.updateFriendImageForGroupMessage(image: FriendImage): OfflineGroupImage {
|
||||
bot.network.run {
|
||||
ImgStore.GroupPicUp(
|
||||
val response = ImgStore.GroupPicUp(
|
||||
bot.client,
|
||||
uin = bot.id,
|
||||
groupCode = id,
|
||||
md5 = image.md5,
|
||||
size = if (image is OnlineFriendImageImpl) image.delegate.fileLen else 0
|
||||
).sendAndExpect<ImgStore.GroupPicUp.Response>()
|
||||
return OfflineGroupImage(image.imageId).also { img ->
|
||||
when (response) {
|
||||
is ImgStore.GroupPicUp.Response.FileExists -> {
|
||||
img.fileId = response.fileId.toInt()
|
||||
}
|
||||
is ImgStore.GroupPicUp.Response.RequireUpload -> {
|
||||
img.fileId = response.fileId.toInt()
|
||||
}
|
||||
is ImgStore.GroupPicUp.Response.Failed -> {
|
||||
img.fileId = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,6 +178,7 @@ internal fun ImMsgBody.CustomFace.toNotOnlineImage(): ImMsgBody.NotOnlineImage {
|
||||
@Suppress("DEPRECATION")
|
||||
internal fun OfflineGroupImage.toJceData(): ImMsgBody.CustomFace {
|
||||
return ImMsgBody.CustomFace(
|
||||
fileId = this.fileId ?: 0,
|
||||
filePath = this.imageId,
|
||||
picMd5 = this.md5,
|
||||
flag = ByteArray(4),
|
||||
@ -185,7 +186,9 @@ internal fun OfflineGroupImage.toJceData(): ImMsgBody.CustomFace {
|
||||
//_400Url = "/gchatpic_new/000000000/1041235568-2195821338-01E9451B70EDEAE3B37C101F1EEBF5B5/400?term=2",
|
||||
//_400Width = 351,
|
||||
oldData = oldData,
|
||||
// pbReserve = CustomFaceExtPb.ResvAttr().toByteArray(CustomFaceExtPb.ResvAttr.serializer())
|
||||
// pbReserve = "08 00 10 00 32 00 50 00 78 08".autoHexToBytes(),
|
||||
// useful = 1,
|
||||
// pbReserve = CustomFaceExtPb.ResvAttr().toByteArray(CustomFaceExtPb.ResvAttr.serializer())
|
||||
)
|
||||
}
|
||||
|
||||
@ -258,6 +261,9 @@ internal interface OfflineImage : Image
|
||||
internal data class OfflineGroupImage(
|
||||
override val imageId: String
|
||||
) : GroupImage(), OfflineImage, DeferredOriginUrlAware {
|
||||
@Transient
|
||||
internal var fileId: Int? = null
|
||||
|
||||
object Serializer : Image.FallbackSerializer("OfflineGroupImage")
|
||||
|
||||
override fun getUrl(bot: Bot): String {
|
||||
|
Loading…
Reference in New Issue
Block a user