Image uploading

This commit is contained in:
Him188 2019-10-20 21:27:59 +08:00
parent 14722eb838
commit 28b47f9603
7 changed files with 55 additions and 25 deletions

View File

@ -90,7 +90,7 @@ data class PlainText(override val stringValue: String) : Message() {
* 图片消息. 在发送时将会区分群图片和好友图片发送.
* 由接收消息时构建, 可直接发送
*
* @param id 类似 `/01ee6426-5ff1-4cf0-8278-e8634d2909ef`. 群的是大写id, 好友的是小写id
* @param id 类似 `/01ee6426-5ff1-4cf0-8278-e8634d2909ef` `{F61593B5-5B98-1798-3F47-2A91D32ED2FC}.jpg`
* @param filename 文件名. 这将决定图片的显示
*/
data class Image(val id: ImageId, val filename: String = "") : Message() {

View File

@ -153,6 +153,9 @@ fun MessageChain.toPacket(forGroup: Boolean): ByteReadPacket = buildPacket {
if (forGroup) {
writeUByte(MessageType.GROUP_IMAGE.value)
//00 00 03 00 CB 02 00 2A 7B 46 36 31 35 39 33 42 35 2D 35 42 39 38 2D 31 37 39 38 2D 33 46 34 37 2D 32 41 39 31 44 33 32 45 44 32 46 43 7D 2E 6A 70 67
// 04 00 04 87 E5 09 3B 05 00 04 D2 C4 C0 B7 06 00 04 00 00 00 50 07 00 01 43 08 00 00 09 00 01 01 0B 00 00 14 00 04 00 00 00 00 15 00 04 00 00 01 ED 16 00 04 00 00 02 17 18 00 04 00 00 EB 34 FF 00 5C 15 36 20 39 32 6B 41 31 43 38 37 65 35 30 39 33 62 64 32 63 34 63 30 62 37 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
// 7B 46 36 31 35 39 33 42 35 2D 35 42 39 38 2D 31 37 39 38 2D 33 46 34 37 2D 32 41 39 31 44 33 32 45 44 32 46 43 7D 2E 6A 70 67 41
/*
* 00 00 06 00 F3 02 00 1B 28 52 49 5F 36 31 28 32 52 59 4B 59 43 40 37 59 29 58 29 39 29 42 49 2E 67 69 66 03 00 04 00 00 11 90 04 00 25 2F 35 37 34 63 34 32 34 30 2D 30 31 33 66 2D 34 35 39 38 2D 61 37 32 34 2D 30 36 65 66 35 36 39 39 30 64 30 62 14 00 04 03 00 00 00 0B 00 00 18 00 25 2F 35 37 34 63 34 32 34 30 2D 30 31 33 66 2D 34 35 39 38 2D 61 37 32 34 2D 30 36 65 66 35 36 39 39 30 64 30 62 19 00 04 00 00 00 2D 1A 00 04 00 00 00 2D FF 00 63 16 20 20 39 39 31 30 20 38 38 31 44 42 20 20 20 20 20 20 34 34 39 36 65 33 39 46 37 36 35 33 32 45 31 41 42 35 43 41 37 38 36 44 37 41 35 31 33 38 39 32 32 35 33 38 35 2E 67 69 66 66 2F 35 37 34 63 34 32 34 30 2D 30 31 33 66 2D 34 35 39 38 2D 61 37 32 34 2D 30 36 65 66 35 36 39 39 30 64 30 62 41
* 00 00 06 00 F3 02 00 1B 46 52 25 46 60 30 59 4F 4A 5A 51 48 31 46 4A 53 4C 51 4C 4A 33 46 31 2E 6A 70 67 03 00 04 00 00 02 A2 04 00 25 2F 37 33 38 33 35 38 36 37 2D 38 64 65 31 2D 34 65 30 66 2D 61 33 36 35 2D 34 39 62 30 33 39 63 34 61 39 31 66 14 00 04 03 00 00 00 0B 00 00 18 00 25 2F 37 33 38 33 35 38 36 37 2D 38 64 65 31 2D 34 65 30 66 2D 61 33 36 35 2D 34 39 62 30 33 39 63 34 61 39 31 66 19 00 04 00 00 00 4E 1A 00 04 00 00 00 23 FF 00 63 16 20 20 39 39 31 30 20 38 38 31 43 42 20 20 20 20 20 20 20 36 37 34 65 31 46 42 34 43 32 35 45 42 34 46 45 31 32 45 34 46 33 42 42 38 31 39 31 33 37 42 44 39 39 30 39 2E 6A 70 67 66 2F 37 33 38 33 35 38 36 37 2D 38 64 65 31 2D 34 65 30 66 2D 61 33 36 35 2D 34 39 62 30 33 39 63 34 61 39 31 66 41
@ -160,19 +163,11 @@ fun MessageChain.toPacket(forGroup: Boolean): ByteReadPacket = buildPacket {
writeShortLVPacket {
//todo
writeByte(0x02)
writeShortLVString(id.value.substring(1..35))
writeHex("04 00 " +
"04 9B 53 B0 08 " +
"05 00 " +
"04 D9 8A 5A 70 " +
"06 00 " +
"04 00 00 00 50 " +
"07 00 " +
"01 43 08 00 00 09 00 01 01 0B 00 00 14 00 04 11 00 00 00 15 00 04 00 00 02 BC 16 00 04 00 00 02 BC 18 00 04 00 00 7D 5E FF 00 5C 15 36 20 39 32 6B 41 31 43 39 62 35 33 62 30 30 38 64 39 38 61 35 61 37 30 20")
writeHex("20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20")
writeUByte(0x02u)
writeShortLVString(id.value)
writeHex("04 00 04 87 E5 09 3B 05 00 04 D2 C4 C0 B7 06 00 04 00 00 00 50 07 00 01 43 08 00 00 09 00 01 01 0B 00 00 14 00 04 00 00 00 00 15 00 04 00 00 01 ED 16 00 04 00 00 02 17 18 00 04 00 00 EB 34 FF 00 5C 15 36 20 39 32 6B 41 31 43 38 37 65 35 30 39 33 62 64 32 63 34 63 30 62 37 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20")
writeStringUtf8(id.value)
writeByte(0x41)
writeUByte(0x41u)
}
} else {
writeUByte(MessageType.FRIEND_IMAGE.value)
@ -212,13 +207,28 @@ fun MessageChain.toPacket(forGroup: Boolean): ByteReadPacket = buildPacket {
writeByte(0x02)
//"46 52 25 46 60 30 59 4F 4A 5A 51 48 31 46 4A 53 4C 51 4C 4A 33 46 31 2E 6A 70 67".hexToBytes().stringOfWitch()
// writeShortLVString(filename)//图片文件名 FR%F`0YOJZQH1FJSLQLJ3F1.jpg
writeShortLVString(getRandomString(24, 'A'..'Z') + ".jpg")//图片文件名 FR%F`0YOJZQH1FJSLQLJ3F1.jpg
writeShortLVString(id.value.substring(1..24) + ".gif")//图片文件名 FR%F`0YOJZQH1FJSLQLJ3F1.jpg
writeHex("03 00 04 00 00 02 A2 04")
writeShortLVString(id.value)
writeHex("14 00 04 03 00 00 00 0B 00 00 18")
writeShortLVString(id.value)
writeHex("19 00 04 00 00 00 4E 1A 00 04 00 00 00 23 FF 00 63 16 20 20 39 39 31 30 20 38 38 31 43 42 20 20 20 20 20 20 20 " +
"36 37 34 65 31 46 42 34 43 32 35 45 42 34 46 45 31 32 45 34 46 33 42 42 38 31 39 31 33 37 42 44 39 39 30 39 2E 6A 70 67 66 ")
writeHex("19 00 04 00 00 00 4E 1A 00 04 00 00 00 23 FF 00 63 16 20 20 39 39 31 30 20 38 38 31 43 42 20 20 20 20 20 20 20 ")
writeStringUtf8("674e")//补长度
writeStringUtf8(id.value.substring(1..id.value.lastIndex - 4).replace("-", "B"))//这一串文件名决定手机QQ保存的图片. 可以随意
writeStringUtf8(".gif")
writeUByte(0x66u)
/*
* writeHex("19 00 04 00 00 00 4E 1A 00 04 00 00 00 23 FF 00 63 16 20 20 39 39 31 30 20 38 38 31 43 42 20 20 20 20 20 20 20 ")
writeStringUtf8(id.value.subSequence(1..id.value.lastIndex))//674e1FB4C25EB4FE12E4F3BB819137BD9909.jpg
writeStringUtf8(".jpg")// "36 37 34 65 31 46 42 34 43 32 35 45 42 34 46 45 31 32 45 34 46 33 42 42 38 31 39 31 33 37 42 44 39 39 30 39 2E 6A 70 67
writeUByte(0x66u)
* */
//36 37 34 65 31 46 42 34 43 32 35 45 42 34 46 45 31 32 45 34 46 33 42 42 38 31 39 31 33 37 42 44 39 39 30 39 2E 6A 70 67 66
writeStringUtf8(id.value)
writeUByte(0x41u)

View File

@ -193,11 +193,16 @@ class GroupImageIdRequestPacket(
override fun decode(): Unit = with(input) {
discardExact(6)//00 00 00 05 00 00
if (readUByte() != UByte.MIN_VALUE) {
//if (readUByte() != UByte.MIN_VALUE) {
//服务器还没有
discardExact(remaining - 128)
uKey = readBytes(128)
}
//} else {
// println("服务器已经有了这个图片")
// println("后文 = ${readRemainingBytes().toUHexString()}")
//}
// 已经有了的一张图片
// 00 3B 12 03 98 01 01

View File

@ -42,7 +42,7 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP
discardExact(2)//2个0x00
message = readMessageChain()
val map = readTLVMap(true).withDefault { byteArrayOf(0, 0, 0, 0) }
val map = readTLVMap(true)
//map.printTLVMap("父map")
if (map.containsKey(18)) {
senderName = map.getValue(18).read {
@ -56,7 +56,9 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP
senderPermission = when (val value0x03 = tlv.getValue(0x03)[0].toUInt()) {
0x04u -> SenderPermission.OWNER
0x02u -> {
when (val value0x04 = tlv.getValue(0x04)[3].toUInt()) {
if (!tlv.containsKey(0x04)) {
SenderPermission.MEMBER
} else when (val value0x04 = tlv.getValue(0x04)[3].toUInt()) {
0x08u -> SenderPermission.OPERATOR
0x10u -> SenderPermission.MEMBER
else -> error("Could not determine member permission, unknown tlv(key=0x04,value=$value0x04)")

View File

@ -12,7 +12,7 @@ class PlatformImage(
) {
val fileSize: Long = fileData.remaining
val id: ImageId by lazy { ImageId("{${md5[0..4]}-${md5[0..2]}-${md5[0..2]}-${md5[0..2]}-${md5[0..6]}}.$format") }
val id: ImageId by lazy { ImageId("{${md5[0..3]}-${md5[4..5]}-${md5[6..7]}-${md5[8..9]}-${md5[10..15]}}.$format") }
override fun toString(): String = "[PlatformImage(${width}x${height} $format)]"
}

View File

@ -39,7 +39,11 @@ fun UInt.toByteArray(): ByteArray = byteArrayOf(
)
fun Int.toUHexString(separator: String = " "): String = this.toByteArray().toUHexString(separator)
fun Byte.toUHexString(): String = this.toUByte().toString(16).toUpperCase()
fun Byte.toUHexString(): String = this.toUByte().toString(16).toUpperCase().let {
if (it.length == 1) "0$it"
else it
}
fun String.hexToBytes(): ByteArray = HexCache.hexToBytes(this)
/**
@ -50,6 +54,7 @@ fun String.hexToUBytes(): UByteArray = HexCache.hexToUBytes(this)
fun String.hexToInt(): Int = hexToBytes().toUInt().toInt()
fun getRandomByteArray(length: Int): ByteArray = ByteArray(length) { Random.nextInt(0..255).toByte() }
fun getRandomString(length: Int, charRange: CharRange): String = String(CharArray(length) { charRange.random() })
fun getRandomString(length: Int, vararg charRanges: CharRange): String = String(CharArray(length) { charRanges[Random.Default.nextInt(0..charRanges.lastIndex)].random() })
fun ByteArray.toUInt(): UInt = this[0].toUInt().and(255u).shl(24) + this[1].toUInt().and(255u).shl(16) + this[2].toUInt().and(255u).shl(8) + this[3].toUInt().and(255u).shl(0)
fun ByteArray.toIoBuffer(): IoBuffer = IoBuffer.Pool.borrow().let { it.writeFully(this); it }

View File

@ -81,18 +81,26 @@ suspend fun main() {
"上传好友图片" in it.message -> withTimeoutOrNull(3000) {
val id = QQ(bot, 1040400290u)
.uploadImage(withContext(Dispatchers.IO) { ImageIO.read(File("C:\\Users\\Him18\\Desktop\\lemon.png").readBytes().inputStream()) }.toPlatformImage("png"))
.uploadImage(withContext(Dispatchers.IO) { ImageIO.read(File("C:\\Users\\Him18\\Desktop\\色图.jpg").readBytes().inputStream()) }.toPlatformImage("png"))
it.reply(id.value)
delay(1000)
it.reply(Image(id))
}
"上传群图片" in it.message -> withTimeoutOrNull(3000) {
val image = withContext(Dispatchers.IO) { ImageIO.read(File("C:\\Users\\Him18\\Desktop\\lemon.png").readBytes().inputStream()) }.toPlatformImage("png")
val image = withContext(Dispatchers.IO) { ImageIO.read(File("C:\\Users\\Him18\\Desktop\\色图.jpg").readBytes().inputStream()) }.toPlatformImage("png")
Group(bot, 580266363u).uploadImage(image)
it.reply(image.id.value)
delay(1000)
it.reply(Image(image.id))
Group(bot, 580266363u).sendMessage(Image(image.id))
}
"发群图片" in it.message -> {
Group(bot, 580266363u).sendMessage(Image(ImageId(it.message.toString().substringAfter("发图片"))))
}
"发好友图片" in it.message -> {
it.reply(Image(ImageId(it.message.toString().substringAfter("发好友图片"))))
}
/*it.event eq "发图片群" -> sendGroupMessage(Group(session.bot, 580266363), PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->