mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-06 09:00:14 +08:00
Simplify message handler
This commit is contained in:
parent
265a431b7f
commit
57685d39e7
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -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})"
|
||||
}
|
||||
|
||||
|
@ -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 }) { this@content.reply(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) { this@case.reply(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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 易产生迷惑感
|
||||
|
@ -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)
|
||||
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) } }
|
||||
|
||||
|
@ -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 号发送的消息(可以是好友消息也可以是群消息)
|
||||
|
@ -108,7 +108,7 @@ class MiraiService : Service() {
|
||||
|
||||
|
||||
// 当收到 "我的qq" 就执行 lambda 并回复 lambda 的返回值 String
|
||||
"我的qq" reply { sender.id.toString() }
|
||||
"我的qq" reply { sender.id }
|
||||
|
||||
|
||||
// 当消息前缀为 "我是" 时
|
||||
|
@ -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> {
|
||||
|
Loading…
Reference in New Issue
Block a user