From 44a6ba160e04d03c89c3463c450d5efdf0d06280 Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Wed, 20 Nov 2019 19:40:22 +0800 Subject: [PATCH] Explict image declaration --- .../kotlin/net.mamoe.mirai/message/Message.kt | 34 +++++++++++++- .../message/internal/MessageDataInternal.kt | 44 +++++++++++++++++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt index 589bca46d..74d0581a2 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt @@ -6,6 +6,8 @@ import net.mamoe.mirai.contact.Contact import net.mamoe.mirai.contact.QQ import net.mamoe.mirai.network.protocol.tim.packet.action.FriendImagePacket import net.mamoe.mirai.utils.ExternalImage +import net.mamoe.mirai.utils.io.debugPrintln +import net.mamoe.mirai.utils.io.toUHexString import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract import kotlin.js.JsName @@ -162,6 +164,34 @@ inline class Image(inline val id: ImageId) : Message { inline val Image.idValue: String get() = id.value +inline class ImageId0x06(override inline val value: String) : ImageId { + override fun toString(): String = "ImageId($value)" +} + +/** + * 一般是群的图片的 id. + * + * @param md5 用于下载图片时提交 + */ +class ImageId0x03 constructor(override inline val value: String, inline val uniqueId: UInt, inline val height: Int, inline val width: Int) : ImageId { + override fun toString(): String = "ImageId(value=$value, uniqueId=${uniqueId}, height=$height, width=$width)" + + val md5: ByteArray + get() = this.value + .substringAfter("{").substringBefore("}") + .replace("-", "") + .chunked(2) + .map { (it[0] + it[1].toString()).toUByte(16).toByte() } + .toByteArray().also { check(it.size == 16); debugPrintln("image md5=" + it.toUHexString()); debugPrintln("imageId=$this") } +} + +@Suppress("FunctionName") +fun ImageId(value: String): ImageId = ImageId0x06(value) + +@Suppress("FunctionName") +fun ImageId(value: String, uniqueId: UInt, height: Int, width: Int): ImageId = ImageId0x03(value, uniqueId, height, width) + + /** * 图片的标识符. 由图片的数据产生. * 对于群, [value] 类似于 `{F61593B5-5B98-1798-3F47-2A91D32ED2FC}.jpg`, 由图片文件 MD5 直接产生. @@ -170,7 +200,9 @@ inline val Image.idValue: String get() = id.value * @see ExternalImage.groupImageId 群图片的 [ImageId] 获取 * @see FriendImagePacket 好友图片的 [ImageId] 获取 */ -inline class ImageId(inline val value: String) +interface ImageId { + val value: String +} fun ImageId.checkLength() = check(value.length == 37 || value.length == 42) { "Illegal ImageId length" } fun ImageId.requireLength() = require(value.length == 37 || value.length == 42) { "Illegal ImageId length" } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt index 93e736b37..b95591ab1 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt @@ -41,7 +41,7 @@ internal fun IoBuffer.parseMessageImage0x06(): Image { discardExact(filenameLength.toInt()) discardExact(8)//03 00 04 00 00 02 9C 04 val length = readShort()//=27 - return Image(ImageId(readString(length))) + return Image(ImageId0x06(readString(length))) //return Image("{${readString(length)}}.$suffix") } @@ -56,9 +56,44 @@ internal fun IoBuffer.parseMessageImage0x06(): Image { // 00 63 16 20 20 39 39 31 30 20 38 38 31 43 42 20 20 20 20 20 20 20 36 36 38 65 35 43 36 38 45 36 42 44 32 46 35 38 34 31 42 30 39 37 39 45 37 46 32 35 34 33 38 38 31 33 43 33 2E 6A 70 67 66 2F 32 65 37 61 65 33 36 66 2D 61 39 31 63 2D 34 31 32 39 2D 62 61 34 32 2D 37 65 30 31 32 39 37 37 35 63 63 38 41 internal fun IoBuffer.parseMessageImage0x03(): Image { - discardExact(1) + //discardExact(1) + val tlv = readTLVMap(expectingEOF = true, tagSize = 1) + tlv.printTLVMap("parseMessageImage0x03") + // 02 [ ] IMAGE ID + // 04 [00 04] 8B 88 95 C1 + // 05 [00 04] 3B 24 59 FC + // 06 [00 04] 00 00 01 BB + // 07 [00 01] 42 + // 08 [00 10] 32 55 6D 52 33 4E 53 64 41 68 44 78 71 56 79 41 + // 09 [00 01] 01 + // 0A [00 10] F5 C3 E6 86 70 EA 03 3E D3 30 1D 2A B5 2E D6 5C + // 15 [00 04] 00 00 03 76 + // 16 [00 04] 00 00 07 80 + // 17 [00 02] 00 65 + // 18 [00 04] 00 01 A6 F2 + // 19 [00 01] 00 + // 1A [00 04] 00 00 81 5C + // 1B [00 04] 00 01 3D 27 + // 1C [00 04] 00 00 03 EB + // FF [00 56] 15 36 20 38 36 65 41 31 42 38 62 38 38 39 35 63 31 33 62 32 34 35 39 66 63 20 20 20 20 20 31 62 62 32 55 6D 52 33 4E 53 64 41 68 44 78 71 56 79 41 46 35 43 33 45 36 38 36 37 30 45 41 30 33 33 45 44 33 33 30 31 44 32 41 42 35 32 45 44 36 35 43 2E 6A 70 67 41 + // return if (tlv.containsKey(0x0Au)) { + return Image( + ImageId0x03( + String(tlv[0x02u]!!).adjustImageId(), + // tlv[0x0Au], + uniqueId = tlv[0x04u]!!.read { readUInt() }, + height = tlv[0x16u]!!.toUInt().toInt(), + width = tlv[0x15u]!!.toUInt().toInt() + ).also { debugPrintln("ImageId: $it") } + ) + //} else { + // Image( + // ImageId0x06( + // String(tlv[0x02u]!!).adjustImageId() + // ) + // ) + //} - return Image(ImageId(String(readUShortLVByteArray()).adjustImageId())) } private operator fun String.get(range: IntRange) = this.substring(range) @@ -165,7 +200,8 @@ fun MessageChain.toPacket(): ByteReadPacket = buildPacket { is Image -> buildPacket { when (id.value.length) { // "{F61593B5-5B98-1798-3F47-2A91D32ED2FC}.jpg" - 42 -> { + // 41 ??? + 41, 42 -> { writeUByte(MessageType.IMAGE_42.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