mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 18:40:15 +08:00
Improve CommandSender
This commit is contained in:
parent
b857c8ad41
commit
ffe9f5f992
@ -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,
|
owner: PluginBase,
|
||||||
descriptor: CommandDescriptor
|
descriptor: CommandDescriptor
|
||||||
) : PluginCommand(owner, descriptor) {
|
) : PluginCommand(owner, descriptor) {
|
||||||
final override suspend fun onCommand(sender: CommandSender, args: CommandArgs): Boolean {
|
final override suspend fun CommandSender.onCommand(args: CommandArgs): Boolean {
|
||||||
return withContext(Dispatchers.IO) { onCommandBlocking(sender, args) }
|
return withContext(Dispatchers.IO) { onCommandBlocking(this@onCommand, args) }
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun onCommandBlocking(sender: CommandSender, args: CommandArgs): Boolean
|
abstract fun onCommandBlocking(sender: CommandSender, args: CommandArgs): Boolean
|
||||||
|
@ -141,8 +141,8 @@ object ExistFriendArgParser : CommandArgParser<Friend>() {
|
|||||||
illegalArgument("无法解析~作为默认")
|
illegalArgument("无法解析~作为默认")
|
||||||
}
|
}
|
||||||
val targetID = when (sender) {
|
val targetID = when (sender) {
|
||||||
is GroupContactCommandSender -> sender.realSender.id
|
is MemberCommandSender -> sender.realSender.id
|
||||||
is ContactCommandSender -> sender.contact.id
|
is UserCommandSender -> sender.user.id
|
||||||
else -> illegalArgument("无法解析~作为默认")
|
else -> illegalArgument("无法解析~作为默认")
|
||||||
}
|
}
|
||||||
return try {
|
return try {
|
||||||
@ -177,7 +177,7 @@ object ExistFriendArgParser : CommandArgParser<Friend>() {
|
|||||||
|
|
||||||
override fun parse(raw: SingleMessage, sender: CommandSender): Friend {
|
override fun parse(raw: SingleMessage, sender: CommandSender): Friend {
|
||||||
if (raw is At) {
|
if (raw is At) {
|
||||||
assert(sender is GroupContactCommandSender)
|
assert(sender is MemberCommandSender)
|
||||||
return (sender as BotAware).bot.friends.getOrNull(raw.target) ?: illegalArgument("At的对象非Bot好友")
|
return (sender as BotAware).bot.friends.getOrNull(raw.target) ?: illegalArgument("At的对象非Bot好友")
|
||||||
} else {
|
} else {
|
||||||
error("无法解析 $raw 为好友")
|
error("无法解析 $raw 为好友")
|
||||||
@ -188,8 +188,8 @@ object ExistFriendArgParser : CommandArgParser<Friend>() {
|
|||||||
object ExistGroupArgParser : CommandArgParser<Group>() {
|
object ExistGroupArgParser : CommandArgParser<Group>() {
|
||||||
override fun parse(raw: String, sender: CommandSender): Group {
|
override fun parse(raw: String, sender: CommandSender): Group {
|
||||||
//by default
|
//by default
|
||||||
if ((raw == "" || raw == "~") && sender is GroupContactCommandSender) {
|
if ((raw == "" || raw == "~") && sender is MemberCommandSender) {
|
||||||
return sender.contact as Group
|
return sender.user as Group
|
||||||
}
|
}
|
||||||
//from bot to group
|
//from bot to group
|
||||||
if (sender is BotAware) {
|
if (sender is BotAware) {
|
||||||
@ -255,8 +255,8 @@ object ExistMemberArgParser : CommandArgParser<Member>() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val bot = sender.bot
|
val bot = sender.bot
|
||||||
if (sender is GroupContactCommandSender) {
|
if (sender is MemberCommandSender) {
|
||||||
val group = sender.contact as Group
|
val group = sender.user as Group
|
||||||
return try {
|
return try {
|
||||||
group.members[raw.toLong()]
|
group.members[raw.toLong()]
|
||||||
} catch (ignored: Exception) {
|
} catch (ignored: Exception) {
|
||||||
@ -288,8 +288,8 @@ object ExistMemberArgParser : CommandArgParser<Member>() {
|
|||||||
|
|
||||||
override fun parse(raw: SingleMessage, sender: CommandSender): Member {
|
override fun parse(raw: SingleMessage, sender: CommandSender): Member {
|
||||||
return if (raw is At) {
|
return if (raw is At) {
|
||||||
checkArgument(sender is GroupContactCommandSender)
|
checkArgument(sender is MemberCommandSender)
|
||||||
(sender.contact as Group).members[raw.target]
|
(sender.user as Group).members[raw.target]
|
||||||
} else {
|
} else {
|
||||||
illegalArgument("无法识别Member" + raw.content)
|
illegalArgument("无法识别Member" + raw.content)
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,6 @@
|
|||||||
package net.mamoe.mirai.console.command
|
package net.mamoe.mirai.console.command
|
||||||
|
|
||||||
import net.mamoe.mirai.Bot
|
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())
|
constructor(vararg fromBot: Bot) : this(*fromBot.map { it.id }.toLongArray())
|
||||||
|
|
||||||
override fun CommandSender.hasPermission(): Boolean {
|
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() {
|
companion object Any : CommandPermission() {
|
||||||
override fun CommandSender.hasPermission(): Boolean {
|
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())
|
constructor(vararg fromBot: Bot) : this(*fromBot.map { it.id }.toLongArray())
|
||||||
|
|
||||||
override fun CommandSender.hasPermission(): Boolean {
|
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() {
|
companion object Any : CommandPermission() {
|
||||||
override fun CommandSender.hasPermission(): Boolean {
|
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())
|
constructor(vararg fromBot: Bot) : this(*fromBot.map { it.id }.toLongArray())
|
||||||
|
|
||||||
override fun CommandSender.hasPermission(): Boolean {
|
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() {
|
companion object Any : CommandPermission() {
|
||||||
override fun CommandSender.hasPermission(): Boolean {
|
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())
|
constructor(vararg fromBot: Bot) : this(*fromBot.map { it.id }.toLongArray())
|
||||||
|
|
||||||
override fun CommandSender.hasPermission(): Boolean {
|
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() {
|
companion object Any : CommandPermission() {
|
||||||
override fun CommandSender.hasPermission(): Boolean {
|
override fun CommandSender.hasPermission(): Boolean {
|
||||||
return this is GroupContactCommandSender && this.realSender.isManager
|
return this is MemberCommandSender && this.realSender.isManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,18 @@
|
|||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("NOTHING_TO_INLINE")
|
||||||
|
|
||||||
package net.mamoe.mirai.console.command
|
package net.mamoe.mirai.console.command
|
||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import net.mamoe.mirai.Bot
|
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.Member
|
||||||
|
import net.mamoe.mirai.contact.User
|
||||||
import net.mamoe.mirai.message.data.Message
|
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 请继承于该抽象类
|
* @see AbstractCommandSender 请继承于该抽象类
|
||||||
*/
|
*/
|
||||||
interface CommandSender {
|
interface CommandSender {
|
||||||
|
/**
|
||||||
|
* 与这个 [CommandSender] 相关的 [Bot]. 当通过控制台执行时为 null.
|
||||||
|
*/
|
||||||
|
val bot: Bot?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 立刻发送一条消息
|
* 立刻发送一条消息
|
||||||
*/
|
*/
|
||||||
suspend fun sendMessage(message: Message)
|
suspend fun sendMessage(message: Message)
|
||||||
|
|
||||||
suspend fun sendMessage(message: String)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写入要发送的内容 所有内容最后会被以一条发出
|
* 写入要发送的内容 所有内容最后会被以一条发出
|
||||||
*/
|
*/
|
||||||
@ -37,6 +45,7 @@ interface CommandSender {
|
|||||||
fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) }
|
fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend inline fun CommandSender.sendMessage(message: String) = sendMessage(PlainText(message))
|
||||||
|
|
||||||
abstract class AbstractCommandSender : CommandSender {
|
abstract class AbstractCommandSender : CommandSender {
|
||||||
internal val builder = StringBuilder()
|
internal val builder = StringBuilder()
|
||||||
@ -56,50 +65,56 @@ abstract class AbstractCommandSender : CommandSender {
|
|||||||
* 控制台指令执行者. 代表由控制台执行指令
|
* 控制台指令执行者. 代表由控制台执行指令
|
||||||
*/
|
*/
|
||||||
object ConsoleCommandSender : AbstractCommandSender() {
|
object ConsoleCommandSender : AbstractCommandSender() {
|
||||||
|
override val bot: Nothing? get() = null
|
||||||
|
|
||||||
override suspend fun sendMessage(message: Message) {
|
override suspend fun sendMessage(message: Message) {
|
||||||
TODO()
|
TODO()
|
||||||
// MiraiConsole.logger("[Command]", 0, messageChain.toString())
|
// MiraiConsole.logger("[Command]", 0, messageChain.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendMessage(message: String) {
|
|
||||||
TODO()
|
|
||||||
// MiraiConsole.logger("[Command]", 0, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun flushMessage() {
|
override suspend fun flushMessage() {
|
||||||
super.flushMessage()
|
super.flushMessage()
|
||||||
builder.clear()
|
builder.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
inline fun Friend.asCommandSender(): FriendCommandSender = FriendCommandSender(this)
|
||||||
* 指向性CommandSender
|
|
||||||
* 你可以获得用户在和哪个Bot说指令
|
inline fun Member.asCommandSender(): MemberCommandSender = MemberCommandSender(this)
|
||||||
*/
|
|
||||||
interface BotAware {
|
inline fun User.asCommandSender(): UserCommandSender {
|
||||||
val bot: Bot
|
return when (this) {
|
||||||
|
is Friend -> this.asCommandSender()
|
||||||
|
is Member -> this.asCommandSender()
|
||||||
|
else -> error("stub")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 联系人指令执行者. 代表由一个 QQ 用户私聊执行指令
|
* 代表一个用户私聊机器人执行指令
|
||||||
|
* @see User.asCommandSender
|
||||||
*/
|
*/
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
sealed class UserCommandSender : AbstractCommandSender() {
|
||||||
open class ContactCommandSender(override val bot: Bot, val contact: Contact) : AbstractCommandSender(), BotAware {
|
abstract val user: User
|
||||||
override suspend fun sendMessage(message: Message) {
|
|
||||||
contact.sendMessage(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun sendMessage(message: String) {
|
final override val bot: Bot get() = user.bot
|
||||||
contact.sendMessage(message)
|
|
||||||
|
final override suspend fun sendMessage(message: Message) {
|
||||||
|
user.sendMessage(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 联系人指令执行者. 代表由一个 QQ 用户 在群里执行指令
|
* 代表一个用户私聊机器人执行指令
|
||||||
|
* @see Friend.asCommandSender
|
||||||
*/
|
*/
|
||||||
open class GroupContactCommandSender(
|
class FriendCommandSender(override val user: Friend) : UserCommandSender()
|
||||||
bot: Bot,
|
|
||||||
val realSender: Member,
|
/**
|
||||||
subject: Contact
|
* 代表一个群成员在群内执行指令.
|
||||||
) : ContactCommandSender(bot, subject)
|
* @see Member.asCommandSender
|
||||||
|
*/
|
||||||
|
class MemberCommandSender(override val user: Member) : UserCommandSender() {
|
||||||
|
inline val group: Group get() = user.group
|
||||||
|
}
|
@ -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
|
@Test
|
||||||
fun testExecute() = runBlocking {
|
fun testExecute() = runBlocking {
|
||||||
TestCommand.register()
|
TestCommand.register()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
"ok",
|
"ok",
|
||||||
withSender {
|
withSender {
|
||||||
execute("test", "ok", "extra")
|
execute("test", "arg")
|
||||||
}.contentToString()
|
}.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()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user