Commit 8e8f91bb authored by Him188's avatar Him188

Send temp messages as friend messages if a target Member is also a friend

parent 5b2ae6e9
...@@ -31,14 +31,14 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352 ...@@ -31,14 +31,14 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils
import net.mamoe.mirai.qqandroid.utils.toUHexString import net.mamoe.mirai.qqandroid.utils.toUHexString
import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.getValue
import net.mamoe.mirai.utils.unsafeWeakRef
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic import kotlin.jvm.JvmSynthetic
import kotlin.math.roundToInt
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime
internal inline class FriendInfoImpl( internal inline class FriendInfoImpl(
private val jceFriendInfo: net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo private val jceFriendInfo: net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo
...@@ -72,13 +72,13 @@ internal class FriendImpl( ...@@ -72,13 +72,13 @@ internal class FriendImpl(
@JvmSynthetic @JvmSynthetic
@Suppress("DuplicatedCode") @Suppress("DuplicatedCode")
override suspend fun sendMessage(message: Message): MessageReceipt<Friend> { override suspend fun sendMessage(message: Message): MessageReceipt<Friend> {
return sendMessageImpl(message).also { return sendMessageImpl(this, message).also {
logMessageSent(message) logMessageSent(message)
} }
} }
@JvmSynthetic @JvmSynthetic
@OptIn(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class, ExperimentalStdlibApi::class, ExperimentalTime::class)
override suspend fun uploadImage(image: ExternalImage): OfflineFriendImage = try { override suspend fun uploadImage(image: ExternalImage): OfflineFriendImage = try {
if (BeforeImageUploadEvent(this, image).broadcast().isCancelled) { if (BeforeImageUploadEvent(this, image).broadcast().isCancelled) {
throw EventCancelledException("cancelled by BeforeImageUploadEvent.ToGroup") throw EventCancelledException("cancelled by BeforeImageUploadEvent.ToGroup")
...@@ -102,6 +102,11 @@ internal class FriendImpl( ...@@ -102,6 +102,11 @@ internal class FriendImpl(
ImageUploadEvent.Succeed(this@FriendImpl, image, it).broadcast() ImageUploadEvent.Succeed(this@FriendImpl, image, it).broadcast()
} }
is LongConn.OffPicUp.Response.RequireUpload -> { is LongConn.OffPicUp.Response.RequireUpload -> {
bot.network.logger.verbose {
"[Http] Uploading friend image, size=${image.inputSize / 1024} KiB"
}
val time = measureTime {
MiraiPlatformUtils.Http.postImage( MiraiPlatformUtils.Http.postImage(
"0x6ff0070", "0x6ff0070",
bot.id, bot.id,
...@@ -110,16 +115,21 @@ internal class FriendImpl( ...@@ -110,16 +115,21 @@ internal class FriendImpl(
inputSize = image.inputSize, inputSize = image.inputSize,
uKeyHex = response.uKey.toUHexString("") uKeyHex = response.uKey.toUHexString("")
) )
//HighwayHelper.uploadImage( }
// client = bot.client,
// serverIp = response.serverIp[0].toIpV4AddressString(), bot.network.logger.verbose {
// serverPort = response.serverPort[0], "[Http] Uploading friend image: succeed at ${(image.inputSize.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
// imageInput = image.input, }
// inputSize = image.inputSize.toInt(),
// fileMd5 = image.md5, /*
// uKey = response.uKey, HighwayHelper.uploadImageToServers(
// commandId = 1 bot,
//) response.serverIp.zip(response.serverPort),
response.uKey,
image,
kind = "friend",
commandId = 1
)*/
// 为什么不能 ?? // 为什么不能 ??
return OfflineFriendImage(response.resourceId).also { return OfflineFriendImage(response.resourceId).also {
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
package net.mamoe.mirai.qqandroid.contact package net.mamoe.mirai.qqandroid.contact
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.io.core.Closeable import kotlinx.io.core.Closeable
import net.mamoe.mirai.LowLevelAPI import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.*
...@@ -33,17 +32,13 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement ...@@ -33,17 +32,13 @@ 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.ImgStore
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
import net.mamoe.mirai.qqandroid.utils.addSuppressedMirai
import net.mamoe.mirai.qqandroid.utils.estimateLength import net.mamoe.mirai.qqandroid.utils.estimateLength
import net.mamoe.mirai.qqandroid.utils.toIpV4AddressString
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic import kotlin.jvm.JvmSynthetic
import kotlin.math.roundToInt
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime
import kotlin.time.measureTime
@OptIn(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
internal fun GroupImpl.Companion.checkIsInstance(instance: Group) { internal fun GroupImpl.Companion.checkIsInstance(instance: Group) {
...@@ -412,86 +407,21 @@ internal class GroupImpl( ...@@ -412,86 +407,21 @@ internal class GroupImpl(
} }
is ImgStore.GroupPicUp.Response.FileExists -> { is ImgStore.GroupPicUp.Response.FileExists -> {
val resourceId = image.calculateImageResourceId() val resourceId = image.calculateImageResourceId()
// return NotOnlineImageFromFile(
// resourceId = resourceId,
// md5 = response.fileInfo.fileMd5,
// filepath = resourceId,
// fileLength = response.fileInfo.fileSize.toInt(),
// height = response.fileInfo.fileHeight,
// width = response.fileInfo.fileWidth,
// imageType = response.fileInfo.fileType,
// fileId = response.fileId.toInt()
// )
// println("NMSL")
return OfflineGroupImage(imageId = resourceId) return OfflineGroupImage(imageId = resourceId)
.also { ImageUploadEvent.Succeed(this@GroupImpl, image, it).broadcast() } .also { ImageUploadEvent.Succeed(this@GroupImpl, image, it).broadcast() }
} }
is ImgStore.GroupPicUp.Response.RequireUpload -> { is ImgStore.GroupPicUp.Response.RequireUpload -> {
// 每 10KB 等 1 秒, 最少等待 5 秒 HighwayHelper.uploadImageToServers(
var exception: Throwable? = null bot,
val success = response.uploadIpList.zip(response.uploadPortList).any { (ip, port) -> response.uploadIpList.zip(response.uploadPortList),
kotlin.runCatching { response.uKey,
withTimeoutOrNull((image.inputSize * 1000 / 1024 / 10).coerceAtLeast(5000)) { image,
bot.network.logger.verbose { "[Highway] Uploading group image to ${ip.toIpV4AddressString()}:$port, size=${image.inputSize / 1024} KiB" } kind = "group",
val time = measureTime {
HighwayHelper.uploadImage(
client = bot.client,
serverIp = ip.toIpV4AddressString(),
serverPort = port,
imageInput = image.input,
inputSize = image.inputSize.toInt(),
fileMd5 = image.md5,
ticket = response.uKey,
commandId = 2 commandId = 2
) )
}
bot.network.logger.verbose { "[Highway] Uploading group image: succeed at ${(image.inputSize.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s" }
true
} ?: kotlin.run {
bot.network.logger.verbose { "[Highway] Uploading group image: timeout, retrying next server" }
false
}
}.getOrElse {
exception?.addSuppressedMirai(it)
exception = it
false
}
}
if (!success) {
throw IllegalStateException("cannot upload group image, failed on all servers.", exception)
}
val resourceId = image.calculateImageResourceId() val resourceId = image.calculateImageResourceId()
// return NotOnlineImageFromFile(
// resourceId = resourceId,
// md5 = image.md5,
// filepath = resourceId,
// fileLength = image.inputSize.toInt(),
// height = image.height,
// width = image.width,
// imageType = image.imageType,
// fileId = response.fileId.toInt()
// )
return OfflineGroupImage(imageId = resourceId) return OfflineGroupImage(imageId = resourceId)
.also { ImageUploadEvent.Succeed(this@GroupImpl, image, it).broadcast() } .also { ImageUploadEvent.Succeed(this@GroupImpl, image, it).broadcast() }
/*
fileId = response.fileId.toInt(),
fileType = 0, // ?
height = image.height,
width = image.width,
imageType = image.imageType,
bizType = 0,
serverIp = response.uploadIpList.first(),
serverPort = response.uploadPortList.first(),
signature = image.md5,
size = image.inputSize.toInt(),
useful = 1,
source = 200,
original = 1,
pbReserve = EMPTY_BYTE_ARRAY
*/
} }
} }
} }
......
...@@ -54,9 +54,8 @@ internal class MemberImpl constructor( ...@@ -54,9 +54,8 @@ internal class MemberImpl constructor(
@JvmSynthetic @JvmSynthetic
override suspend fun sendMessage(message: Message): MessageReceipt<Member> { override suspend fun sendMessage(message: Message): MessageReceipt<Member> {
return sendMessageImpl(message).also { return (this.asFriendOrNull()?.sendMessageImpl(this, message) ?: sendMessageImpl(message))
logMessageSent(message) .also { logMessageSent(message) }
}
} }
private suspend fun sendMessageImpl(message: Message): MessageReceipt<Member> { private suspend fun sendMessageImpl(message: Message): MessageReceipt<Member> {
......
...@@ -31,7 +31,7 @@ import net.mamoe.mirai.utils.MiraiInternalAPI ...@@ -31,7 +31,7 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.verbose import net.mamoe.mirai.utils.verbose
@OptIn(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
internal suspend fun Friend.sendMessageImpl(message: Message): MessageReceipt<Friend> { internal suspend fun <T : Contact> Friend.sendMessageImpl(generic: T, message: Message): MessageReceipt<T> {
val event = MessageSendEvent.FriendMessageSendEvent(this, message.asMessageChain()).broadcast() val event = MessageSendEvent.FriendMessageSendEvent(this, message.asMessageChain()).broadcast()
if (event.isCancelled) { if (event.isCancelled) {
throw EventCancelledException("cancelled by FriendMessageSendEvent") throw EventCancelledException("cancelled by FriendMessageSendEvent")
...@@ -49,7 +49,7 @@ internal suspend fun Friend.sendMessageImpl(message: Message): MessageReceipt<Fr ...@@ -49,7 +49,7 @@ internal suspend fun Friend.sendMessageImpl(message: Message): MessageReceipt<Fr
}.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS }.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS
) { "send message failed" } ) { "send message failed" }
} }
return MessageReceipt(source, this, null) return MessageReceipt(source, generic, null)
} }
@OptIn(MiraiInternalAPI::class, MiraiExperimentalAPI::class) @OptIn(MiraiInternalAPI::class, MiraiExperimentalAPI::class)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment