Ver Fonte

Simplify message handler

Him188 há 6 anos atrás
pai
commit
57685d39e7

+ 5 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt

@@ -18,13 +18,17 @@ import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
 interface Group : Contact {
     val internalId: GroupInternalId
 
+    /**
+     * 在 [Group] 实例创建的时候查询一次. 收到各事件后
+     */
     val member: ContactList<Member>
 
+
     suspend fun getMember(id: UInt): Member
 
     /**
      * 查询群资料
-     */
+     */ // should be `suspend val` if kotlin supports in the future
     suspend fun queryGroupInfo(): GroupInfo
 }
 

+ 8 - 12
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt

@@ -2,11 +2,10 @@
 
 package net.mamoe.mirai.contact
 
-import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.Deferred
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.contact.data.Profile
 import net.mamoe.mirai.network.BotSession
+import net.mamoe.mirai.network.protocol.tim.packet.action.FriendNameRemark
 import net.mamoe.mirai.network.protocol.tim.packet.action.PreviousNameList
 
 /**
@@ -23,17 +22,9 @@ import net.mamoe.mirai.network.protocol.tim.packet.action.PreviousNameList
  */
 interface QQ : Contact {
     /**
-     * 用户资料.
-     * 第一次获取时将会向服务器查询.
-     * 第一次以后则是直接得到一个用 [CompletableDeferred] 包装的值
+     * 查询用户资料
      */
-    val profile: Deferred<Profile>
-
-    /**
-     * 更新个人资料.
-     * 将会同步更新 property [profile]
-     */
-    suspend fun updateProfile(): Profile
+    suspend fun queryProfile(): Profile
 
     /**
      * 查询曾用名.
@@ -43,4 +34,9 @@ interface QQ : Contact {
      * - 共同群内的群名片
      */
     suspend fun queryPreviousNameList(): PreviousNameList
+
+    /**
+     * 查询机器人账号给这个人设置的备注
+     */
+    suspend fun queryRemark(): FriendNameRemark
 }

+ 7 - 16
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/internal/ContactImpl.kt

@@ -2,8 +2,6 @@
 
 package net.mamoe.mirai.contact.internal
 
-import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.sync.Mutex
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.contact.*
@@ -17,7 +15,6 @@ import net.mamoe.mirai.network.qqAccount
 import net.mamoe.mirai.network.sessionKey
 import net.mamoe.mirai.qqAccount
 import net.mamoe.mirai.sendPacket
