瀏覽代碼

`Image.isEmoji()` (#1596)

- Also remove image regex inlining
Karlatemp 4 年之前
父節點
當前提交
0b2a759028

+ 1 - 0
binary-compatibility-validator/android/api/binary-compatibility-validator-android.api

@@ -4357,6 +4357,7 @@ public abstract interface class net/mamoe/mirai/message/data/Image : net/mamoe/m
 	public abstract fun getImageType ()Lnet/mamoe/mirai/message/data/ImageType;
 	public abstract fun getSize ()J
 	public abstract fun getWidth ()I
+	public fun isEmoji ()Z
 	public static fun queryUrl (Lnet/mamoe/mirai/message/data/Image;)Ljava/lang/String;
 	public static fun queryUrl (Lnet/mamoe/mirai/message/data/Image;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
 }

+ 1 - 0
binary-compatibility-validator/api/binary-compatibility-validator.api

@@ -4357,6 +4357,7 @@ public abstract interface class net/mamoe/mirai/message/data/Image : net/mamoe/m
 	public abstract fun getImageType ()Lnet/mamoe/mirai/message/data/ImageType;
 	public abstract fun getSize ()J
 	public abstract fun getWidth ()I
+	public fun isEmoji ()Z
 	public static fun queryUrl (Lnet/mamoe/mirai/message/data/Image;)Ljava/lang/String;
 	public static fun queryUrl (Lnet/mamoe/mirai/message/data/Image;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
 }

+ 19 - 10
mirai-core-api/src/commonMain/kotlin/message/data/Image.kt

@@ -107,6 +107,13 @@ public interface Image : Message, MessageContent, CodableMessage {
      */
     public val imageType: ImageType
 
+    /**
+     * 判断该图片是否为 `动画表情`
+     *
+     * @since 2.8.0
+     */
+    public val isEmoji: Boolean get() = false
+
     public object AsStringSerializer : KSerializer<Image> by String.serializer().mapPrimitive(
         SERIAL_NAME,
         serialize = { imageId },
@@ -166,9 +173,8 @@ public interface Image : Message, MessageContent, CodableMessage {
         @Suppress("RegExpRedundantEscape") // This is required on Android
         @JvmStatic
         @get:JvmName("getImageIdRegex")
-        // inline because compilation error
-        public inline val IMAGE_ID_REGEX: Regex
-            get() = Regex("""\{[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\}\..{3,5}""")
+        public val IMAGE_ID_REGEX: Regex =
+            Regex("""\{[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\}\..{3,5}""")
 
         /**
          * 图片资源 ID 正则表达式 1. mirai 内部使用.
@@ -179,9 +185,8 @@ public interface Image : Message, MessageContent, CodableMessage {
         @JvmStatic
         @MiraiInternalApi
         @get:JvmName("getImageResourceIdRegex1")
-        // inline because compilation error
-        public inline val IMAGE_RESOURCE_ID_REGEX_1: Regex
-            get() = Regex("""/[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}""")
+        public val IMAGE_RESOURCE_ID_REGEX_1: Regex =
+            Regex("""/[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}""")
 
         /**
          * 图片资源 ID 正则表达式 2. mirai 内部使用.
@@ -192,9 +197,8 @@ public interface Image : Message, MessageContent, CodableMessage {
         @JvmStatic
         @MiraiInternalApi
         @get:JvmName("getImageResourceIdRegex2")
-        // inline because compilation error
-        public inline val IMAGE_RESOURCE_ID_REGEX_2: Regex
-            get() = Regex("""/[0-9]*-[0-9]*-[0-9a-fA-F]{32}""")
+        public val IMAGE_RESOURCE_ID_REGEX_2: Regex =
+            Regex("""/[0-9]*-[0-9]*-[0-9a-fA-F]{32}""")
     }
 }
 
@@ -266,7 +270,12 @@ public sealed class AbstractImage : Image {
         get() = ImageType.UNKNOWN
 
     final override fun toString(): String = _stringValue!!
-    final override fun contentToString(): String = "[图片]"
+    final override fun contentToString(): String = if (isEmoji) {
+        "[动画表情]"
+    } else {
+        "[图片]"
+    }
+
     override fun appendMiraiCodeTo(builder: StringBuilder) {
         builder.append("[mirai:image:").append(imageId).append("]")
     }

+ 18 - 2
mirai-core/src/commonMain/kotlin/message/imagesImpl.kt

@@ -11,6 +11,7 @@
 
 package net.mamoe.mirai.internal.message
 
+import kotlinx.serialization.KSerializer
 import kotlinx.serialization.Serializable
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.IMirai
@@ -19,9 +20,9 @@ import net.mamoe.mirai.contact.Contact.Companion.uploadImage
 import net.mamoe.mirai.contact.ContactOrBot
 import net.mamoe.mirai.contact.Group
 import net.mamoe.mirai.contact.User
-import net.mamoe.mirai.internal.network.protocol.data.proto.HummerCommelem
-import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
+import net.mamoe.mirai.internal.network.protocol.data.proto.*
 import net.mamoe.mirai.internal.utils._miraiContentToString
+import net.mamoe.mirai.internal.utils.io.serialization.loadAs
 import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
 import net.mamoe.mirai.message.data.*
 import net.mamoe.mirai.message.data.Image.Key.IMAGE_ID_REGEX
@@ -63,6 +64,18 @@ internal class OnlineGroupImageImpl(
             }/0?term=2"
         } else "http://gchat.qpic.cn" + delegate.origUrl
 
+    override val isEmoji: Boolean by lazy {
+        delegate.pbReserve.pbImageResv_checkIsEmoji(CustomFaceExtPb.ResvAttr.serializer())
+    }
+}
+
+private fun <T : ImgExtPbResvAttrCommon> ByteArray.pbImageResv_checkIsEmoji(serializer: KSerializer<T>): Boolean {
+    val data = this
+    return kotlin.runCatching {
+        data.takeIf { it.isNotEmpty() }?.loadAs(serializer)?.let { ext ->
+            ext.imageBizType == 1 || ext.textSummary.encodeToString() == "[动画表情]"
+        }
+    }.getOrNull() ?: false
 }
 
 private val imageLogger: MiraiLogger by lazy { MiraiLogger.Factory.create(Image::class) }
@@ -108,6 +121,9 @@ OnlineFriendImage() {
             "http://c2cpicdw.qpic.cn/offpic_new/0/" + delegate.resId + "/0?term=2"
         }
 
+    override val isEmoji: Boolean by lazy {
+        delegate.pbReserve.pbImageResv_checkIsEmoji(NotOnlineImageExtPb.ResvAttr.serializer())
+    }
 }
 
 /*

+ 3 - 3
mirai-core/src/commonMain/kotlin/network/protocol/data/proto/HummerResv3.kt

@@ -29,14 +29,14 @@ internal class CustomFaceExtPb : ProtoBuf {
 
     @Serializable
     internal class ResvAttr(
-        @JvmField @ProtoNumber(1) val imageBizType: Int = 0,
+        @ProtoNumber(1) override val imageBizType: Int = 0,
         @JvmField @ProtoNumber(2) val customfaceType: Int = 0,
         @JvmField @ProtoNumber(3) val emojiPackageid: Int = 0,
         @JvmField @ProtoNumber(4) val emojiId: Int = 0,
         @JvmField @ProtoNumber(5) val text: String = "",
         @JvmField @ProtoNumber(6) val doutuSuppliers: String = "",
         @JvmField @ProtoNumber(7) val msgImageShow: AnimationImageShow? = null,
-        @JvmField @ProtoNumber(9) val textSummary: ByteArray = EMPTY_BYTE_ARRAY,
+        @ProtoNumber(9) override val textSummary: ByteArray = EMPTY_BYTE_ARRAY,
         @JvmField @ProtoNumber(10) val emojiFrom: Int = 0,
         @JvmField @ProtoNumber(11) val emojiSource: String = "",
         @JvmField @ProtoNumber(12) val emojiWebUrl: String = "",
@@ -47,6 +47,6 @@ internal class CustomFaceExtPb : ProtoBuf {
         @JvmField @ProtoNumber(17) val cameraCaptureMaterialname: String = "",
         @JvmField @ProtoNumber(18) val adEmoJumpUrl: String = "",
         @JvmField @ProtoNumber(19) val adEmoDescStr: String = "",
-    ) : ProtoBuf
+    ) : ProtoBuf, ImgExtPbResvAttrCommon
 }
         

+ 37 - 0
mirai-core/src/commonMain/kotlin/network/protocol/data/proto/HummerResv6.kt

@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
+ *
+ *  此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ *  Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
+ *
+ *  https://github.com/mamoe/mirai/blob/master/LICENSE
+ */
+@file:Suppress("unused", "SpellCheckingInspection")
+
+package net.mamoe.mirai.internal.network.protocol.data.proto
+
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.protobuf.ProtoNumber
+import net.mamoe.mirai.internal.utils.io.ProtoBuf
+import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY
+
+@Serializable
+internal class NotOnlineImageExtPb : ProtoBuf {
+    @Serializable
+    internal class ResvAttr(
+        @ProtoNumber(1) override val imageBizType: Int = 0,
+        @JvmField @ProtoNumber(2) val customfaceType: Int = 0,
+        @JvmField @ProtoNumber(3) val emojiPackageid: Int = 0,
+        @JvmField @ProtoNumber(4) val emojiId: Int = 0,
+        @JvmField @ProtoNumber(5) val text: String = "",
+        @JvmField @ProtoNumber(6) val doutuSuppliers: String = "",
+        @ProtoNumber(8) override val textSummary: ByteArray = EMPTY_BYTE_ARRAY,
+        @JvmField @ProtoNumber(10) val emojiFrom: Int = 0,
+        @JvmField @ProtoNumber(11) val emojiSource: String = "",
+        @JvmField @ProtoNumber(12) val emojiWebUrl: String = "",
+        @JvmField @ProtoNumber(13) val emojiIconUrl: String = "",
+        @JvmField @ProtoNumber(14) val emojiMarketFaceName: String = "",
+        @JvmField @ProtoNumber(15) val source: Int = 0
+    ) : ProtoBuf, ImgExtPbResvAttrCommon
+}
+        

+ 17 - 0
mirai-core/src/commonMain/kotlin/network/protocol/data/proto/ImgExtPbResvAttrCommon.kt

@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019-2021 Mamoe Technologies and contributors.
+ *
+ * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
+ *
+ * https://github.com/mamoe/mirai/blob/dev/LICENSE
+ */
+
+package net.mamoe.mirai.internal.network.protocol.data.proto
+
+import net.mamoe.mirai.internal.utils.io.ProtoBuf
+
+internal interface ImgExtPbResvAttrCommon: ProtoBuf {
+    val textSummary: ByteArray
+    val imageBizType: Int
+}