Friend image upload

This commit is contained in:
Him188 2020-02-07 18:43:24 +08:00
parent 96d6268adb
commit 13b72b312c
7 changed files with 34 additions and 24 deletions

View File

@ -51,7 +51,7 @@ internal class QQImpl(bot: QQAndroidBot, override val coroutineContext: Coroutin
}
}
override suspend fun uploadImage(image: ExternalImage): Image {
override suspend fun uploadImage(image: ExternalImage): Image = try {
bot.network.run {
val response = LongConn.OffPicUp(
bot.client, Cmd0x352.TryUpImgReq(
@ -60,12 +60,11 @@ internal class QQImpl(bot: QQAndroidBot, override val coroutineContext: Coroutin
fileId = 0,
fileMd5 = image.md5,
fileSize = image.inputSize.toInt(),
fileName = image.md5.toUHexString("") + ".jpg",
fileName = image.md5.toUHexString("") + "." + image.format,
imgOriginal = 1,
imgWidth = image.width,
imgHeight = image.height,
imgType = image.imageType,
buType = 0
imgType = image.imageType
)
).sendAndExpect<LongConn.OffPicUp.Response>()
@ -81,7 +80,6 @@ internal class QQImpl(bot: QQAndroidBot, override val coroutineContext: Coroutin
is LongConn.OffPicUp.Response.RequireUpload -> {
HighwayHelper.uploadImage(
client = bot.client,
uin = bot.uin,
serverIp = response.serverIp[0].toIpV4AddressString(),
serverPort = response.serverPort[0],
imageInput = image.input,
@ -103,6 +101,8 @@ internal class QQImpl(bot: QQAndroidBot, override val coroutineContext: Coroutin
is LongConn.OffPicUp.Response.Failed -> error(response.message)
}
}
} finally {
image.input.close()
}
override suspend fun queryProfile(): Profile {
@ -355,7 +355,7 @@ internal class GroupImpl(
}
}
override suspend fun uploadImage(image: ExternalImage): Image {
override suspend fun uploadImage(image: ExternalImage): Image = try {
bot.network.run {
val response: ImgStore.GroupPicUp.Response = ImgStore.GroupPicUp(
bot.client,
@ -393,7 +393,6 @@ internal class GroupImpl(
HighwayHelper.uploadImage(
client = bot.client,
uin = bot.uin,
serverIp = response.uploadIpList.first().toIpV4AddressString(),
serverPort = response.uploadPortList.first(),
imageInput = image.input,
@ -436,6 +435,8 @@ internal class GroupImpl(
}
}
}
} finally {
image.input.close()
}
override fun equals(other: Any?): Boolean {

View File

@ -104,8 +104,11 @@ internal open class QQAndroidClient(
private val requestPacketRequestId: AtomicInt = atomic(1921334513)
internal fun nextRequestPacketRequestId(): Int = requestPacketRequestId.getAndAdd(2)
private val highwayDataTransSequenceId: AtomicInt = atomic(87017)
internal fun nextHighwayDataTransSequenceId(): Int = highwayDataTransSequenceId.getAndAdd(2)
private val highwayDataTransSequenceIdForGroup: AtomicInt = atomic(87017)
internal fun nextHighwayDataTransSequenceIdForGroup(): Int = highwayDataTransSequenceIdForGroup.getAndAdd(2)
private val highwayDataTransSequenceIdForFriend: AtomicInt = atomic(40717)
internal fun nextHighwayDataTransSequenceIdForFriend(): Int = highwayDataTransSequenceIdForFriend.getAndAdd(2)
val appClientVersion: Int = 0

View File

@ -78,6 +78,9 @@ object Highway {
md5: ByteArray
): ByteReadPacket {
require(uKey.size == 128) { "bad uKey. Required size=128, got ${uKey.size}" }
require(data !is ByteReadPacket || data.remaining.toInt() == dataSize) { "bad input. given dataSize=$dataSize, but actual readRemaining=${(data as ByteReadPacket).remaining}" }
require(data !is IoBuffer || data.readRemaining == dataSize) { "bad input. given dataSize=$dataSize, but actual readRemaining=${(data as IoBuffer).readRemaining}" }
val dataHighwayHead = CSDataHighwayHead.DataHighwayHead(
version = 1,
uin = uin.toString(),
@ -91,7 +94,7 @@ object Highway {
)
val segHead = CSDataHighwayHead.SegHead(
datalength = dataSize,
filesize = dataSize.toLong() and 0xFFffFFff,
filesize = dataSize.toLong(),
serviceticket = uKey,
md5 = md5,
fileMd5 = md5,

View File

@ -15,7 +15,6 @@ internal object HighwayHelper {
suspend fun uploadImage(
client: QQAndroidClient,
uin: Long,
serverIp: String,
serverPort: Int,
uKey: ByteArray,
@ -26,14 +25,18 @@ internal object HighwayHelper {
) {
require(md5.size == 16) { "bad md5. Required size=16, got ${md5.size}" }
require(uKey.size == 128) { "bad uKey. Required size=128, got ${uKey.size}" }
require(commandId == 2 || commandId == 1) { "bad commandId. Must be 1 or 2" }
val socket = PlatformSocket()
socket.connect(serverIp, serverPort)
socket.use {
socket.send(
Highway.RequestDataTrans(
uin = uin,
uin = client.uin,
command = "PicUp.DataUp",
sequenceId = client.nextHighwayDataTransSequenceId(),
sequenceId =
if (commandId == 2) client.nextHighwayDataTransSequenceIdForGroup()
else client.nextHighwayDataTransSequenceIdForFriend(),
uKey = uKey,
data = imageInput,
dataSize = inputSize,

View File

@ -91,7 +91,7 @@ internal class Cmd0x352 : ProtoBuf {
@SerialId(2) val msgTryupImgReq: List<TryUpImgReq>? = null,// optional
@SerialId(3) val msgGetimgUrlReq: List<GetImgUrlReq>? = null,// optional
@SerialId(4) val msgDelImgReq: List<DelImgReq>? = null,
@SerialId(10) val netType: Int = 0// 数据网络=5
@SerialId(10) val netType: Int = 3// 数据网络=5
) : ProtoBuf
@Serializable
@ -117,11 +117,10 @@ internal class Cmd0x352 : ProtoBuf {
@SerialId(9) val innerIP: Int = 0,
@SerialId(10) val addressBook: Int = 0,//chatType == 1006为1 我觉得发0没问题
@SerialId(11) val retry: Int = 0,//default
@SerialId(12) val buType: Int,//1或96 不确定
@SerialId(12) val buType: Int = 1,//1或96 不确定
@SerialId(13) val imgOriginal: Int,//是否为原图
@SerialId(14) val imgWidth: Int,
@SerialId(15) val imgHeight: Int,
@SerialId(16) val imgType: Int = 1000,
/**
* ImgType:
* JPG: 1000
@ -131,7 +130,8 @@ internal class Cmd0x352 : ProtoBuf {
* GIG: 2000
* APNG: 2001
* SHARPP: 1004
* */
*/
@SerialId(16) val imgType: Int = 1000,
@SerialId(17) val buildVer: String = "8.2.0.1296",//版本号
@SerialId(18) val fileIndex: ByteArray = EMPTY_BYTE_ARRAY,//default
@SerialId(19) val fileStoreDays: Int = 0,//default

View File

@ -85,7 +85,7 @@ kotlin {
api(ktor("network", ktorVersion))
//implementation("io.ktor:ktor-io:1.3.0-beta-1")
runtimeOnly(files("build/classes/kotlin/metadata/main")) // classpath is not properly set by IDE
//runtimeOnly(files("build/classes/kotlin/metadata/main")) // classpath is not properly set by IDE
}
}
commonTest {
@ -93,7 +93,7 @@ kotlin {
api(kotlin("test-annotations-common"))
api(kotlin("test-common"))
runtimeOnly(files("build/classes/kotlin/metadata/test")) // classpath is not properly set by IDE
//runtimeOnly(files("build/classes/kotlin/metadata/test")) // classpath is not properly set by IDE
}
}

View File

@ -43,13 +43,13 @@ class ExternalImage(
): ExternalImage = ExternalImage(width, height, md5, format, data, data.remaining, filename)
}
private val format: String = when (val it = imageFormat.toLowerCase()) {
"jpeg" -> "jpg" //必须转换
else -> it
}
val format: String =
when (val it = imageFormat.toLowerCase()) {
"jpeg" -> "jpg" //必须转换
else -> it
}
/**
*
* ImgType:
* JPG: 1000
* PNG: 1001