-import net.mamoe.mirai.utils.SuspendLazy
 import net.mamoe.mirai.withSession
 
 internal sealed class ContactImpl : Contact {
@@ -40,9 +37,7 @@ internal data class GroupImpl internal constructor(override val bot: Bot, val gr
 
     override suspend fun getMember(id: UInt): Member =
         if (_members.containsKey(id)) _members[id]!!
-        else throw NoSuchElementException("No such member whose id is $id in group $id") /*membersLock.withLock {
-            _members.getOrPut(id) { MemberImpl(bot.getQQ(id), this) }
-        }*/
+        else throw NoSuchElementException("No such member whose id is $id in group $id")
 
     override suspend fun sendMessage(message: MessageChain) {
         bot.sendPacket(GroupPacket.Message(bot.qqAccount, internalId, bot.sessionKey, message))
@@ -56,25 +51,21 @@ internal data class GroupImpl internal constructor(override val bot: Bot, val gr
 }
 
 internal data class QQImpl internal constructor(override val bot: Bot, override val id: UInt) : ContactImpl(), QQ {
-    private var _profile: Profile? = null
-    private val _initialProfile by bot.network.SuspendLazy { updateProfile() }
-
-    override val profile: Deferred<Profile> get() = if (_profile == null) _initialProfile else CompletableDeferred(_profile!!)
-
     override suspend fun sendMessage(message: MessageChain) =
         bot.sendPacket(SendFriendMessagePacket(bot.qqAccount, id, bot.sessionKey, message))
 
-    override suspend fun updateProfile(): Profile = bot.withSession {
-        _profile = RequestProfileDetailsPacket(bot.qqAccount, id, sessionKey)
-            .sendAndExpect<RequestProfileDetailsResponse, Profile> { it.profile }
-
-        return _profile!!
+    override suspend fun queryProfile(): Profile = bot.withSession {
+        RequestProfileDetailsPacket(bot.qqAccount, id, sessionKey).sendAndExpect<RequestProfileDetailsResponse>().profile
     }
 
     override suspend fun queryPreviousNameList(): PreviousNameList = bot.withSession {
         QueryPreviousNamePacket(bot.qqAccount, sessionKey, id).sendAndExpect()
     }
 
+    override suspend fun queryRemark(): FriendNameRemark = bot.withSession {
+        QueryFriendRemarkPacket(bot.qqAccount, sessionKey, id).sendAndExpect()
+    }
+
     override fun toString(): String = "QQ(${this.id})"
 }
 

+ 14 - 8
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/MessageSubscribers.kt

@@ -109,15 +109,13 @@ suspend inline fun Bot.subscribeFriendMessages(crossinline listeners: suspend Me
     }.apply { listeners() }
 }
 
-private typealias MessageReplier<T> = @MessageDsl suspend T.(String) -> Message
-
-private typealias StringReplier<T> = @MessageDsl suspend T.(String) -> String
+private typealias AnyReplier<T> = @MessageDsl suspend T.(String) -> Any?
 
 private suspend inline operator fun <T : MessagePacket<*>> (@MessageDsl suspend T.(String) -> Unit).invoke(t: T) =
     this.invoke(t, t.message.stringValue)
 
 @JvmName("invoke1") //Avoid Platform declaration clash
-private suspend inline operator fun <T : MessagePacket<*>> StringReplier<T>.invoke(t: T): String =
+private suspend inline operator fun <T : MessagePacket<*>> AnyReplier<T>.invoke(t: T): Any? =
     this.invoke(t, t.message.stringValue)
 
 /**
@@ -217,15 +215,15 @@ class MessageSubscribersBuilder<T : MessagePacket<*>>(
         content({ this@containsReply in it }) { [email protected](replier) }
 
     @MessageDsl
-    suspend infix fun String.containsReply(replier: StringReplier<T>) =
+    suspend infix fun String.containsReply(replier: AnyReplier<T>) =
         content({ this@containsReply in it }) { replier(this) }
 
     @MessageDsl
-    suspend infix fun String.startsWithReply(replier: StringReplier<T>) =
+    suspend infix fun String.startsWithReply(replier: AnyReplier<T>) =
         content({ it.startsWith(this@startsWithReply) }) { replier(this) }
 
     @MessageDsl
-    suspend infix fun String.endswithReply(replier: StringReplier<T>) =
+    suspend infix fun String.endswithReply(replier: AnyReplier<T>) =
         content({ it.endsWith(this@endswithReply) }) { replier(this) }
 
     @MessageDsl
@@ -234,7 +232,15 @@ class MessageSubscribersBuilder<T : MessagePacket<*>>(
     }
 
     @MessageDsl
-    suspend infix fun String.reply(reply: StringReplier<T>) = case(this) { [email protected](reply(this)) }
+    suspend infix fun String.reply(reply: AnyReplier<T>) = case(this) {
+        when (val message = reply(this)) {
+            is Message -> reply(message)
+            is Unit -> {
+
+            }
+            else -> reply(message.toString())
+        }
+    }
 
 
 /* 易产生迷惑感

+ 5 - 7
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageChain.kt

@@ -99,18 +99,16 @@ fun SingleMessageChain(delegate: Message): MessageChain {
 /**
  * 得到包含 [this] 的 [MessageChain].
  * 若 [this] 为 [MessageChain] 将直接返回 this
- * 否则将调用 [SingleMessageChain] 构造一个唯一成员且不可修改的 [SingleMessageChainImpl]
- *
- * @see SingleMessageChain
- * @see SingleMessageChainImpl
+ * 否则将调用 [MessageChain] 构造一个 [MessageChainImpl]
  */
-fun Message.chain(): MessageChain = if (this is MessageChain) this else MessageChain(this)
+@Suppress("NOTHING_TO_INLINE")
+inline fun Message.chain(): MessageChain = if (this is MessageChain) this else MessageChain(this)
 
 /**
  * 构造 [MessageChain]
  */
-@Suppress("unused")
-fun List<Message>.messageChain(): MessageChain = MessageChain(this)
+@Suppress("unused", "NOTHING_TO_INLINE")
+inline fun List<Message>.messageChain(): MessageChain = MessageChain(this)
 
 
 /**

+ 7 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Message.kt

@@ -32,6 +32,10 @@ import kotlin.jvm.JvmName
 @UseExperimental(MiraiInternalAPI::class)
 expect abstract class MessagePacket<TSubject : Contact>() : MessagePacketBase<TSubject>
 
+interface BotExtensions {
+    suspend fun MessageChain.reply()
+}
+
 @MiraiInternalAPI
 abstract class MessagePacketBase<TSubject : Contact> : EventPacket, BotEvent() {
     internal lateinit var botVar: Bot
@@ -172,7 +176,9 @@ data class FriendMessage(
     /**
      * 是否应被自动广播. 此为内部 API
      */
-    override val shouldBroadcast: Boolean get() = !previous
+    @MiraiInternalAPI
+    override val shouldBroadcast: Boolean
+        get() = !previous
 
     override val subject: QQ get() = sender
 }

+ 3 - 0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/packet/event/MessagePacket.kt

@@ -49,6 +49,9 @@ actual abstract class MessagePacket<TSubject : Contact> : MessagePacketBase<TSub
     suspend inline fun File.sendAsImage() = sendAsImageTo(subject)
 
     suspend inline fun Image.downloadTo(file: File): Long = file.outputStream().use { downloadTo(it) }
+    /**
+     * 这个函数结束后不会关闭 [output]
+     */
     suspend inline fun Image.downloadTo(output: OutputStream): Long =
         download().inputStream().use { input -> withContext(Dispatchers.IO) { input.copyTo(output) } }
 

+ 3 - 1
mirai-demos/mirai-demo-1/src/main/java/demo/subscribe/SubscribeSamples.kt

@@ -96,6 +96,8 @@ suspend fun Bot.messageDSL() {
             // sender: QQ
             // it: String (MessageChain.toString)
 
+
+            message[Image].download()
             if (this is GroupMessage) {
                 //如果是群消息
                 // group: Group
@@ -112,7 +114,7 @@ suspend fun Bot.messageDSL() {
 
 
         // 当收到 "我的qq" 就执行 lambda 并回复 lambda 的返回值 String
-        "我的qq" reply { sender.id.toString() }
+        "我的qq" reply { sender.id }
 
 
         // 如果是这个 QQ 号发送的消息(可以是好友消息也可以是群消息)

+ 1 - 1
mirai-demos/mirai-demo-android/src/main/kotlin/net/mamoe/mirai/demo/MiraiService.kt

@@ -108,7 +108,7 @@ class MiraiService : Service() {
 
 
                 // 当收到 "我的qq" 就执行 lambda 并回复 lambda 的返回值 String
-                "我的qq" reply { sender.id.toString() }
+                "我的qq" reply { sender.id }
 
 
                 // 当消息前缀为 "我是" 时

+ 1 - 2
mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt

@@ -68,7 +68,6 @@ suspend fun main() {
             if (this is GroupMessage) {
                 group.queryGroupInfo().toString().reply()
             }
-            ""
         }
 
         startsWith("profile", removePrefix = true) {
@@ -77,7 +76,7 @@ suspend fun main() {
                 bot.getQQ(account.toUInt())
             } else {
                 sender
-            }.profile.await().toString().reply()
+            }.queryProfile().toString().reply()
         }
 
         has<Image> {