From 90deacb692047d9943be2401a0683db344a3779d Mon Sep 17 00:00:00 2001 From: Him188 Date: Mon, 16 May 2022 20:38:04 +0100 Subject: [PATCH] Fix imageType sent from macOS client, fix #1111 --- .../src/commonMain/kotlin/Bytes.kt | 4 +-- .../commonMain/kotlin/contact/AbstractUser.kt | 2 +- .../commonMain/kotlin/contact/GroupImpl.kt | 2 +- .../kotlin/message/image/AbstractImage.kt | 2 -- .../kotlin/message/image/ImageInfo.kt | 4 +-- .../kotlin/message/image/OnlineImage.kt | 36 ++++++++++++++----- 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/mirai-core-utils/src/commonMain/kotlin/Bytes.kt b/mirai-core-utils/src/commonMain/kotlin/Bytes.kt index 4deb22943..4b8eb3378 100644 --- a/mirai-core-utils/src/commonMain/kotlin/Bytes.kt +++ b/mirai-core-utils/src/commonMain/kotlin/Bytes.kt @@ -19,8 +19,8 @@ import kotlin.contracts.contract @JvmOverloads -public fun generateImageId(md5: ByteArray, format: String = "mirai"): String { - return """{${generateUUID(md5)}}.$format""" +public fun generateImageId(md5: ByteArray, format: String? = null): String { + return """{${generateUUID(md5)}}.${format ?: "mirai"}""" } @JvmOverloads diff --git a/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt b/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt index 089e8b7bf..1927d6809 100644 --- a/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt +++ b/mirai-core/src/commonMain/kotlin/contact/AbstractUser.kt @@ -120,7 +120,7 @@ internal sealed class AbstractUser( }, width = fileWidth, height = fileHeight, - imageType = getImageTypeById(fileType), + imageType = getImageTypeById(fileType) ?: ImageType.UNKNOWN, size = resource.size ) }.also { diff --git a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt index c432da697..db90240fb 100644 --- a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt @@ -241,7 +241,7 @@ internal class GroupImpl constructor( imageId = resourceId, height = fileHeight, width = fileWidth, - imageType = getImageTypeById(fileType), + imageType = getImageTypeById(fileType) ?: ImageType.UNKNOWN, size = resource.size ) } diff --git a/mirai-core/src/commonMain/kotlin/message/image/AbstractImage.kt b/mirai-core/src/commonMain/kotlin/message/image/AbstractImage.kt index 019f5ec98..4dbb302ab 100644 --- a/mirai-core/src/commonMain/kotlin/message/image/AbstractImage.kt +++ b/mirai-core/src/commonMain/kotlin/message/image/AbstractImage.kt @@ -26,8 +26,6 @@ internal sealed class AbstractImage : Image { get() = 0 override val height: Int get() = 0 - override val imageType: ImageType - get() = ImageType.UNKNOWN final override fun toString(): String = _stringValue!! final override fun contentToString(): String = if (isEmoji) { diff --git a/mirai-core/src/commonMain/kotlin/message/image/ImageInfo.kt b/mirai-core/src/commonMain/kotlin/message/image/ImageInfo.kt index c0baefd1c..e8702e000 100644 --- a/mirai-core/src/commonMain/kotlin/message/image/ImageInfo.kt +++ b/mirai-core/src/commonMain/kotlin/message/image/ImageInfo.kt @@ -31,11 +31,11 @@ internal data class ImageInfo(val width: Int = 0, val height: Int = 0, val image internal val UNKNOWN_IMAGE_TYPE_PROMPT_ENABLED = systemProp("mirai.unknown.image.type.logging", false) -internal fun getImageTypeById(id: Int): ImageType { +internal fun getImageTypeById(id: Int): ImageType? { return if (id == 2001) { ImageType.APNG } else { - ImageType.match(getImageType(id)) + ImageType.matchOrNull(getImageType(id)) } } diff --git a/mirai-core/src/commonMain/kotlin/message/image/OnlineImage.kt b/mirai-core/src/commonMain/kotlin/message/image/OnlineImage.kt index 5841e693f..3f412ec48 100644 --- a/mirai-core/src/commonMain/kotlin/message/image/OnlineImage.kt +++ b/mirai-core/src/commonMain/kotlin/message/image/OnlineImage.kt @@ -47,9 +47,9 @@ OnlineFriendImage() { override val height: Int get() = delegate.picHeight override val imageType: ImageType - get() = getImageTypeById(delegate.imgType) + get() = OnlineImageIds.speculateImageType(delegate.filePath, delegate.imgType) override val imageId: String = kotlin.run { - val imageType = getImageType(delegate.imgType) + val imageType = imageType.formatName generateImageIdFromResourceId(delegate.resId, imageType) ?: kotlin.run { if (delegate.picMd5.size == 16) generateImageId(delegate.picMd5, imageType) @@ -118,16 +118,11 @@ internal class OnlineGroupImageImpl( override val height: Int get() = delegate.height override val imageType: ImageType - get() = getImageTypeById(delegate.imageType) + get() = OnlineImageIds.speculateImageType(delegate.filePath, delegate.imageType) override val imageId: String = generateImageId( delegate.picMd5, - delegate.filePath.substringAfterLast('.').lowercase().let { ext -> - if (ext == "null") { - // official clients might send `null` - getImageType(delegate.imageType) - } else ext - } + OnlineImageIds.speculateImageTypeNameFromFilePath(delegate.filePath) ).takeIf { Image.IMAGE_ID_REGEX.matches(it) } ?: generateImageId(delegate.picMd5) @@ -141,3 +136,26 @@ internal class OnlineGroupImageImpl( delegate.pbReserve.pbImageResv_checkIsEmoji(CustomFaceExtPb.ResvAttr.serializer()) } } + +private object OnlineImageIds { + + fun speculateImageType(filePath: String, imageTypeInt: Int): ImageType { + return getImageTypeById(imageTypeInt) ?: speculateImageTypeFromImageId(filePath) ?: ImageType.UNKNOWN + } + + fun speculateImageTypeFromImageId(filePathOrImageId: String): ImageType? { + return speculateImageTypeNameFromFilePath(filePathOrImageId)?.let { ImageType.matchOrNull(it) } + } + + /** + * @param filePath should ends with `.type` + */ + fun speculateImageTypeNameFromFilePath(filePath: String): String? { + return filePath.substringAfterLast('.').lowercase().let { ext -> + if (ext == "null") { + // official clients might send `null` + null + } else ext + } + } +} \ No newline at end of file