From ffe9f5f99223d8bf10c5203355e2aae0d265bcfe Mon Sep 17 00:00:00 2001 From: Him188 Date: Thu, 14 May 2020 16:52:11 +0800 Subject: [PATCH] Improve CommandSender --- .../mamoe/mirai/console/command/Command.kt | 6 +- .../mirai/console/command/CommandArgParser.kt | 18 ++--- .../console/command/CommandPermission.kt | 20 +++--- .../mirai/console/command/CommandSender.kt | 71 +++++++++++-------- .../mirai/console/command/TestCommands.kt | 40 +++++------ 5 files changed, 83 insertions(+), 72 deletions(-) diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt index 2f5d388ce..a23330a58 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt @@ -37,7 +37,7 @@ interface Command { /** * 执行这个指令. */ - suspend fun onCommand(sender: CommandSender, args: CommandArgs): Boolean + suspend fun CommandSender.onCommand(args: CommandArgs): Boolean } /** @@ -138,8 +138,8 @@ abstract class BlockingCommand( owner: PluginBase, descriptor: CommandDescriptor ) : PluginCommand(owner, descriptor) { - final override suspend fun onCommand(sender: CommandSender, args: CommandArgs): Boolean { - return withContext(Dispatchers.IO) { onCommandBlocking(sender, args) } + final override suspend fun CommandSender.onCommand(args: CommandArgs): Boolean { + return withContext(Dispatchers.IO) { onCommandBlocking(this@onCommand, args) } } abstract fun onCommandBlocking(sender: CommandSender, args: CommandArgs): Boolean diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandArgParser.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandArgParser.kt index 91e1ffda4..cc95ed28b 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandArgParser.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandArgParser.kt @@ -141,8 +141,8 @@ object ExistFriendArgParser : CommandArgParser() { illegalArgument("无法解析~作为默认") } val targetID = when (sender) { - is GroupContactCommandSender -> sender.realSender.id - is ContactCommandSender -> sender.contact.id + is MemberCommandSender -> sender.realSender.id + is UserCommandSender -> sender.user.id else -> illegalArgument("无法解析~作为默认") } return try { @@ -177,7 +177,7 @@ object ExistFriendArgParser : CommandArgParser() { override fun parse(raw: SingleMessage, sender: CommandSender): Friend { if (raw is At) { - assert(sender is GroupContactCommandSender) + assert(sender is MemberCommandSender) return (sender as BotAware).bot.friends.getOrNull(raw.target) ?: illegalArgument("At的对象非Bot好友") } else { error("无法解析 $raw 为好友") @@ -188,8 +188,8 @@ object ExistFriendArgParser : CommandArgParser() { object ExistGroupArgParser : CommandArgParser() { override fun parse(raw: String, sender: CommandSender): Group { //by default - if ((raw == "" || raw == "~") && sender is GroupContactCommandSender) { - return sender.contact as Group + if ((raw == "" || raw == "~") && sender is MemberCommandSender) { + return sender.user as Group } //from bot to group if (sender is BotAware) { @@ -255,8 +255,8 @@ object ExistMemberArgParser : CommandArgParser() { } } else { val bot = sender.bot - if (sender is GroupContactCommandSender) { - val group = sender.contact as Group + if (sender is MemberCommandSender) { + val group = sender.user as Group return try { group.members[raw.toLong()] } catch (ignored: Exception) { @@ -288,8 +288,8 @@ object ExistMemberArgParser : CommandArgParser() { override fun parse(raw: SingleMessage, sender: CommandSender): Member { return if (raw is At) { - checkArgument(sender is GroupContactCommandSender) - (sender.contact as Group).members[raw.target] + checkArgument(sender is MemberCommandSender) + (sender.user as Group).members[raw.target] } else { illegalArgument("无法识别Member" + raw.content) } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandPermission.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandPermission.kt index af45d41a6..33f95f801 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandPermission.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandPermission.kt @@ -12,10 +12,6 @@ package net.mamoe.mirai.console.command import net.mamoe.mirai.Bot -import net.mamoe.mirai.console.utils.isManager -import net.mamoe.mirai.contact.isAdministrator -import net.mamoe.mirai.contact.isOperator -import net.mamoe.mirai.contact.isOwner /** * 指令权限 @@ -66,7 +62,7 @@ abstract class CommandPermission { constructor(vararg fromBot: Bot) : this(*fromBot.map { it.id }.toLongArray()) override fun CommandSender.hasPermission(): Boolean { - return this is GroupContactCommandSender && this.bot.id in fromBot && this.realSender.isOperator() + return this is MemberCommandSender && this.bot.id in fromBot && this.realSender.isOperator() } /** @@ -74,7 +70,7 @@ abstract class CommandPermission { */ companion object Any : CommandPermission() { override fun CommandSender.hasPermission(): Boolean { - return this is GroupContactCommandSender && this.realSender.isOperator() + return this is MemberCommandSender && this.realSender.isOperator() } } } @@ -91,7 +87,7 @@ abstract class CommandPermission { constructor(vararg fromBot: Bot) : this(*fromBot.map { it.id }.toLongArray()) override fun CommandSender.hasPermission(): Boolean { - return this is GroupContactCommandSender && this.bot.id in fromBot && this.realSender.isOwner() + return this is MemberCommandSender && this.bot.id in fromBot && this.realSender.isOwner() } /** @@ -99,7 +95,7 @@ abstract class CommandPermission { */ companion object Any : CommandPermission() { override fun CommandSender.hasPermission(): Boolean { - return this is GroupContactCommandSender && this.realSender.isOwner() + return this is MemberCommandSender && this.realSender.isOwner() } } } @@ -116,7 +112,7 @@ abstract class CommandPermission { constructor(vararg fromBot: Bot) : this(*fromBot.map { it.id }.toLongArray()) override fun CommandSender.hasPermission(): Boolean { - return this is GroupContactCommandSender && this.bot.id in fromBot && this.realSender.isAdministrator() + return this is MemberCommandSender && this.bot.id in fromBot && this.realSender.isAdministrator() } /** @@ -124,7 +120,7 @@ abstract class CommandPermission { */ companion object Any : CommandPermission() { override fun CommandSender.hasPermission(): Boolean { - return this is GroupContactCommandSender && this.realSender.isAdministrator() + return this is MemberCommandSender && this.realSender.isAdministrator() } } } @@ -141,7 +137,7 @@ abstract class CommandPermission { constructor(vararg fromBot: Bot) : this(*fromBot.map { it.id }.toLongArray()) override fun CommandSender.hasPermission(): Boolean { - return this is GroupContactCommandSender && this.bot.id in fromBot && this.realSender.isManager + return this is MemberCommandSender && this.bot.id in fromBot && this.realSender.isManager } /** @@ -149,7 +145,7 @@ abstract class CommandPermission { */ companion object Any : CommandPermission() { override fun CommandSender.hasPermission(): Boolean { - return this is GroupContactCommandSender && this.realSender.isManager + return this is MemberCommandSender && this.realSender.isManager } } } diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt index e2366374c..0ae71d792 100644 --- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt +++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt @@ -7,13 +7,18 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ +@file:Suppress("NOTHING_TO_INLINE") + package net.mamoe.mirai.console.command import kotlinx.coroutines.runBlocking import net.mamoe.mirai.Bot -import net.mamoe.mirai.contact.Contact +import net.mamoe.mirai.contact.Friend +import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Member +import net.mamoe.mirai.contact.User import net.mamoe.mirai.message.data.Message +import net.mamoe.mirai.message.data.PlainText /** * 指令发送者 @@ -21,13 +26,16 @@ import net.mamoe.mirai.message.data.Message * @see AbstractCommandSender 请继承于该抽象类 */ interface CommandSender { + /** + * 与这个 [CommandSender] 相关的 [Bot]. 当通过控制台执行时为 null. + */ + val bot: Bot? + /** * 立刻发送一条消息 */ suspend fun sendMessage(message: Message) - suspend fun sendMessage(message: String) - /** * 写入要发送的内容 所有内容最后会被以一条发出 */ @@ -37,6 +45,7 @@ interface CommandSender { fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) } } +suspend inline fun CommandSender.sendMessage(message: String) = sendMessage(PlainText(message)) abstract class AbstractCommandSender : CommandSender { internal val builder = StringBuilder() @@ -56,50 +65,56 @@ abstract class AbstractCommandSender : CommandSender { * 控制台指令执行者. 代表由控制台执行指令 */ object ConsoleCommandSender : AbstractCommandSender() { + override val bot: Nothing? get() = null + override suspend fun sendMessage(message: Message) { TODO() // MiraiConsole.logger("[Command]", 0, messageChain.toString()) } - override suspend fun sendMessage(message: String) { - TODO() - // MiraiConsole.logger("[Command]", 0, message) - } - override suspend fun flushMessage() { super.flushMessage() builder.clear() } } -/** - * 指向性CommandSender - * 你可以获得用户在和哪个Bot说指令 - */ -interface BotAware { - val bot: Bot +inline fun Friend.asCommandSender(): FriendCommandSender = FriendCommandSender(this) + +inline fun Member.asCommandSender(): MemberCommandSender = MemberCommandSender(this) + +inline fun User.asCommandSender(): UserCommandSender { + return when (this) { + is Friend -> this.asCommandSender() + is Member -> this.asCommandSender() + else -> error("stub") + } } /** - * 联系人指令执行者. 代表由一个 QQ 用户私聊执行指令 + * 代表一个用户私聊机器人执行指令 + * @see User.asCommandSender */ -@Suppress("MemberVisibilityCanBePrivate") -open class ContactCommandSender(override val bot: Bot, val contact: Contact) : AbstractCommandSender(), BotAware { - override suspend fun sendMessage(message: Message) { - contact.sendMessage(message) - } +sealed class UserCommandSender : AbstractCommandSender() { + abstract val user: User - override suspend fun sendMessage(message: String) { - contact.sendMessage(message) + final override val bot: Bot get() = user.bot + + final override suspend fun sendMessage(message: Message) { + user.sendMessage(message) } } /** - * 联系人指令执行者. 代表由一个 QQ 用户 在群里执行指令 + * 代表一个用户私聊机器人执行指令 + * @see Friend.asCommandSender */ -open class GroupContactCommandSender( - bot: Bot, - val realSender: Member, - subject: Contact -) : ContactCommandSender(bot, subject) \ No newline at end of file +class FriendCommandSender(override val user: Friend) : UserCommandSender() + +/** + * 代表一个群成员在群内执行指令. + * @see Member.asCommandSender + */ +class MemberCommandSender(override val user: Member) : UserCommandSender() { + inline val group: Group get() = user.group +} \ No newline at end of file diff --git a/backend/mirai-console/src/test/java/net/mamoe/mirai/console/command/TestCommands.kt b/backend/mirai-console/src/test/java/net/mamoe/mirai/console/command/TestCommands.kt index 13a6726b7..cb685fab0 100644 --- a/backend/mirai-console/src/test/java/net/mamoe/mirai/console/command/TestCommands.kt +++ b/backend/mirai-console/src/test/java/net/mamoe/mirai/console/command/TestCommands.kt @@ -71,34 +71,34 @@ internal class TestCommands { ) } - inline fun withSender(block: CommandSender.() -> Unit): MessageChain { - val result = MessageChainBuilder() - val sender: CommandSender = object : CommandSender { - override suspend fun sendMessage(message: Message) { - result.add(message) - } - - override suspend fun sendMessage(message: String) { - result.add(message) - } - - override fun appendMessage(message: String) { - result.add(message) - } - } - sender.let(block) - return result.asMessageChain() - } - @Test fun testExecute() = runBlocking { TestCommand.register() assertEquals( "ok", withSender { - execute("test", "ok", "extra") + execute("test", "arg") }.contentToString() ) } } + +internal inline fun withSender(block: CommandSender.() -> Unit): MessageChain { + val result = MessageChainBuilder() + val sender: CommandSender = object : CommandSender { + override suspend fun sendMessage(message: Message) { + result.add(message) + } + + override suspend fun sendMessage(message: String) { + result.add(message) + } + + override fun appendMessage(message: String) { + result.add(message) + } + } + sender.let(block) + return result.asMessageChain() +} \ No newline at end of file