Commit 28b47f96 authored by Him188's avatar Him188

Image uploading

parent 14722eb8
...@@ -90,7 +90,7 @@ data class PlainText(override val stringValue: String) : Message() { ...@@ -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 文件名. 这将决定图片的显示 * @param filename 文件名. 这将决定图片的显示
*/ */
data class Image(val id: ImageId, val filename: String = "") : Message() { data class Image(val id: ImageId, val filename: String = "") : Message() {
......
...@@ -153,6 +153,9 @@ fun MessageChain.toPacket(forGroup: Boolean): ByteReadPacket = buildPacket { ...@@ -153,6 +153,9 @@ fun MessageChain.toPacket(forGroup: Boolean): ByteReadPacket = buildPacket {
if (forGroup) { if (forGroup) {
writeUByte(MessageType.GROUP_IMAGE.value) 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 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 * 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 { ...@@ -160,19 +163,11 @@ fun MessageChain.toPacket(forGroup: Boolean): ByteReadPacket = buildPacket {
writeShortLVPacket { writeShortLVPacket {
//todo //todo
writeByte(0x02) writeUByte(0x02u)
writeShortLVString(id.value.substring(1..35)) writeShortLVString(id.value)
writeHex("04 00 " + 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")
"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")
writeStringUtf8(id.value) writeStringUtf8(id.value)
writeByte(0x41) writeUByte(0x41u)
} }
} else { } else {
writeUByte(MessageType.FRIEND_IMAGE.value) writeUByte(MessageType.FRIEND_IMAGE.value)
...@@ -212,13 +207,28 @@ fun MessageChain.toPacket(forGroup: Boolean): ByteReadPacket = buildPacket { ...@@ -212,13 +207,28 @@ fun MessageChain.toPacket(forGroup: Boolean): ByteReadPacket = buildPacket {
writeByte(0x02) 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() //"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(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") writeHex("03 00 04 00 00 02 A2 04")
writeShortLVString(id.value) writeShortLVString(id.value)
writeHex("14 00 04 03 00 00 00 0B 00 00 18") writeHex("14 00 04 03 00 00 00 0B 00 00 18")
writeShortLVString(id.value) 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 //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) writeStringUtf8(id.value)
writeUByte(0x41u) writeUByte(0x41u)
......
...@@ -193,11 +193,16 @@ class GroupImageIdRequestPacket( ...@@ -193,11 +193,16 @@ class GroupImageIdRequestPacket(
override fun decode(): Unit = with(input) { override fun decode(): Unit = with(input) {
discardExact(6)//00 00 00 05 00 00 discardExact(6)//00 00 00 05 00 00
if (readUByte() != UByte.MIN_VALUE) { //if (readUByte() != UByte.MIN_VALUE) {
//服务器还没有 //服务器还没有
discardExact(remaining - 128) discardExact(remaining - 128)
uKey = readBytes(128) uKey = readBytes(128)
} //} else {
// println("服务器已经有了这个图片")
// println("后文 = ${readRemainingBytes().toUHexString()}")
//}
// 已经有了的一张图片 // 已经有了的一张图片
// 00 3B 12 03 98 01 01 // 00 3B 12 03 98 01 01
......
...@@ -42,7 +42,7 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP ...@@ -42,7 +42,7 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP
discardExact(2)//2个0x00 discardExact(2)//2个0x00
message = readMessageChain() message = readMessageChain()
val map = readTLVMap(true).withDefault { byteArrayOf(0, 0, 0, 0) } val map = readTLVMap(true)
//map.printTLVMap("父map") //map.printTLVMap("父map")
if (map.containsKey(18)) { if (map.containsKey(18)) {
senderName = map.getValue(18).read { senderName = map.getValue(18).read {
...@@ -56,7 +56,9 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP ...@@ -56,7 +56,9 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP
senderPermission = when (val value0x03 = tlv.getValue(0x03)[0].toUInt()) { senderPermission = when (val value0x03 = tlv.getValue(0x03)[0].toUInt()) {
0x04u -> SenderPermission.OWNER 0x04u -> SenderPermission.OWNER
0x02u -> { 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 0x08u -> SenderPermission.OPERATOR
0x10u -> SenderPermission.MEMBER 0x10u -> SenderPermission.MEMBER
else -> error("Could not determine member permission, unknown tlv(key=0x04,value=$value0x04)") else -> error("Could not determine member permission, unknown tlv(key=0x04,value=$value0x04)")
......
...@@ -12,7 +12,7 @@ class PlatformImage( ...@@ -12,7 +12,7 @@ class PlatformImage(
) { ) {
val fileSize: Long = fileData.remaining 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)]" override fun toString(): String = "[PlatformImage(${width}x${height} $format)]"
} }
......
...@@ -39,7 +39,11 @@ fun UInt.toByteArray(): ByteArray = byteArrayOf( ...@@ -39,7 +39,11 @@ fun UInt.toByteArray(): ByteArray = byteArrayOf(
) )
fun Int.toUHexString(separator: String = " "): String = this.toByteArray().toUHexString(separator) 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) fun String.hexToBytes(): ByteArray = HexCache.hexToBytes(this)
/** /**
...@@ -50,6 +54,7 @@ fun String.hexToUBytes(): UByteArray = HexCache.hexToUBytes(this) ...@@ -50,6 +54,7 @@ fun String.hexToUBytes(): UByteArray = HexCache.hexToUBytes(this)
fun String.hexToInt(): Int = hexToBytes().toUInt().toInt() fun String.hexToInt(): Int = hexToBytes().toUInt().toInt()
fun getRandomByteArray(length: Int): ByteArray = ByteArray(length) { Random.nextInt(0..255).toByte() } 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, 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.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 } fun ByteArray.toIoBuffer(): IoBuffer = IoBuffer.Pool.borrow().let { it.writeFully(this); it }
......
...@@ -81,18 +81,26 @@ suspend fun main() { ...@@ -81,18 +81,26 @@ suspend fun main() {
"上传好友图片" in it.message -> withTimeoutOrNull(3000) { "上传好友图片" in it.message -> withTimeoutOrNull(3000) {
val id = QQ(bot, 1040400290u) 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) it.reply(id.value)
delay(1000) delay(1000)
it.reply(Image(id)) it.reply(Image(id))
} }
"上传群图片" in it.message -> withTimeoutOrNull(3000) { "上传群图片" 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) Group(bot, 580266363u).uploadImage(image)
it.reply(image.id.value) it.reply(image.id.value)
delay(1000) 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 -> /*it.event eq "发图片群" -> sendGroupMessage(Group(session.bot, 580266363), PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
......
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