From 51ceafdfe474b3b671cf717446da046c9f0e9b3c Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 21 Mar 2020 15:29:06 +0800 Subject: [PATCH 01/12] Adapt to new API --- .../console/graphical/controller/MiraiGraphicalUIController.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt index 2cab97a46..0b60a8767 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt @@ -78,7 +78,8 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI { } } - override suspend fun requestInput(): String { + override suspend fun requestInput(hint: String): String { + // TODO: 2020/3/21 HINT val model = VerificationCodeModel() find(Scope(model)).openModal( modality = Modality.APPLICATION_MODAL, From 7fb9056572ee4b6550f4eca6f0a70389ec470c40 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 21 Mar 2020 15:52:27 +0800 Subject: [PATCH 02/12] Review: misc improvements --- .../controller/MiraiGraphicalUIController.kt | 6 +- .../mamoe/mirai/console/command/Command.kt | 137 +++++++---------- .../mirai/console/command/CommandManager.kt | 139 +++++++++--------- .../mirai/console/command/CommandSender.kt | 82 +++++++++++ .../mamoe/mirai/console/plugins/PluginBase.kt | 6 +- .../mirai/console/pure/MiraiConsoleUIPure.kt | 4 +- 6 files changed, 218 insertions(+), 156 deletions(-) create mode 100644 mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt index 0b60a8767..0d7431547 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt @@ -6,7 +6,7 @@ import javafx.stage.Modality import javafx.stage.StageStyle import kotlinx.coroutines.delay import net.mamoe.mirai.Bot -import net.mamoe.mirai.console.MiraiConsole +import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.graphical.model.* import net.mamoe.mirai.console.graphical.view.VerificationCodeFragment import net.mamoe.mirai.console.plugins.PluginManager @@ -30,10 +30,10 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI { val consoleInfo = ConsoleInfo() fun login(qq: String, psd: String) { - MiraiConsole.CommandProcessor.runConsoleCommandBlocking("/login $qq $psd") + CommandManager.runConsoleCommand("/login $qq $psd") } - fun sendCommand(command: String) = MiraiConsole.CommandProcessor.runConsoleCommandBlocking(command) + fun sendCommand(command: String) = CommandManager.runConsoleCommand(command) override fun pushLog(identity: Long, message: String) = Platform.runLater { fun ObservableList<*>.trim() { diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt index ad41fcc52..c3b190b75 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt @@ -7,90 +7,53 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -@file:Suppress("NOTHING_TO_INLINE") +@file:Suppress("NOTHING_TO_INLINE", "MemberVisibilityCanBePrivate") package net.mamoe.mirai.console.command import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext -import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.plugins.PluginBase -import net.mamoe.mirai.contact.Contact -import net.mamoe.mirai.contact.sendMessage -import net.mamoe.mirai.message.data.MessageChain -import net.mamoe.mirai.utils.SimpleLogger.LogPriority - -interface CommandSender { - /** - * 立刻发送一条Message - */ - - suspend fun sendMessage(messageChain: MessageChain) - - suspend fun sendMessage(message: String) - - /** - * 写入要发送的内容 所有内容最后会被以一条发出 - */ - fun appendMessage(message: String) - - fun sendMessageBlocking(messageChain: MessageChain) = runBlocking { sendMessage(messageChain) } - fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) } -} - -abstract class CommandSenderImpl : CommandSender { - internal val builder = StringBuilder() - - override fun appendMessage(message: String) { - builder.append(message).append("\n") - } - - internal open suspend fun flushMessage() { - if (!builder.isEmpty()) { - sendMessage(builder.toString().removeSuffix("\n")) - } - } -} - -object ConsoleCommandSender : CommandSenderImpl() { - override suspend fun sendMessage(messageChain: MessageChain) { - MiraiConsole.logger("[Command]", 0, messageChain.toString()) - } - - override suspend fun sendMessage(message: String) { - MiraiConsole.logger("[Command]", 0, message) - } - - override suspend fun flushMessage() { - super.flushMessage() - builder.clear() - } -} - -open class ContactCommandSender(val contact: Contact) : CommandSenderImpl() { - override suspend fun sendMessage(messageChain: MessageChain) { - contact.sendMessage(messageChain) - } - - override suspend fun sendMessage(message: String) { - contact.sendMessage(message) - } -} +/** + * 指令 + * + * @see register 注册这个指令 + * @see registerCommand 注册指令 DSL + */ interface Command { + /** + * 指令主名称 + */ val name: String + + /** + * 别名 + */ val alias: List + + /** + * 描述, 将会显示在 "/help" 指令中 + */ val description: String + + /** + * 用法说明 + */ val usage: String suspend fun onCommand(sender: CommandSender, args: List): Boolean } +/** + * 注册这个指令 + */ inline fun Command.register() = CommandManager.register(this) - -fun registerCommand(builder: CommandBuilder.() -> Unit): Command { +/** + * 构造并注册一个指令 + */ +inline fun registerCommand(builder: CommandBuilder.() -> Unit): Command { return CommandBuilder().apply(builder).register() } @@ -104,8 +67,9 @@ abstract class BlockingCommand( override val usage: String = "" ) : Command { /** - * 最高优先级监听器 - * 如果 return `false`, 这次指令不会被 [PluginBase] 的全局 onCommand 监听器监听 + * 最高优先级监听器. + * + * 指令调用将优先触发 [Command.onCommand], 若该函数返回 `false`, 则不会调用 [PluginBase.onCommand] * */ final override suspend fun onCommand(sender: CommandSender, args: List): Boolean { return withContext(Dispatchers.IO) { @@ -116,7 +80,27 @@ abstract class BlockingCommand( abstract fun onCommandBlocking(sender: CommandSender, args: List): Boolean } -class AnonymousCommand internal constructor( +/** + * @see registerCommand + */ +class CommandBuilder @PublishedApi internal constructor() { + var name: String? = null + var alias: List? = null + var description: String = "" + var usage: String = "use /help for help" + + internal var onCommand: (suspend CommandSender.(args: List) -> Boolean)? = null + + fun onCommand(commandProcess: suspend CommandSender.(args: List) -> Boolean) { + onCommand = commandProcess + } +} + + +// internal + + +internal class AnonymousCommand internal constructor( override val name: String, override val alias: List, override val description: String, @@ -128,19 +112,8 @@ class AnonymousCommand internal constructor( } } -class CommandBuilder internal constructor() { - var name: String? = null - var alias: List? = null - var description: String = "" - var usage: String = "use /help for help" - internal var onCommand: (suspend CommandSender.(args: List) -> Boolean)? = null - - fun onCommand(commandProcess: suspend CommandSender.(args: List) -> Boolean) { - onCommand = commandProcess - } -} - -private fun CommandBuilder.register(): AnonymousCommand { +@PublishedApi +internal fun CommandBuilder.register(): AnonymousCommand { if (name == null || onCommand == null) { error("CommandBuilder not complete") } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt index 3bff9bbd3..43f9f2c33 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt @@ -7,7 +7,7 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ -@file:Suppress("unused") +@file:Suppress("unused", "MemberVisibilityCanBePrivate") package net.mamoe.mirai.console.command @@ -18,7 +18,6 @@ import net.mamoe.mirai.console.plugins.PluginBase import net.mamoe.mirai.console.plugins.PluginManager import java.util.concurrent.Executors - object CommandManager : Job by { GlobalScope.launch(start = CoroutineStart.LAZY) { processCommandQueue() @@ -28,6 +27,11 @@ object CommandManager : Job by { val commands: Collection get() = registeredCommand.values + /** + * 注册这个指令. + * + * @throws IllegalStateException 当已注册的指令与 [command] 重名时 + */ fun register(command: Command) { val allNames = mutableListOf(command.name).also { it.addAll(command.alias) } allNames.forEach { @@ -41,9 +45,10 @@ object CommandManager : Job by { } fun unregister(command: Command) { - (command.alias.asSequence() + command.name).forEach { + command.alias.forEach { registeredCommand.remove(it) } + registeredCommand.remove(command.name) } fun unregister(commandName: String): Boolean { @@ -52,23 +57,65 @@ object CommandManager : Job by { /** - * 指令是单线程运行的 + * 最基础的执行指令的方式 + * 指令将会被加入队列,依次执行 + * + * @param sender 指令执行者, 可为 [ConsoleCommandSender] 或 [ContactCommandSender] */ - private val commandDispatcher = Executors.newFixedThreadPool(1).asCoroutineDispatcher() + fun runCommand(sender: CommandSender, command: String) { + commandChannel.offer( + FullCommand(sender, command) + ) + } /** - * 执行一个指令, 但是如果你想模拟一个指令的执行 - * 请向下看 + * 插队异步执行一个指令并返回 [Deferred] * - * 返回一个指令是否执行成功 + * @param sender 指令执行者, 可为 [ConsoleCommandSender] 或 [ContactCommandSender] + * @see PluginBase.runCommandAsync 扩展 */ - internal suspend fun processCommand(sender: CommandSender, fullCommand: String):Boolean { - return withContext(commandDispatcher) { - _processCommand(sender, fullCommand) + fun runCommandAsync(pluginBase: PluginBase, sender: CommandSender, command: String): Deferred { + return pluginBase.async { + processCommand(sender, command) } } - private suspend fun _processCommand(sender: CommandSender, fullCommand: String): Boolean { + /** + * 插队执行一个指令并返回 [Deferred] + * + * @param sender 指令执行者, 可为 [ConsoleCommandSender] 或 [ContactCommandSender] + * @see PluginBase.runCommandAsync 扩展 + */ + @Suppress("KDocUnresolvedReference") + suspend fun dispatchCommand(sender: CommandSender, command: String): Boolean { + return processCommand(sender, command) + } + + + /** + * 阻塞当前线程, 插队执行一个指令 + * + * @param sender 指令执行者, 可为 [ConsoleCommandSender] 或 [ContactCommandSender] + */ + // for java + fun dispatchCommandBlocking(sender: CommandSender, command: String): Boolean = + runBlocking { dispatchCommand(sender, command) } + + + // internal + + /** + * 单线程执行指令 + */ + private val commandDispatcher = Executors.newFixedThreadPool(1).asCoroutineDispatcher() + + private suspend fun processCommand(sender: CommandSender, fullCommand: String): Boolean { + return withContext(commandDispatcher) { + processCommandImpl(sender, fullCommand) + } + } + + private suspend fun processCommandImpl(sender: CommandSender, fullCommand: String): Boolean { val blocks = fullCommand.split(" ") val commandHead = blocks[0].replace("/", "") val args = blocks.drop(1) @@ -81,17 +128,16 @@ object CommandManager : Job by { sender.sendMessage(this.usage) } } - }catch (e: Exception){ + } catch (e: Exception) { sender.sendMessage("在运行指令时出现了未知错误") e.printStackTrace() false - }finally { + } finally { (sender as CommandSenderImpl).flushMessage() } - }?: throw UnknownCommandException(commandHead) + } ?: throw UnknownCommandException(commandHead) } - internal class FullCommand( val sender: CommandSender, val commandStr: String @@ -103,62 +149,23 @@ object CommandManager : Job by { val command = commandChannel.receive() try { processCommand(command.sender, command.commandStr) - }catch (e:UnknownCommandException){ + } catch (e: UnknownCommandException) { command.sender.sendMessage("未知指令 " + command.commandStr) - }catch (e:Throwable){//should never happen + } catch (e: Throwable) {//should never happen e.printStackTrace() } processCommandQueue() } - - /** - * runCommand()是最基础的执行指令的方式 - * 指令将会被加入队列,依次执行 - * 方法由0.27.0的阻塞模式改为不阻塞(鉴于commandChannel大小无限) - */ - fun runCommand(sender: CommandSender, command: String) { - runBlocking {//it wont be blocking - commandChannel.send( - FullCommand(sender, command) - ) - } - } - - @Suppress("unused") - fun runConsoleCommand(command: String) = runCommand(ConsoleCommandSender,command) - - /** - * runCommandAnsyc()执行一个指令并返回deferred - * 为插队执行 - */ - fun runCommandAsync(pluginBase: PluginBase, sender: CommandSender, command: String):Deferred{ - return pluginBase.async{ - processCommand(sender,command) - } - } - - fun runConsoleCommandAsync(pluginBase: PluginBase, command: String):Deferred = runCommandAsync(pluginBase,ConsoleCommandSender,command) - - /** - * dispatchCommand()执行一个指令并等到完成 - * 为插队执行 - */ - suspend fun dispatchCommand(sender: CommandSender,command: String):Boolean{ - return processCommand(sender,command) - } - - suspend fun dispatchConsoleCommand(command: String):Boolean = dispatchCommand(ConsoleCommandSender,command) - - - fun dispatchCommandBlocking(sender: CommandSender,command: String):Boolean = runBlocking { dispatchCommand(sender, command) } - - fun dispatchConsoleCommandBlocking(command: String):Boolean = runBlocking { dispatchConsoleCommandBlocking(command) } } -fun PluginBase.runCommandAsnyc(sender: CommandSender, command: String):Deferred = CommandManager.runCommandAsync(this,sender,command) - -fun PluginBase.runConsoleCommandAsync(command: String):Deferred = CommandManager.runConsoleCommandAsync(this,command) +/** + * 插队异步执行一个指令并返回 [Deferred] + * + * @param sender 指令执行者, 可为 [ConsoleCommandSender] 或 [ContactCommandSender] + * @see PluginBase.runCommandAsync 扩展 + */ +fun PluginBase.runCommandAsync(sender: CommandSender, command: String): Deferred = + CommandManager.runCommandAsync(this, sender, command) - -class UnknownCommandException(command: String):Exception("unknown command \"$command\"") \ No newline at end of file +class UnknownCommandException(command: String) : Exception("unknown command \"$command\"") \ No newline at end of file diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt new file mode 100644 index 000000000..c6369fa60 --- /dev/null +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + +package net.mamoe.mirai.console.command + +import kotlinx.coroutines.runBlocking +import net.mamoe.mirai.console.MiraiConsole +import net.mamoe.mirai.contact.Contact +import net.mamoe.mirai.contact.sendMessage +import net.mamoe.mirai.message.data.Message + +/** + * 指令发送者 + */ +interface CommandSender { + /** + * 立刻发送一条消息 + */ + suspend fun sendMessage(messageChain: Message) + + suspend fun sendMessage(message: String) + + /** + * 写入要发送的内容 所有内容最后会被以一条发出 + */ + fun appendMessage(message: String) + + fun sendMessageBlocking(messageChain: Message) = runBlocking { sendMessage(messageChain) } + fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) } +} + +abstract class CommandSenderImpl : CommandSender { + internal val builder = StringBuilder() + + override fun appendMessage(message: String) { + builder.append(message).append("\n") + } + + internal open suspend fun flushMessage() { + if (builder.isNotEmpty()) { + sendMessage(builder.toString().removeSuffix("\n")) + } + } +} + +/** + * 控制台指令执行者. 代表由控制台执行指令 + */ +object ConsoleCommandSender : CommandSenderImpl() { + override suspend fun sendMessage(messageChain: Message) { + MiraiConsole.logger("[Command]", 0, messageChain.toString()) + } + + override suspend fun sendMessage(message: String) { + MiraiConsole.logger("[Command]", 0, message) + } + + override suspend fun flushMessage() { + super.flushMessage() + builder.clear() + } +} + +/** + * 联系人指令执行者. 代表由一个 QQ 用户执行指令 + */ +@Suppress("MemberVisibilityCanBePrivate") +open class ContactCommandSender(val contact: Contact) : CommandSenderImpl() { + override suspend fun sendMessage(messageChain: Message) { + contact.sendMessage(messageChain) + } + + override suspend fun sendMessage(message: String) { + contact.sendMessage(message) + } +} diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt index 3f2e6bac9..b9a2992f2 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt @@ -15,10 +15,8 @@ import kotlinx.coroutines.* import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.command.Command import net.mamoe.mirai.console.command.CommandSender -import net.mamoe.mirai.console.pure.MiraiConsoleUIPure import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.SimpleLogger -import net.mamoe.mirai.utils.SimpleLogger.LogPriority import java.io.File import java.io.InputStream import java.net.URLClassLoader @@ -63,7 +61,9 @@ abstract class PluginBase } /** - * 当任意指令被使用 + * 当任意指令被使用时调用. + * + * 指令调用将优先触发 [Command.onCommand], 若该函数返回 `false`, 则不会调用 [PluginBase.onCommand] */ open fun onCommand(command: Command, sender: CommandSender, args: List) { diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt index 5031cce96..289076d20 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt @@ -11,7 +11,7 @@ package net.mamoe.mirai.console.pure import kotlinx.coroutines.delay import net.mamoe.mirai.Bot -import net.mamoe.mirai.console.MiraiConsole +import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.utils.MiraiConsoleUI import net.mamoe.mirai.utils.DefaultLoginSolver import net.mamoe.mirai.utils.LoginSolver @@ -49,7 +49,7 @@ class MiraiConsoleUIPure : MiraiConsoleUI { requestStr = input requesting = false } else { - MiraiConsole.CommandProcessor.runConsoleCommandBlocking(input) + CommandManager.runConsoleCommand(input) } } } From 02173d96df6c1ed49e582271b54f1302042c54e2 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 21 Mar 2020 15:57:48 +0800 Subject: [PATCH 03/12] Review: misc improvements --- .../controller/MiraiGraphicalUIController.kt | 5 +- .../mirai/console/MiraiConsoleTerminalUI.kt | 3 +- .../net/mamoe/mirai/console/MiraiConsole.kt | 71 +++++++++++-------- .../mirai/console/command/DefaultCommands.kt | 2 +- .../mamoe/mirai/console/events/EventsImpl.kt | 11 --- .../mirai/console/pure/MiraiConsoleUIPure.kt | 3 +- 6 files changed, 48 insertions(+), 47 deletions(-) diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt index 0d7431547..8bba7d406 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt @@ -7,6 +7,7 @@ import javafx.stage.StageStyle import kotlinx.coroutines.delay import net.mamoe.mirai.Bot import net.mamoe.mirai.console.command.CommandManager +import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.graphical.model.* import net.mamoe.mirai.console.graphical.view.VerificationCodeFragment import net.mamoe.mirai.console.plugins.PluginManager @@ -30,10 +31,10 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI { val consoleInfo = ConsoleInfo() fun login(qq: String, psd: String) { - CommandManager.runConsoleCommand("/login $qq $psd") + CommandManager.runCommand(ConsoleCommandSender, "/login $qq $psd") } - fun sendCommand(command: String) = CommandManager.runConsoleCommand(command) + fun sendCommand(command: String) = CommandManager.runCommand(ConsoleCommandSender, command) override fun pushLog(identity: Long, message: String) = Platform.runLater { fun ObservableList<*>.trim() { diff --git a/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalUI.kt b/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalUI.kt index a1c52d5f6..93bcd53e5 100644 --- a/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalUI.kt +++ b/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalUI.kt @@ -23,6 +23,7 @@ import net.mamoe.mirai.console.MiraiConsoleTerminalUI.LoggerDrawer.cleanPage import net.mamoe.mirai.console.MiraiConsoleTerminalUI.LoggerDrawer.drawLog import net.mamoe.mirai.console.MiraiConsoleTerminalUI.LoggerDrawer.redrawLogs import net.mamoe.mirai.console.command.CommandManager +import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.utils.MiraiConsoleUI import net.mamoe.mirai.utils.LoginSolver import net.mamoe.mirai.utils.SimpleLogger.LogPriority @@ -124,7 +125,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI { requestResult = input requesting = false } else { - CommandManager.runConsoleCommand(commandBuilder.toString()) + CommandManager.runCommand(ConsoleCommandSender, commandBuilder.toString()) } } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt index 55ac51dd0..0fcf9915b 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt @@ -9,10 +9,11 @@ package net.mamoe.mirai.console -import kotlinx.coroutines.* +import kotlinx.coroutines.runBlocking import net.mamoe.mirai.Bot import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.command.CommandSender +import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.command.DefaultCommands import net.mamoe.mirai.console.plugins.PluginManager import net.mamoe.mirai.console.utils.MiraiConsoleUI @@ -45,14 +46,16 @@ object MiraiConsole { * Console运行路径 */ var path: String = System.getProperty("user.dir") + internal set /** * Console前端接口 */ lateinit var frontEnd: MiraiConsoleUI + internal set - var start = false + private var started = false /** @@ -63,10 +66,10 @@ object MiraiConsole { coreVersion: String = "0.0.0", consoleVersion: String = "0.0.0" ) { - if (start) { + if (started) { return } - start = true + started = true /* 初始化前端 */ this.version = consoleVersion @@ -110,49 +113,55 @@ object MiraiConsole { } } + @Suppress("RedundantSuspendModifier") // binary compatibility @Deprecated("Please use CommandManager directly, this will be removed in later release") - object CommandProcessor{ - @Deprecated("Please use CommandManager directly, this will be removed in later release", ReplaceWith( - "CommandManager.runConsoleCommand(command)", - "net.mamoe.mirai.console.command.CommandManager" - ) + object CommandProcessor { + @Deprecated( + "Please use CommandManager directly, this will be removed in later release", ReplaceWith( + "CommandManager.runConsoleCommand(command)", + "net.mamoe.mirai.console.command.CommandManager" + ), level = DeprecationLevel.ERROR ) suspend fun runConsoleCommand(command: String) { - CommandManager.runConsoleCommand(command) - } - @Deprecated("Please use CommandManager directly, this will be removed in later release", ReplaceWith( - "CommandManager.runCommand(sender, command)", - "net.mamoe.mirai.console.command.CommandManager" - ) - ) - suspend fun runCommand(sender: CommandSender, command: String) { - CommandManager.runCommand(sender,command) + CommandManager.runCommand(ConsoleCommandSender, command) } - @Deprecated("Please use CommandManager directly, this will be removed in later release", ReplaceWith( - "CommandManager.runConsoleCommand(command)", - "net.mamoe.mirai.console.command.CommandManager" + @Deprecated( + "Please use CommandManager directly, this will be removed in later release", ReplaceWith( + "CommandManager.runCommand(sender, command)", + "net.mamoe.mirai.console.command.CommandManager" + ), level = DeprecationLevel.ERROR ) + suspend fun runCommand(sender: CommandSender, command: String) { + CommandManager.runCommand(sender, command) + } + + @Deprecated( + "Please use CommandManager directly, this will be removed in later release", ReplaceWith( + "CommandManager.runCommand(command)", + "net.mamoe.mirai.console.command.CommandManager", + "net.mamoe.mirai.console.command.ConsoleCommandSender" + ), level = DeprecationLevel.ERROR ) - fun runConsoleCommandBlocking(command: String) = runBlocking { runConsoleCommand(command)} + fun runConsoleCommandBlocking(command: String) = + runBlocking { CommandManager.runCommand(ConsoleCommandSender, command) } @Suppress("unused") - @Deprecated("Please use CommandManager directly, this will be removed in later release", ReplaceWith( - "CommandManager.runCommand(sender, command)", - "net.mamoe.mirai.console.command.CommandManager" + @Deprecated( + "Please use CommandManager directly, this will be removed in later release", ReplaceWith( + "CommandManager.runCommand(sender, command)", + "net.mamoe.mirai.console.command.CommandManager" + ) ) - ) - fun runCommandBlocking(sender: CommandSender, command: String) = runBlocking { runCommand(sender, command) } + fun runCommandBlocking(sender: CommandSender, command: String) = runBlocking { + CommandManager.runCommand(sender, command) + } } } -/** - * Mirai Console的logger - * 它用于适配不同的Console前段 - */ internal object MiraiConsoleLogger { operator fun invoke(any: Any? = null) { invoke( diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt index 5232984b0..05d575544 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt @@ -143,7 +143,7 @@ object DefaultCommands { startsWith("/") { message -> if (bot.checkManager(this.sender.id)) { val sender = ContactCommandSender(this.subject) - MiraiConsole.CommandProcessor.runCommand( + CommandManager.runCommand( sender, message ) } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/events/EventsImpl.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/events/EventsImpl.kt index 8e0b06693..7d8b07733 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/events/EventsImpl.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/events/EventsImpl.kt @@ -14,14 +14,3 @@ import net.mamoe.mirai.event.Event import net.mamoe.mirai.event.broadcast internal fun broadcast(e: E): E = runBlocking { e.broadcast() } - -class A{ - - var x = 0 - - var width:Int - get() = x - set(value){ - x = value - } -} \ No newline at end of file diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt index 289076d20..731a3d972 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt @@ -12,6 +12,7 @@ package net.mamoe.mirai.console.pure import kotlinx.coroutines.delay import net.mamoe.mirai.Bot import net.mamoe.mirai.console.command.CommandManager +import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.utils.MiraiConsoleUI import net.mamoe.mirai.utils.DefaultLoginSolver import net.mamoe.mirai.utils.LoginSolver @@ -49,7 +50,7 @@ class MiraiConsoleUIPure : MiraiConsoleUI { requestStr = input requesting = false } else { - CommandManager.runConsoleCommand(input) + CommandManager.runCommand(ConsoleCommandSender, input) } } } From 20e699fb31f73b9446236f753bf510630660f2f5 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 21 Mar 2020 16:07:48 +0800 Subject: [PATCH 04/12] Review: misc improvements --- .../mirai/console/wrapper/ConsoleUpdater.kt | 2 +- .../{CoreUpdator.kt => CoreUpdater.kt} | 2 +- .../mamoe/mirai/console/wrapper/Downloader.kt | 66 +++++++++---------- .../mirai/console/wrapper/WrapperMain.kt | 25 +++---- .../mirai/console/command/CommandSender.kt | 8 ++- .../mamoe/mirai/console/plugins/PluginBase.kt | 52 ++++++++------- .../mirai/console/pure/MiraiConsoleUIPure.kt | 5 +- .../mirai/console/scheduler/SchedulerTask.kt | 48 ++++---------- .../mirai/console/utils/MiraiConsoleUI.kt | 22 +++---- 9 files changed, 104 insertions(+), 126 deletions(-) rename mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/{CoreUpdator.kt => CoreUpdater.kt} (99%) diff --git a/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/ConsoleUpdater.kt b/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/ConsoleUpdater.kt index 237209368..554c3cad9 100644 --- a/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/ConsoleUpdater.kt +++ b/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/ConsoleUpdater.kt @@ -11,7 +11,7 @@ const val CONSOLE_TERMINAL = "Terminal" const val CONSOLE_GRAPHICAL = "Graphical" -object ConsoleUpdater { +internal object ConsoleUpdater { @Suppress("SpellCheckingInspection") private object Links : HashMap>() { diff --git a/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/CoreUpdator.kt b/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/CoreUpdater.kt similarity index 99% rename from mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/CoreUpdator.kt rename to mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/CoreUpdater.kt index 6943cdcc1..fa3a41d61 100644 --- a/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/CoreUpdator.kt +++ b/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/CoreUpdater.kt @@ -20,7 +20,7 @@ import java.net.URLClassLoader import kotlin.math.pow import kotlin.system.exitProcess -object CoreUpdator { +internal object CoreUpdater { fun getProtocolLib(): File? { contentPath.listFiles()?.forEach { file -> diff --git a/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/Downloader.kt b/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/Downloader.kt index f10b1e150..5b63a5757 100644 --- a/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/Downloader.kt +++ b/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/Downloader.kt @@ -1,9 +1,9 @@ @file:Suppress("EXPERIMENTAL_API_USAGE") + package net.mamoe.mirai.console.wrapper import io.ktor.client.HttpClient import io.ktor.client.engine.cio.CIO -import io.ktor.client.features.ClientRequestException import io.ktor.client.request.get import io.ktor.client.statement.HttpResponse import io.ktor.utils.io.ByteReadChannel @@ -11,14 +11,11 @@ import io.ktor.utils.io.jvm.javaio.copyTo import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.File - import kotlin.system.exitProcess -val Http: HttpClient - get() = HttpClient(CIO) +internal val Http: HttpClient = HttpClient(CIO) - -inline fun tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R){ +internal inline fun tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R) { var lastException: Throwable? = null repeat(repeat) { @@ -38,82 +35,84 @@ inline fun tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R } -suspend inline fun HttpClient.downloadRequest(url: String): ByteReadChannel { - return with(this.get(url)){ - if(this.status.value == 404 || this.status.value == 403){ +internal suspend inline fun HttpClient.downloadRequest(url: String): ByteReadChannel { + return with(this.get(url)) { + if (this.status.value == 404 || this.status.value == 403) { error("File not found") } - if(this.headers["status"] !=null && this.headers["status"] == "404"){ + if (this.headers["status"] != null && this.headers["status"] == "404") { error("File not found") } this.content } } -private val jcenterPath = "https://jcenter.bintray.com/{group}/{project}/{version}/:{project}-{version}.{extension}" -private val aliyunPath = "https://maven.aliyun.com/nexus/content/repositories/jcenter/{group}/{project}/{version}/{project}-{version}.{extension}" +private val jcenterPath = "https://jcenter.bintray.com/{group}/{project}/{version}/:{project}-{version}.{extension}" +private val aliyunPath = + "https://maven.aliyun.com/nexus/content/repositories/jcenter/{group}/{project}/{version}/{project}-{version}.{extension}" + private fun String.buildPath( groupName: String, projectName: String, version: String, extension: String -):String{ +): String { return this .replace( - "{group}",groupName + "{group}", groupName ) .replace( - "{project}",projectName + "{project}", projectName ) .replace( - "{extension}",extension + "{extension}", extension ) .replace( - "{version}",version + "{version}", version ) } -suspend fun HttpClient.downloadMaven( +internal suspend fun HttpClient.downloadMaven( groupName: String, projectName: String, version: String, extension: String -):ByteReadChannel{ +): ByteReadChannel { return kotlin.runCatching { downloadRequest( - aliyunPath.buildPath(groupName,projectName,version,extension) + aliyunPath.buildPath(groupName, projectName, version, extension) ) }.getOrElse { downloadRequest( - jcenterPath.buildPath(groupName,projectName,version,extension) + jcenterPath.buildPath(groupName, projectName, version, extension) ) } } -suspend inline fun HttpClient.downloadMavenArchive( +internal suspend inline fun HttpClient.downloadMavenArchive( groupName: String, projectName: String, version: String -):ByteReadChannel{ - return downloadMaven(groupName,projectName,version,"jar") +): ByteReadChannel { + return downloadMaven(groupName, projectName, version, "jar") } -suspend inline fun HttpClient.downloadMavenPom( +internal suspend inline fun HttpClient.downloadMavenPom( groupName: String, projectName: String, version: String -):ByteReadChannel{ - return downloadMaven(groupName,projectName,version,"pom") +): ByteReadChannel { + return downloadMaven(groupName, projectName, version, "pom") } -suspend fun HttpClient.downloadMavenPomAsString( +internal suspend fun HttpClient.downloadMavenPomAsString( groupName: String, projectName: String, version: String -):String{ +): String { return kotlin.runCatching { this.get( - aliyunPath.buildPath(groupName,projectName,version,"pom") + aliyunPath.buildPath(groupName, projectName, version, "pom") ) }.getOrElse { this.get( @@ -123,12 +122,11 @@ suspend fun HttpClient.downloadMavenPomAsString( } - /** - * 只要填content path后面的就可以 + * 只要填 content path 后面的就可以 */ -suspend fun ByteReadChannel.saveToContent(filepath:String){ - val fileStream = File(contentPath.absolutePath + "/" + filepath).also { +internal suspend fun ByteReadChannel.saveToContent(filepath: String) { + val fileStream = File(contentPath.absolutePath + "/" + filepath).also { withContext(Dispatchers.IO) { it.createNewFile() } diff --git a/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/WrapperMain.kt b/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/WrapperMain.kt index f4a47d17b..df9794c79 100644 --- a/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/WrapperMain.kt +++ b/mirai-console-wrapper/src/main/kotlin/net/mamoe/mirai/console/wrapper/WrapperMain.kt @@ -9,7 +9,10 @@ @file:Suppress("EXPERIMENTAL_API_USAGE") package net.mamoe.mirai.console.wrapper -import kotlinx.coroutines.* +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import java.io.File import java.net.URLClassLoader import java.util.* @@ -56,31 +59,31 @@ object WrapperMain { println("Starting version check...") runBlocking { launch { - CoreUpdator.versionCheck() + CoreUpdater.versionCheck() } launch { ConsoleUpdater.versionCheck(type) } } println("Version check complete, starting Mirai") - println("Core :" + CoreUpdator.getCore()!!) - println("Protocol:" + CoreUpdator.getProtocolLib()!!) - println("Console :" + ConsoleUpdater.getFile()!! ) + println("Core :" + CoreUpdater.getCore()!!) + println("Protocol:" + CoreUpdater.getProtocolLib()!!) + println("Console :" + ConsoleUpdater.getFile()!!) println("Root :" + System.getProperty("user.dir") + "/") val loader = MiraiClassLoader( - CoreUpdator.getCore()!!, - CoreUpdator.getProtocolLib()!!, + CoreUpdater.getCore()!!, + CoreUpdater.getProtocolLib()!!, ConsoleUpdater.getFile()!!, this.javaClass.classLoader ) - when(type) { + when (type) { CONSOLE_PURE -> { loader.loadClass("net.mamoe.mirai.BotFactoryJvm") loader.loadClass( - "net.mamoe.mirai.console.pure.MiraiConsolePureLoader" - ).getMethod("load", String::class.java,String::class.java) - .invoke(null,CoreUpdator.getCurrentVersion(),ConsoleUpdater.getCurrentVersion()) + "net.mamoe.mirai.console.pure.MiraiConsolePureLoader" + ).getMethod("load", String::class.java, String::class.java) + .invoke(null, CoreUpdater.getCurrentVersion(), ConsoleUpdater.getCurrentVersion()) } } } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt index c6369fa60..12120bdd4 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandSender.kt @@ -17,6 +17,8 @@ import net.mamoe.mirai.message.data.Message /** * 指令发送者 + * + * @see AbstractCommandSender 请继承于该抽象类 */ interface CommandSender { /** @@ -35,7 +37,7 @@ interface CommandSender { fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) } } -abstract class CommandSenderImpl : CommandSender { +abstract class AbstractCommandSender : CommandSender { internal val builder = StringBuilder() override fun appendMessage(message: String) { @@ -52,7 +54,7 @@ abstract class CommandSenderImpl : CommandSender { /** * 控制台指令执行者. 代表由控制台执行指令 */ -object ConsoleCommandSender : CommandSenderImpl() { +object ConsoleCommandSender : AbstractCommandSender() { override suspend fun sendMessage(messageChain: Message) { MiraiConsole.logger("[Command]", 0, messageChain.toString()) } @@ -71,7 +73,7 @@ object ConsoleCommandSender : CommandSenderImpl() { * 联系人指令执行者. 代表由一个 QQ 用户执行指令 */ @Suppress("MemberVisibilityCanBePrivate") -open class ContactCommandSender(val contact: Contact) : CommandSenderImpl() { +open class ContactCommandSender(val contact: Contact) : AbstractCommandSender() { override suspend fun sendMessage(messageChain: Message) { contact.sendMessage(messageChain) } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt index b9a2992f2..b11f8f8a8 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt @@ -23,7 +23,9 @@ import java.net.URLClassLoader import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext - +/** + * 所有插件的基类 + */ abstract class PluginBase @JvmOverloads constructor(coroutineContext: CoroutineContext = EmptyCoroutineContext) : CoroutineScope { @@ -34,7 +36,7 @@ abstract class PluginBase * 插件被分配的数据目录。数据目录会与插件名称同名。 */ val dataFolder: File by lazy { - File(PluginManager.pluginsPath + "/" + PluginManager.lastPluginName).also { + File(PluginManager.pluginsPath + "/" + pluginName).also { it.mkdir() } } @@ -69,31 +71,13 @@ abstract class PluginBase } - - internal fun enable() { - this.onEnable() - } - /** - * 加载一个data folder中的Config - * 这个config是read-write的 + * 加载一个 [dataFolder] 中的 [Config] */ fun loadConfig(fileName: String): Config { return Config.load(dataFolder.absolutePath + "/" + fileName) } - @JvmOverloads - internal fun disable(throwable: CancellationException? = null) { - this.coroutineContext[Job]!!.cancelChildren(throwable) - try { - this.onDisable() - } catch (e: Exception) { - logger.info(e) - } - } - - internal var pluginName: String = "" - val logger: MiraiLogger by lazy { SimpleLogger("Plugin $pluginName") { priority, message, e -> val identityString = "[${pluginName}]" @@ -120,16 +104,34 @@ abstract class PluginBase /** * 加载 resource 中的 [Config] - * 这个 [Config] 是 read-only 的 + * 这个 [Config] 是只读的 */ fun getResourcesConfig(fileName: String): Config { - if (!fileName.contains(".")) { - error("Unknown Config Type") - } + require(fileName.contains(".")) { "Unknown Config Type" } return Config.load(getResources(fileName) ?: error("No such file: $fileName"), fileName.substringAfter('.')) } + + // internal + + internal fun enable() { + this.onEnable() + } + + internal fun disable(throwable: CancellationException? = null) { + this.coroutineContext[Job]!!.cancelChildren(throwable) + try { + this.onDisable() + } catch (e: Exception) { + logger.info(e) + } + } + + internal var pluginName: String = "" } +/** + * 插件描述 + */ class PluginDescription( val name: String, val author: String, diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt index 731a3d972..85c1986f1 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt @@ -66,8 +66,7 @@ class MiraiConsoleUIPure : MiraiConsoleUI { override fun pushLog(priority: LogPriority, identityStr: String, identity: Long, message: String) { var priorityStr = "[${priority.name}]" - val _message = message + COLOR_RESET - /** + /* * 通过ANSI控制码添加颜色 * 更多的颜色定义在 [MiraiConsoleUIPure] 的 companion */ @@ -86,7 +85,7 @@ class MiraiConsoleUIPure : MiraiConsoleUI { else -> priorityStr } - println("\u001b[0m " + sdf.format(Date()) + " $priorityStr $identityStr $_message") + println("\u001b[0m " + sdf.format(Date()) + " $priorityStr $identityStr ${message + COLOR_RESET}") } override fun prePushBot(identity: Long) { diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/scheduler/SchedulerTask.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/scheduler/SchedulerTask.kt index ac145af57..c648e9453 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/scheduler/SchedulerTask.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/scheduler/SchedulerTask.kt @@ -2,25 +2,25 @@ package net.mamoe.mirai.console.scheduler import net.mamoe.mirai.console.plugins.PluginBase -interface SchedulerTask{ - abstract fun onTick(i:Long) +interface SchedulerTask { + abstract fun onTick(i: Long) abstract fun onRun() } -abstract class RepeatTask( +abstract class RepeatTask( val intervalInMs: Int -):SchedulerTask{ +) : SchedulerTask { override fun onTick(i: Long) { - if(i%intervalInMs == 0L){ + if (i % intervalInMs == 0L) { onRun() } } - companion object{ - fun of( + companion object { + fun of( intervalInMs: Int, runnable: () -> Unit - ):RepeatTask{ + ): RepeatTask { return AnonymousRepeatTask( intervalInMs, runnable ) @@ -28,42 +28,18 @@ abstract class RepeatTask( } } -internal class AnonymousRepeatTask( +internal class AnonymousRepeatTask( intervalInMs: Int, private val runnable: () -> Unit -): RepeatTask(intervalInMs){ +) : RepeatTask(intervalInMs) { override fun onRun() { runnable.invoke() } } -fun T.repeatTask( +fun T.repeatTask( intervalInMs: Int, runnable: () -> Unit -):RepeatTask{ +): RepeatTask { return AnonymousRepeatTask( intervalInMs, runnable ) } - - -fun repeatTask(){ - -} - -class X: PluginBase() { - override fun onLoad() { - //kotlin - this.repeatTask(5){ - - } - //java1 - RepeatTask.of(5){ - - } - //java2 - class Xtask:RepeatTask(5){ - override fun onRun() { - - } - } - } -} \ No newline at end of file diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/MiraiConsoleUI.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/MiraiConsoleUI.kt index 9e784e0cd..84a475362 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/MiraiConsoleUI.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/MiraiConsoleUI.kt @@ -14,15 +14,14 @@ import net.mamoe.mirai.utils.LoginSolver import net.mamoe.mirai.utils.SimpleLogger.LogPriority /** - * 只需要实现一个这个 传入MiraiConsole 就可以绑定UI层与Console层 - * 注意线程 + * 只需要实现一个这个传入 MiraiConsole 就可以绑定 UI 层与 Console 层 + * 需要保证线程安全 */ - interface MiraiConsoleUI { /** - * 让UI层展示一条log + * 让 UI 层展示一条 log * - * identity:log所属的screen, Main=0; Bot=Bot.uin + * identity:log 所属的 screen, Main=0; Bot=Bot.uin */ fun pushLog( identity: Long, @@ -37,14 +36,14 @@ interface MiraiConsoleUI { ) /** - * 让UI层准备接受新增的一个BOT + * 让 UI 层准备接受新增的一个BOT */ fun prePushBot( identity: Long ) /** - * 让UI层接受一个新的bot + * 让 UI 层接受一个新的bot * */ fun pushBot( bot: Bot @@ -58,14 +57,13 @@ interface MiraiConsoleUI { ) /** - * 让UI层提供一个Input - * 这个Input 不 等于 Command + * 让 UI 层提供一个输入, 相当于 [readLine] */ - suspend fun requestInput(hint:String): String + suspend fun requestInput(hint: String): String /** - * 让UI层更新BOT管理员的数据 + * 让 UI 层更新 bot 管理员的数据 */ fun pushBotAdminStatus( identity: Long, @@ -73,7 +71,7 @@ interface MiraiConsoleUI { ) /** - * 由UI层创建一个LoginSolver + * 由 UI 层创建一个 [LoginSolver] */ fun createLoginSolver(): LoginSolver From ba21e354e72650acfd020d6267764e7428189977 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 21 Mar 2020 16:14:40 +0800 Subject: [PATCH 05/12] Review: misc improvements --- .../mirai/console/command/CommandManager.kt | 2 +- .../mamoe/mirai/console/plugins/PluginBase.kt | 5 ++- .../mirai/console/plugins/PluginManager.kt | 33 ++++++++++++------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt index 43f9f2c33..b0b7dd9bc 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt @@ -133,7 +133,7 @@ object CommandManager : Job by { e.printStackTrace() false } finally { - (sender as CommandSenderImpl).flushMessage() + (sender as AbstractCommandSender).flushMessage() } } ?: throw UnknownCommandException(commandHead) } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt index b11f8f8a8..a6c101734 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginBase.kt @@ -36,9 +36,8 @@ abstract class PluginBase * 插件被分配的数据目录。数据目录会与插件名称同名。 */ val dataFolder: File by lazy { - File(PluginManager.pluginsPath + "/" + pluginName).also { - it.mkdir() - } + File(PluginManager.pluginsPath + "/" + PluginManager.lastPluginName) + .also { it.mkdir() } } /** diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt index 6ec9c4d86..59f222c0a 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt @@ -24,9 +24,6 @@ import java.util.jar.JarFile object PluginManager { - @Volatile - internal var lastPluginName: String = "" - internal val pluginsPath = (System.getProperty("user.dir") + "/plugins/").replace("//", "/").also { File(it).mkdirs() } @@ -40,11 +37,11 @@ object PluginManager { private val nameToPluginBaseMap: MutableMap = mutableMapOf() private val pluginDescriptions: MutableMap = mutableMapOf() - fun onCommand(command: Command, sender: CommandSender, args: List) { + internal fun onCommand(command: Command, sender: CommandSender, args: List) { nameToPluginBaseMap.values.forEach { try { it.onCommand(command, sender, args) - }catch (e:Throwable){ + } catch (e: Throwable) { logger.info(e) } } @@ -64,6 +61,10 @@ object PluginManager { return pluginDescriptions.values } + + @Volatile + internal var lastPluginName: String = "" + /** * 尝试加载全部插件 */ @@ -153,27 +154,37 @@ object PluginManager { //real load logger.info("loading plugin " + description.name) - lastPluginName = description.name try { val pluginClass = try { PluginClassLoader( (pluginsLocation[description.name]!!), this.javaClass.classLoader - ) - .loadClass(description.basePath) + ).loadClass(description.basePath) } catch (e: ClassNotFoundException) { logger.info("failed to find Main: " + description.basePath + " checking if it's kotlin's path") PluginClassLoader( (pluginsLocation[description.name]!!), this.javaClass.classLoader - ) - .loadClass("${description.basePath}Kt") + ).loadClass("${description.basePath}Kt") } + return try { val subClass = pluginClass.asSubclass(PluginBase::class.java) + + lastPluginName = description.name val plugin: PluginBase = - subClass.kotlin.objectInstance ?: subClass.getDeclaredConstructor().newInstance() + subClass.kotlin.objectInstance ?: subClass.getDeclaredConstructor().apply { + try { + trySetAccessible() // Java 9+ + } catch (e: Throwable) { + kotlin.runCatching { + isAccessible = true // Java 9- + }.exceptionOrNull()?.printStackTrace() + } + }.newInstance() + plugin.dataFolder // initialize right now + description.loaded = true logger.info("successfully loaded plugin " + description.name + " version " + description.version + " by " + description.author) logger.info(description.info) From 765c240ffbe4722efabf0458bd3579384d1edcf4 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 21 Mar 2020 16:15:36 +0800 Subject: [PATCH 06/12] Add missing copyright --- .../kotlin/net/mamoe/mirai/console/utils/ConsoleInput.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/ConsoleInput.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/ConsoleInput.kt index 9316fd4ca..8295c7012 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/ConsoleInput.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/ConsoleInput.kt @@ -1,3 +1,12 @@ +/* + * Copyright 2020 Mamoe Technologies and contributors. + * + * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. + * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. + * + * https://github.com/mamoe/mirai/blob/master/LICENSE + */ + package net.mamoe.mirai.console.utils import kotlinx.coroutines.* From 97b566f60e94cdb6213e4c59d2dc4ee3cd086457 Mon Sep 17 00:00:00 2001 From: ryoii Date: Sat, 21 Mar 2020 18:50:49 +0800 Subject: [PATCH 07/12] Adapt `requestInput` --- .../controller/MiraiGraphicalUIController.kt | 20 +++++----- .../graphical/view/dialog/InputDialog.kt | 39 +++++++++++++++++++ .../{ => dialog}/VerificationCodeFragment.kt | 5 ++- 3 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/dialog/InputDialog.kt rename mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/{ => dialog}/VerificationCodeFragment.kt (88%) diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt index 8bba7d406..b646c08b9 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt @@ -9,7 +9,8 @@ import net.mamoe.mirai.Bot import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.graphical.model.* -import net.mamoe.mirai.console.graphical.view.VerificationCodeFragment +import net.mamoe.mirai.console.graphical.view.dialog.InputDialog +import net.mamoe.mirai.console.graphical.view.dialog.VerificationCodeFragment import net.mamoe.mirai.console.plugins.PluginManager import net.mamoe.mirai.console.utils.MiraiConsoleUI import net.mamoe.mirai.network.WrongPasswordException @@ -80,13 +81,14 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI { } override suspend fun requestInput(hint: String): String { - // TODO: 2020/3/21 HINT - val model = VerificationCodeModel() - find(Scope(model)).openModal( - modality = Modality.APPLICATION_MODAL, - resizable = false - ) - return model.code.value + var ret: String? = null + + // UI必须在UI线程执行,requestInput在协程种被调用 + Platform.runLater { + ret = InputDialog(hint).open() + } + while (ret == null) { delay(1000) } + return ret!! } override fun pushBotAdminStatus(identity: Long, admins: List) = Platform.runLater { @@ -104,7 +106,7 @@ class GraphicalLoginSolver : LoginSolver() { override suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String? { val code = VerificationCodeModel(VerificationCode(data)) - // 界面需要运行在主线程 + // UI必须在UI线程执行,requestInput在协程种被调用 Platform.runLater { find(Scope(code)).openModal( stageStyle = StageStyle.UNDECORATED, diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/dialog/InputDialog.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/dialog/InputDialog.kt new file mode 100644 index 000000000..bbff1378e --- /dev/null +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/dialog/InputDialog.kt @@ -0,0 +1,39 @@ +package net.mamoe.mirai.console.graphical.view.dialog + +import javafx.scene.control.TextField +import javafx.stage.Modality +import javafx.stage.StageStyle +import tornadofx.* + +class InputDialog(title: String) : Fragment() { + + private lateinit var input: TextField + + init { + titleProperty.value = title + } + + override val root = form { + + fieldset { + field(title) { + input = textfield("") + } + + buttonbar { + + button("提交").action { close() } + } + } + } + + fun open(): String { + // 阻塞窗口直到关闭 + openModal( + stageStyle = StageStyle.DECORATED, + modality = Modality.APPLICATION_MODAL, + block = true + ) + return input.text + } +} \ No newline at end of file diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/VerificationCodeFragment.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/dialog/VerificationCodeFragment.kt similarity index 88% rename from mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/VerificationCodeFragment.kt rename to mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/dialog/VerificationCodeFragment.kt index e23b26abe..8fc871d81 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/VerificationCodeFragment.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/dialog/VerificationCodeFragment.kt @@ -1,4 +1,4 @@ -package net.mamoe.mirai.console.graphical.view +package net.mamoe.mirai.console.graphical.view.dialog import javafx.scene.image.Image import net.mamoe.mirai.console.graphical.model.VerificationCodeModel @@ -30,7 +30,8 @@ class VerificationCodeFragment : Fragment() { this@VerificationCodeFragment.close() } button("取消").action { - code.code.value = MAGIC_KEY + code.code.value = + MAGIC_KEY code.commit() this@VerificationCodeFragment.close() } From 6aa8f6a75b0d79382905a0d3cd80defc48e6a6da Mon Sep 17 00:00:00 2001 From: ryoii Date: Sat, 21 Mar 2020 23:31:47 +0800 Subject: [PATCH 08/12] color --- .../graphical/styleSheet/BaseStyleSheet.kt | 15 +++++++++++ .../styleSheet/LoginViewStyleSheet.kt | 12 ++++++--- .../graphical/styleSheet/PrimaryStyleSheet.kt | 26 ++++++++++++++++--- .../console/graphical/view/PrimaryView.kt | 4 ++- 4 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/BaseStyleSheet.kt diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/BaseStyleSheet.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/BaseStyleSheet.kt new file mode 100644 index 000000000..d7bb3cbca --- /dev/null +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/BaseStyleSheet.kt @@ -0,0 +1,15 @@ +package net.mamoe.mirai.console.graphical.styleSheet + +import tornadofx.Stylesheet +import tornadofx.c + +open class BaseStyleSheet : Stylesheet() { + + companion object { + const val primaryColor = "0EA987" + const val stressColor = "35867C" + const val secondaryColor = "32CABA" + const val lightColor ="9FD1CC" + const val FontColor = "FFFFFF" + } +} \ No newline at end of file diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/LoginViewStyleSheet.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/LoginViewStyleSheet.kt index 6e0b1f69c..06fb8166b 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/LoginViewStyleSheet.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/LoginViewStyleSheet.kt @@ -7,7 +7,7 @@ import javafx.scene.paint.Color import javafx.scene.text.FontWeight import tornadofx.* -class LoginViewStyleSheet : Stylesheet() { +class LoginViewStyleSheet : BaseStyleSheet() { companion object { val vBox by csselement("VBox") @@ -15,11 +15,14 @@ class LoginViewStyleSheet : Stylesheet() { init { + /* + * center box + */ vBox { maxWidth = 500.px maxHeight = 500.px - backgroundColor += c("39c5BB", 0.3) + backgroundColor += c(primaryColor, 0.3) backgroundRadius += box(15.px) padding = box(50.px, 100.px) @@ -35,8 +38,11 @@ class LoginViewStyleSheet : Stylesheet() { fontWeight = FontWeight.BOLD } + /* + * login button + */ button { - backgroundColor += c("00BCD4", 0.8) + backgroundColor += c(stressColor, 0.8) padding = box(10.px, 0.px) prefWidth = 500.px textFill = Color.WHITE diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/PrimaryStyleSheet.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/PrimaryStyleSheet.kt index 8f47b7a39..593dad8d9 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/PrimaryStyleSheet.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/PrimaryStyleSheet.kt @@ -1,21 +1,39 @@ package net.mamoe.mirai.console.graphical.styleSheet -import tornadofx.* +import tornadofx.box +import tornadofx.c +import tornadofx.cssclass +import tornadofx.px -class PrimaryStyleSheet : Stylesheet() { +class PrimaryStyleSheet : BaseStyleSheet() { companion object { + // window val jfxTitle by cssclass("jfx-decorator-buttons-container") val container by cssclass("jfx-decorator-content-container") + + // tab + val tabPane by cssclass("tab-header-background") } init { + /* + * window + */ jfxTitle { - backgroundColor += c("00BCD4") + backgroundColor += c(primaryColor) } container { - borderColor += box(c("00BCD4")) + borderColor += box(c(primaryColor)) borderWidth += box(0.px, 4.px, 4.px, 4.px) } + + + /* + * tab pane + */ + tabPane { + backgroundColor += c(primaryColor) + } } } \ No newline at end of file diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/PrimaryView.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/PrimaryView.kt index c858aea81..0f9601cec 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/PrimaryView.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/PrimaryView.kt @@ -23,7 +23,9 @@ class PrimaryView : View() { left = vbox { - imageview(Image(PrimaryView::class.java.classLoader.getResourceAsStream("logo.png"))) + imageview(Image(PrimaryView::class.java.classLoader.getResourceAsStream("logo.png"))) { + isPreserveRatio = true + } // bot list jfxListView(controller.botList) { From 1b60a1b49990b5efc33ccb75f20cb7c7d6327cbe Mon Sep 17 00:00:00 2001 From: ryoii Date: Sun, 22 Mar 2020 00:21:28 +0800 Subject: [PATCH 09/12] Real closable tab --- .../graphical/styleSheet/PrimaryStyleSheet.kt | 24 ++++++++++++++----- .../console/graphical/util/JFoenixAdaptor.kt | 3 +-- .../console/graphical/view/PrimaryView.kt | 12 ++++++---- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/PrimaryStyleSheet.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/PrimaryStyleSheet.kt index 593dad8d9..5b8580d07 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/PrimaryStyleSheet.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/styleSheet/PrimaryStyleSheet.kt @@ -1,9 +1,8 @@ package net.mamoe.mirai.console.graphical.styleSheet -import tornadofx.box -import tornadofx.c -import tornadofx.cssclass -import tornadofx.px +import javafx.scene.Cursor +import javafx.scene.paint.Color +import tornadofx.* class PrimaryStyleSheet : BaseStyleSheet() { companion object { @@ -12,7 +11,8 @@ class PrimaryStyleSheet : BaseStyleSheet() { val container by cssclass("jfx-decorator-content-container") // tab - val tabPane by cssclass("tab-header-background") + val jfxTabPane by cssclass("tab-header-background") + val closeButton by cssclass("tab-close-button") } init { @@ -32,8 +32,20 @@ class PrimaryStyleSheet : BaseStyleSheet() { /* * tab pane */ - tabPane { + jfxTabPane { backgroundColor += c(primaryColor) } + + // 去除JFoenix默认样式 + tab { + and(":closable") { + borderWidth += box(0.px) + borderInsets += box(6.px, 0.px) + } + + closeButton { + and(hover) { cursor = Cursor.HAND } + } + } } } \ No newline at end of file diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/util/JFoenixAdaptor.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/util/JFoenixAdaptor.kt index 394cd82fa..c81136fb9 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/util/JFoenixAdaptor.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/util/JFoenixAdaptor.kt @@ -8,12 +8,11 @@ import javafx.event.EventTarget import javafx.scene.Node import javafx.scene.control.Button import javafx.scene.control.ListView -import javafx.scene.control.TabPane import tornadofx.SortedFilteredList import tornadofx.attachTo import tornadofx.bind -internal fun EventTarget.jfxTabPane(op: TabPane.() -> Unit = {}) = JFXTabPane().attachTo(this, op) +internal fun EventTarget.jfxTabPane(op: JFXTabPane.() -> Unit = {}) = JFXTabPane().attachTo(this, op) internal fun EventTarget.jfxButton(text: String = "", graphic: Node? = null, op: Button.() -> Unit = {}) = JFXButton(text).attachTo(this, op) { diff --git a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/PrimaryView.kt b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/PrimaryView.kt index 0f9601cec..11d7f88bc 100644 --- a/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/PrimaryView.kt +++ b/mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/view/PrimaryView.kt @@ -72,13 +72,15 @@ class PrimaryView : View() { center = jfxTabPane { + tabClosingPolicy = TabPane.TabClosingPolicy.ALL_TABS + logTab("Main", controller.mainLog, closeable = false) - tab("Plugins").content = find().root + tab("Plugins").apply { isClosable = false }.content = find().root - tab("Settings").content = find().root + tab("Settings").apply { isClosable = false }.content = find().root - tab("Login").content = find().root + tab("Login").apply { isClosable = false }.content = find().root mainTabPane = this } @@ -97,6 +99,8 @@ private fun TabPane.logTab( op: Tab.() -> Unit = {} ) = tab(text) { + this.isClosable = closeable + vbox { buttonbar { @@ -119,8 +123,6 @@ private fun TabPane.logTab( }.ui {// isSucceed: Boolean -> // notify something } - - if (closeable) button("关闭").action { close() } } } From d0b7fdfa712034915073ddb460a24426304abb23 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 22 Mar 2020 00:49:51 +0800 Subject: [PATCH 10/12] Fix build --- .../mirai/console/plugins/PluginManager.kt | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt index 59f222c0a..76be17b46 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt @@ -19,6 +19,8 @@ import net.mamoe.mirai.utils.SimpleLogger import net.mamoe.mirai.utils.io.encodeToString import java.io.File import java.io.InputStream +import java.lang.reflect.Constructor +import java.lang.reflect.Method import java.net.URL import java.util.jar.JarFile @@ -175,13 +177,7 @@ object PluginManager { lastPluginName = description.name val plugin: PluginBase = subClass.kotlin.objectInstance ?: subClass.getDeclaredConstructor().apply { - try { - trySetAccessible() // Java 9+ - } catch (e: Throwable) { - kotlin.runCatching { - isAccessible = true // Java 9- - }.exceptionOrNull()?.printStackTrace() - } + againstPermission() }.newInstance() plugin.dataFolder // initialize right now @@ -211,8 +207,8 @@ object PluginManager { nameToPluginBaseMap.values.forEach { try { it.onLoad() - }catch (ignored : Throwable){ - if(ignored is CancellationException) { + } catch (ignored: Throwable) { + if (ignored is CancellationException) { logger.info(ignored) logger.info(it.pluginName + " failed to load, disabling it") it.disable(ignored) @@ -223,10 +219,10 @@ object PluginManager { nameToPluginBaseMap.values.forEach { try { it.enable() - }catch (ignored : Throwable){ + } catch (ignored: Throwable) { logger.info(ignored) logger.info(it.pluginName + " failed to enable, disabling it") - if(ignored is CancellationException) { + if (ignored is CancellationException) { it.disable(ignored) } } @@ -249,7 +245,7 @@ object PluginManager { */ fun getJarFileByName(pluginName: String): File? { File(pluginsPath).listFiles()?.forEach { file -> - if (file != null && file.extension == "jar") { + if (file != null && file.extension == "jar") { val jar = JarFile(file) val pluginYml = jar.entries().asSequence().filter { it.name.toLowerCase().contains("plugin.yml") }.firstOrNull() @@ -281,4 +277,18 @@ object PluginManager { return URL("jar:file:" + jarFile.absoluteFile + "!/" + toFindFile.name).openConnection().inputStream } + } + + +private val trySetAccessibleMethod: Method? = runCatching { + Class.forName("java.lang.reflect.AccessibleObject").getMethod("trySetAccessible") +}.getOrNull() + +private fun Constructor.againstPermission() { + trySetAccessibleMethod?.let { it.invoke(this, true) } + ?: kotlin.runCatching { + @Suppress("DEPRECATED") + this.isAccessible = true + } +} \ No newline at end of file From ab6c15f16f8d4041f3813245c734c878156bc51a Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 22 Mar 2020 13:38:58 +0800 Subject: [PATCH 11/12] Add priority to PluginManager.logger --- .../kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt index 76be17b46..529e197fc 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt @@ -30,9 +30,9 @@ object PluginManager { File(it).mkdirs() } - private val logger = SimpleLogger("Plugin Manager") { _, message, e -> - MiraiConsole.logger("[Plugin Manager]", 0, message) - MiraiConsole.logger("[Plugin Manager]", 0, e) + private val logger = SimpleLogger("Plugin Manager") { p, message, e -> + MiraiConsole.logger(p, "[Plugin Manager]", 0, message) + MiraiConsole.logger(p, "[Plugin Manager]", 0, e) } //已完成加载的 From cafb0c04f69fe33365efcfa396e766c5a8ddafa6 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 22 Mar 2020 15:37:17 +0800 Subject: [PATCH 12/12] Bump mirai version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 2922fad0b..7e3cc1269 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ # style guide kotlin.code.style=official # config -miraiVersion=0.26.1 +miraiVersion=0.28.0 miraiConsoleVersion=0.3.4 miraiConsoleWrapperVersion=0.1.3 kotlin.incremental.multiplatform=true