Improve CommandSender

This commit is contained in:
Him188 2020-05-14 16:52:11 +08:00
parent b857c8ad41
commit ffe9f5f992
5 changed files with 83 additions and 72 deletions

View File

@ -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

View File

@ -141,8 +141,8 @@ object ExistFriendArgParser : CommandArgParser<Friend>() {
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<Friend>() {
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<Friend>() {
object ExistGroupArgParser : CommandArgParser<Group>() {
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<Member>() {
}
} 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<Member>() {
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)
}

View File

@ -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
}
}
}

View File

@ -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)
class FriendCommandSender(override val user: Friend) : UserCommandSender()
/**
* 代表一个群成员在群内执行指令.
* @see Member.asCommandSender
*/
class MemberCommandSender(override val user: Member) : UserCommandSender() {
inline val group: Group get() = user.group
}

View File

@ -71,7 +71,20 @@ internal class TestCommands {
)
}
inline fun withSender(block: CommandSender.() -> Unit): MessageChain {
@Test
fun testExecute() = runBlocking {
TestCommand.register()
assertEquals(
"ok",
withSender {
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) {
@ -89,16 +102,3 @@ internal class TestCommands {
sender.let(block)
return result.asMessageChain()
}
@Test
fun testExecute() = runBlocking {
TestCommand.register()
assertEquals(
"ok",
withSender {
execute("test", "ok", "extra")
}.contentToString()
)
}
}