mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-24 14:30:09 +08:00
Friend image upload done
This commit is contained in:
parent
867b2c8911
commit
a66c71dd8d
@ -10,6 +10,7 @@ import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.NotOnlineImageFromFile
|
||||
import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
|
||||
import net.mamoe.mirai.qqandroid.network.highway.postImage
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
|
||||
@ -50,7 +51,6 @@ internal class QQImpl(bot: QQAndroidBot, override val coroutineContext: Coroutin
|
||||
) { "send message failed" }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun uploadImage(image: ExternalImage): Image = try {
|
||||
bot.network.run {
|
||||
val response = LongConn.OffPicUp(
|
||||
@ -78,16 +78,17 @@ internal class QQImpl(bot: QQAndroidBot, override val coroutineContext: Coroutin
|
||||
resourceId = response.resourceId
|
||||
)
|
||||
is LongConn.OffPicUp.Response.RequireUpload -> {
|
||||
HighwayHelper.uploadImage(
|
||||
client = bot.client,
|
||||
serverIp = response.serverIp[0].toIpV4AddressString(),
|
||||
serverPort = response.serverPort[0],
|
||||
imageInput = image.input,
|
||||
inputSize = image.inputSize.toInt(),
|
||||
md5 = image.md5,
|
||||
uKey = response.uKey,
|
||||
commandId = 1
|
||||
)
|
||||
Http.postImage("0x6ff0070", bot.uin, null, imageInput = image.input, inputSize = image.inputSize, uKeyHex = response.uKey.toUHexString(""))
|
||||
// HighwayHelper.uploadImage(
|
||||
// client = bot.client,
|
||||
// serverIp = response.serverIp[0].toIpV4AddressString(),
|
||||
// serverPort = response.serverPort[0],
|
||||
// imageInput = image.input,
|
||||
// inputSize = image.inputSize.toInt(),
|
||||
// md5 = image.md5,
|
||||
// uKey = response.uKey,
|
||||
// commandId = 1
|
||||
// )
|
||||
|
||||
return NotOnlineImageFromFile(
|
||||
filepath = response.resourceId,
|
||||
|
@ -1,66 +1,9 @@
|
||||
package net.mamoe.mirai.qqandroid.network.highway
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.request.post
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.http.URLProtocol
|
||||
import io.ktor.http.content.OutgoingContent
|
||||
import io.ktor.http.userAgent
|
||||
import kotlinx.coroutines.io.ByteWriteChannel
|
||||
import kotlinx.io.core.*
|
||||
import kotlinx.io.pool.useInstance
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
|
||||
import net.mamoe.mirai.utils.io.ByteArrayPool
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
internal suspend inline fun HttpClient.postImage(
|
||||
htcmd: String,
|
||||
uin: Long,
|
||||
groupcode: Long?,
|
||||
imageInput: Input,
|
||||
inputSize: Long,
|
||||
uKeyHex: String
|
||||
): Boolean = try {
|
||||
post<HttpStatusCode> {
|
||||
url {
|
||||
protocol = URLProtocol.HTTP
|
||||
host = "htdata2.qq.com"
|
||||
path("cgi-bin/httpconn")
|
||||
|
||||
parameters["htcmd"] = htcmd
|
||||
parameters["uin"] = uin.toString()
|
||||
|
||||
if (groupcode != null) parameters["groupcode"] = groupcode.toString()
|
||||
|
||||
parameters["term"] = "pc"
|
||||
parameters["ver"] = "5603"
|
||||
parameters["filesize"] = inputSize.toString()
|
||||
parameters["range"] = 0.toString()
|
||||
parameters["ukey"] = uKeyHex
|
||||
|
||||
userAgent("QQClient")
|
||||
}
|
||||
|
||||
body = object : OutgoingContent.WriteChannelContent() {
|
||||
override val contentType: ContentType = ContentType.Image.Any
|
||||
override val contentLength: Long = inputSize
|
||||
|
||||
override suspend fun writeTo(channel: ByteWriteChannel) {
|
||||
ByteArrayPool.useInstance { buffer: ByteArray ->
|
||||
var size: Int
|
||||
while (imageInput.readAvailable(buffer).also { size = it } != 0) {
|
||||
channel.writeFully(buffer, 0, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} == HttpStatusCode.OK
|
||||
} finally {
|
||||
imageInput.close()
|
||||
}
|
||||
|
||||
object Highway {
|
||||
fun RequestDataTrans(
|
||||
|
@ -1,18 +1,76 @@
|
||||
package net.mamoe.mirai.qqandroid.network.highway
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.request.post
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.http.URLProtocol
|
||||
import io.ktor.http.content.OutgoingContent
|
||||
import io.ktor.http.userAgent
|
||||
import kotlinx.coroutines.io.ByteWriteChannel
|
||||
import kotlinx.io.core.Input
|
||||
import kotlinx.io.core.readAvailable
|
||||
import kotlinx.io.core.use
|
||||
import kotlinx.io.pool.useInstance
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
|
||||
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.withUse
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.io.ByteArrayPool
|
||||
import net.mamoe.mirai.utils.io.PlatformSocket
|
||||
import net.mamoe.mirai.utils.io.discardExact
|
||||
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
internal suspend inline fun HttpClient.postImage(
|
||||
htcmd: String,
|
||||
uin: Long,
|
||||
groupcode: Long?,
|
||||
imageInput: Input,
|
||||
inputSize: Long,
|
||||
uKeyHex: String
|
||||
): Boolean = try {
|
||||
post<HttpStatusCode> {
|
||||
url {
|
||||
protocol = URLProtocol.HTTP
|
||||
host = "htdata2.qq.com"
|
||||
path("cgi-bin/httpconn")
|
||||
|
||||
parameters["htcmd"] = htcmd
|
||||
parameters["uin"] = uin.toString()
|
||||
|
||||
if (groupcode != null) parameters["groupcode"] = groupcode.toString()
|
||||
|
||||
parameters["term"] = "pc"
|
||||
parameters["ver"] = "5603"
|
||||
parameters["filesize"] = inputSize.toString()
|
||||
parameters["range"] = 0.toString()
|
||||
parameters["ukey"] = uKeyHex
|
||||
|
||||
userAgent("QQClient")
|
||||
}
|
||||
|
||||
body = object : OutgoingContent.WriteChannelContent() {
|
||||
override val contentType: ContentType = ContentType.Image.Any
|
||||
override val contentLength: Long = inputSize
|
||||
|
||||
override suspend fun writeTo(channel: ByteWriteChannel) {
|
||||
ByteArrayPool.useInstance { buffer: ByteArray ->
|
||||
var size: Int
|
||||
while (imageInput.readAvailable(buffer).also { size = it } != 0) {
|
||||
channel.writeFully(buffer, 0, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} == HttpStatusCode.OK
|
||||
} finally {
|
||||
imageInput.close()
|
||||
}
|
||||
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
internal object HighwayHelper {
|
||||
|
||||
suspend fun uploadImage(
|
||||
client: QQAndroidClient,
|
||||
serverIp: String,
|
||||
|
Loading…
Reference in New Issue
Block a user