Ver Fonte

Review: misc improvements

Him188 há 6 anos atrás
pai
commit
62001cc1a8

+ 1 - 1
gradle.properties

@@ -2,7 +2,7 @@
 kotlin.code.style=official
 # config
 miraiVersion=0.24.1
-mirai_console_version=0.3.1
+miraiConsoleVersion=0.3.1
 kotlin.incremental.multiplatform=true
 kotlin.parallel.tasks.in.project=true
 # kotlin

+ 2 - 2
mirai-console-graphical/src/main/kotlin/net/mamoe/mirai/console/graphical/controller/MiraiGraphicalUIController.kt

@@ -3,7 +3,6 @@ package net.mamoe.mirai.console.graphical.controller
 import javafx.application.Platform
 import javafx.collections.ObservableList
 import javafx.stage.Modality
-import kotlinx.io.core.IoBuffer
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.console.MiraiConsole
 import net.mamoe.mirai.console.graphical.model.BotModel
@@ -11,6 +10,7 @@ import net.mamoe.mirai.console.graphical.model.ConsoleInfo
 import net.mamoe.mirai.console.graphical.model.PluginModel
 import net.mamoe.mirai.console.graphical.model.VerificationCodeModel
 import net.mamoe.mirai.console.graphical.view.VerificationCodeFragment
+import net.mamoe.mirai.console.plugins.PluginManager
 import net.mamoe.mirai.console.utils.MiraiConsoleUI
 import net.mamoe.mirai.utils.LoginSolver
 import tornadofx.*
@@ -75,7 +75,7 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
     override fun createLoginSolver(): LoginSolver = loginSolver
 
     private fun getPluginsFromConsole(): ObservableList<PluginModel> =
-        MiraiConsole.pluginManager.getAllPluginDescriptions().map(::PluginModel).toObservable()
+        PluginManager.getAllPluginDescriptions().map(::PluginModel).toObservable()
 
 }
 

+ 45 - 69
mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalUI.kt

@@ -1,3 +1,5 @@
+@file:Suppress("MemberVisibilityCanBePrivate")
+
 package net.mamoe.mirai.console
 
 import com.googlecode.lanterna.SGR
@@ -8,7 +10,6 @@ import com.googlecode.lanterna.input.KeyStroke
 import com.googlecode.lanterna.input.KeyType
 import com.googlecode.lanterna.terminal.DefaultTerminalFactory
 import com.googlecode.lanterna.terminal.Terminal
-import com.googlecode.lanterna.terminal.TerminalResizeListener
 import com.googlecode.lanterna.terminal.swing.SwingTerminal
 import com.googlecode.lanterna.terminal.swing.SwingTerminalFrame
 import kotlinx.coroutines.*
@@ -16,7 +17,6 @@ import kotlinx.coroutines.io.ByteWriteChannel
 import kotlinx.coroutines.io.close
 import kotlinx.coroutines.io.jvm.nio.copyTo
 import kotlinx.coroutines.io.reader
-import kotlinx.io.core.IoBuffer
 import kotlinx.io.core.use
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.console.MiraiConsoleTerminalUI.LoggerDrawer.cleanPage
@@ -51,49 +51,26 @@ import kotlin.system.exitProcess
  *
  */
 
-fun String.actualLength(): Int {
-    var x = 0
-    this.forEach {
-        if (it.isChineseChar()) {
-            x += 2
-        } else {
-            x += 1
-        }
-    }
-    return x
-}
+val String.actualLength: Int get() = this.sumBy { if (it.isChineseChar) 2 else 1 }
+
 
 fun String.getSubStringIndexByActualLength(widthMax: Int): Int {
-    var index = 0
-    var currentLength = 0
-    this.forEach {
-        if (it.isChineseChar()) {
-            currentLength += 2
-        } else {
-            currentLength += 1
-        }
-        if (currentLength > widthMax) {
-            return@forEach
-        }
-        ++index
-    }
-    if (index < 2) {
-        index = 2
-    }
-    return index
+    return this.sumBy { if (it.isChineseChar) 2 else 1 }.coerceAtMost(widthMax).coerceAtLeast(2)
 }
 
-fun Char.isChineseChar(): Boolean {
-    return this.toString().isChineseChar()
-}
+val Char.isChineseChar: Boolean
+    get() {
+        return this.toString().isChineseChar
+    }
 
-fun String.isChineseChar(): Boolean {
-    return this.matches(Regex("[\u4e00-\u9fa5]"))
-}
+val String.isChineseChar: Boolean
+    get() {
+        return this.matches(Regex("[\u4e00-\u9fa5]"))
+    }
 
 
 object MiraiConsoleTerminalUI : MiraiConsoleUI {
-    val cacheLogSize = 50
+    const val cacheLogSize = 50
     var mainTitle = "Mirai Console v0.01 Core v0.15"
 
     override fun pushVersion(consoleVersion: String, consoleBuild: String, coreVersion: String) {
@@ -122,7 +99,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
 
     @Volatile
     var requesting = false
-    var requestResult: String? = null
+    private var requestResult: String? = null
     override suspend fun requestInput(): String {
         requesting = true
         while (requesting) {
@@ -132,7 +109,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
     }
 
 
-    suspend fun provideInput(input: String) {
+    private suspend fun provideInput(input: String) {
         if (requesting) {
             requestResult = input
             requesting = false
@@ -164,17 +141,13 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
                     }
                 }
 
-                var toLog = ""
+                lateinit var toLog: String
                 tempFile.inputStream().use {
                     val img = ImageIO.read(it)
-                    if (img == null) {
-                        toLog += "无法创建字符图片. 请查看文件\n"
-                    } else {
-                        toLog += img.createCharImg((terminal.terminalSize.columns / 1.5).toInt())
-                    }
+                    toLog += img?.createCharImg((terminal.terminalSize.columns / 1.5).toInt()) ?: "无法创建字符图片. 请查看文件\n"
                 }
                 pushLog(0, "$toLog[Login Solver]请输验证码. ${tempFile.absolutePath}")
-                return requestInput()!!
+                return requestInput()
                     .takeUnless { it.isEmpty() || it.length != 4 }
                     .also {
                         pushLog(0, "[Login Solver]正在提交[$it]中...")
@@ -206,11 +179,11 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
         }
     }
 
-    val log = ConcurrentHashMap<Long, LimitLinkedQueue<String>>().also {
+    private val log = ConcurrentHashMap<Long, LimitLinkedQueue<String>>().also {
         it[0L] = LimitLinkedQueue(cacheLogSize)
     }
 
-    val botAdminCount = ConcurrentHashMap<Long, Int>()
+    private val botAdminCount = ConcurrentHashMap<Long, Int>()
 
     private val screens = mutableListOf(0L)
     private var currentScreenId = 0
@@ -219,7 +192,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
     lateinit var terminal: Terminal
     lateinit var textGraphics: TextGraphics
 
-    var hasStart = false
+    private var hasStart = false
     private lateinit var internalPrinter: PrintStream
     fun start() {
         if (hasStart) {
@@ -277,11 +250,12 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
 
        */
         var lastJob: Job? = null
-        terminal.addResizeListener(TerminalResizeListener { terminal1: Terminal, newSize: TerminalSize ->
+        terminal.addResizeListener { _: Terminal, _: TerminalSize ->
             lastJob = GlobalScope.launch {
                 try {
                     delay(300)
                     if (lastJob == coroutineContext[Job]) {
+                        @Suppress("BlockingMethodInNonBlockingContext")
                         terminal.clearScreen()
                         //inited = false
                         update()
@@ -292,7 +266,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
                     pushLog(0, "[UI ERROR] ${e.message}")
                 }
             }
-        })
+        }
 
         if (terminal !is SwingTerminalFrame) {
             System.setOut(PrintStream(object : OutputStream() {
@@ -322,7 +296,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
         thread {
             while (true) {
                 try {
-                    var keyStroke: KeyStroke = terminal.readInput()
+                    val keyStroke: KeyStroke = terminal.readInput()
 
                     when (keyStroke.keyType) {
                         KeyType.ArrowLeft -> {
@@ -411,7 +385,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
 
         textGraphics.foregroundColor = TextColor.ANSI.WHITE
         textGraphics.backgroundColor = TextColor.ANSI.GREEN
-        textGraphics.putString((width - mainTitle.actualLength()) / 2, 1, mainTitle, SGR.BOLD)
+        textGraphics.putString((width - mainTitle.actualLength) / 2, 1, mainTitle, SGR.BOLD)
         textGraphics.foregroundColor = TextColor.ANSI.DEFAULT
         textGraphics.backgroundColor = TextColor.ANSI.DEFAULT
         textGraphics.putString(2, 3, "-".repeat(width - 4))
@@ -426,15 +400,15 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
         val leftName =
             getScreenName(getLeftScreenId())
         // clearRows(2)
-        textGraphics.putString((width - title.actualLength()) / 2 - "$leftName << ".length, 2, "$leftName << ")
+        textGraphics.putString((width - title.actualLength) / 2 - "$leftName << ".length, 2, "$leftName << ")
         textGraphics.foregroundColor = TextColor.ANSI.WHITE
         textGraphics.backgroundColor = TextColor.ANSI.YELLOW
-        textGraphics.putString((width - title.actualLength()) / 2, 2, title, SGR.BOLD)
+        textGraphics.putString((width - title.actualLength) / 2, 2, title, SGR.BOLD)
         textGraphics.foregroundColor = TextColor.ANSI.DEFAULT
         textGraphics.backgroundColor = TextColor.ANSI.DEFAULT
         val rightName =
             getScreenName(getRightScreenId())
-        textGraphics.putString((width + title.actualLength()) / 2 + 1, 2, ">> $rightName")
+        textGraphics.putString((width + title.actualLength) / 2 + 1, 2, ">> $rightName")
     }
 
     fun drawMainFrame(
@@ -447,7 +421,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
         clearRows(4)
         textGraphics.putString(2, 4, "|Online Bots: $onlineBotCount")
         textGraphics.putString(
-            width - 2 - "Powered By Mamoe Technologies|".actualLength(),
+            width - 2 - "Powered By Mamoe Technologies|".actualLength,
             4,
             "Powered By Mamoe Technologies|"
         )
@@ -463,7 +437,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
         textGraphics.backgroundColor = TextColor.ANSI.DEFAULT
         clearRows(4)
         textGraphics.putString(2, 4, "|Admins: $adminCount")
-        textGraphics.putString(width - 2 - "Add admins via commands|".actualLength(), 4, "Add admins via commands|")
+        textGraphics.putString(width - 2 - "Add admins via commands|".actualLength, 4, "Add admins via commands|")
     }
 
 
@@ -472,7 +446,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
 
         fun drawLog(string: String, flush: Boolean = true) {
             val maxHeight = terminal.terminalSize.rows - 4
-            val heightNeed = (string.actualLength() / (terminal.terminalSize.columns - 6)) + 1
+            val heightNeed = (string.actualLength / (terminal.terminalSize.columns - 6)) + 1
             if (heightNeed - 1 > maxHeight) {
                 pushLog(0, "[UI ERROR]: 您的屏幕太小, 有一条超长LOG无法显示")
                 return//拒绝打印
@@ -481,7 +455,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
                 cleanPage()//翻页
             }
             if (string.contains("\n")) {
-                string.split("\n").forEach {
+                string.split("\n").forEach { _ ->
                     drawLog(string, false)
                 }
             } else {
@@ -491,7 +465,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
                     if (x == "") {
                         break
                     }
-                    val toWrite = if (x.actualLength() > width) {
+                    val toWrite = if (x.actualLength > width) {
                         val index = x.getSubStringIndexByActualLength(width)
                         x.substring(0, index).also {
                             x = if (index < x.length) {
@@ -539,7 +513,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
             var vara = 0
             val toPrint = mutableListOf<String>()
             toDraw.forEach {
-                val heightNeed = (it.actualLength() / (terminal.terminalSize.columns - 6)) + 1
+                val heightNeed = (it.actualLength / (terminal.terminalSize.columns - 6)) + 1
                 vara += heightNeed
                 if (currentHeight + vara < terminal.terminalSize.rows - 4) {
                     logsToDraw++
@@ -558,8 +532,8 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
     }
 
 
-    var commandBuilder = StringBuilder()
-    fun redrawCommand() {
+    private var commandBuilder = StringBuilder()
+    private fun redrawCommand() {
         val height = terminal.terminalSize.rows
         val width = terminal.terminalSize.columns
         clearRows(height - 3)
@@ -594,7 +568,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
     }
 
     private fun deleteCommandChar() {
-        if (!commandBuilder.isEmpty()) {
+        if (commandBuilder.isNotEmpty()) {
             commandBuilder = StringBuilder(commandBuilder.toString().substring(0, commandBuilder.length - 1))
         }
         val height = terminal.terminalSize.rows
@@ -606,7 +580,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
     }
 
 
-    var lastEmpty: Job? = null
+    private var lastEmpty: Job? = null
     private fun emptyCommand() {
         commandBuilder = StringBuilder()
         if (terminal is SwingTerminal) {
@@ -617,7 +591,9 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
                 try {
                     delay(100)
                     if (lastEmpty == coroutineContext[Job]) {
-                        terminal.clearScreen()
+                        withContext(Dispatchers.IO) {
+                            terminal.clearScreen()
+                        }
                         //inited = false
                         update()
                         redrawCommand()
@@ -630,7 +606,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
         }
     }
 
-    fun update() {
+    private fun update() {
         when (screens[currentScreenId]) {
             0L -> {
                 drawMainFrame(screens.size - 1)
@@ -658,7 +634,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
 
 
 class LimitLinkedQueue<T>(
-    val limit: Int = 50
+    private val limit: Int = 50
 ) : ConcurrentLinkedDeque<T>() {
     override fun push(e: T) {
         if (size >= limit) {

+ 14 - 4
mirai-console/build.gradle.kts

@@ -26,7 +26,7 @@ fun kotlinx(id: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$id:$v
 
 fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
 
-tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>() {
+tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar> {
     manifest {
         attributes["Main-Class"] = "net.mamoe.mirai.console.pure.MiraiConsolePureLoader"
     }
@@ -35,6 +35,16 @@ tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>() {
 
 val miraiVersion: String by rootProject.ext
 
+kotlin {
+    sourceSets {
+        all {
+            languageSettings.enableLanguageFeature("InlineClasses")
+
+            languageSettings.useExperimentalAnnotation("kotlin.Experimental")
+            languageSettings.useExperimentalAnnotation("kotlin.OptIn")
+        }
+    }
+}
 dependencies {
     compileOnly("net.mamoe:mirai-core-jvm:$miraiVersion")
     // compileOnly("net.mamoe:mirai-core-qqandroid-jvm:$miraiVersion")
@@ -65,8 +75,8 @@ dependencies {
     api(ktor("network", ktorVersion))
 }
 
-val mirai_console_version: String by project.ext
-version = mirai_console_version
+val miraiConsoleVersion: String by project.ext
+version = miraiConsoleVersion
 
 description = "Console with plugin support for mirai"
 bintray {
@@ -109,7 +119,7 @@ publishing {
 
             groupId = rootProject.group.toString()
             artifactId = "mirai-console"
-            version = mirai_console_version
+            version = miraiConsoleVersion
 
             pom.withXml {
                 val root = asNode()

+ 5 - 16
mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt

@@ -12,7 +12,6 @@ package net.mamoe.mirai.console
 import kotlinx.coroutines.*
 import kotlinx.coroutines.channels.Channel
 import net.mamoe.mirai.Bot
-import net.mamoe.mirai.BotFactory
 import net.mamoe.mirai.console.MiraiConsole.CommandProcessor.processNextCommandLine
 import net.mamoe.mirai.console.command.CommandManager
 import net.mamoe.mirai.console.command.CommandSender
@@ -38,20 +37,10 @@ object MiraiConsole {
      * */
     val bots get() = Bot.instances
 
-    fun getBotByUIN(uin: Long): Bot? {
-        bots.forEach {
-            if (it.get()?.uin == uin) {
-                return it.get()
-            }
-        }
-        return null
+    fun getBotOrNull(uin: Long): Bot? {
+        return bots.asSequence().mapNotNull { it.get() }.firstOrNull { it.uin == uin }
     }
 
-    /**
-     * PluginManager
-     */
-    val pluginManager: PluginManager get() = PluginManager
-
     /**
      * 与前端交互所使用的Logger
      */
@@ -89,9 +78,8 @@ object MiraiConsole {
         logger("Mirai为开源项目,请自觉遵守开源项目协议")
         logger("Powered by Mamoe Technologies and contributors")
 
-        MiraiCoreLoader()
+        MiraiCoreLoader.loadCore()
 
-        println(BotFactory::class)
         /* 加载ECDH */
         try {
             ECDH()
@@ -102,7 +90,7 @@ object MiraiConsole {
 
         /* 依次启用功能 */
         DefaultCommands()
-        pluginManager.loadPlugins()
+        PluginManager.loadPlugins()
         CommandProcessor.start()
 
         /* 通知启动完成 */
@@ -150,6 +138,7 @@ object MiraiConsole {
 
         fun runConsoleCommandBlocking(command: String) = runBlocking { runConsoleCommand(command) }
 
+        @Suppress("unused")
         fun runCommandBlocking(sender: CommandSender, command: String) = runBlocking { runCommand(sender, command) }
 
         private suspend fun processNextCommandLine() {

+ 31 - 114
mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt

@@ -7,82 +7,18 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
+@file:Suppress("NOTHING_TO_INLINE")
+
 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.PluginManager
+import net.mamoe.mirai.console.plugins.PluginBase
 import net.mamoe.mirai.contact.Contact
 import net.mamoe.mirai.contact.sendMessage
-import net.mamoe.mirai.message.GroupMessage
 import net.mamoe.mirai.message.data.MessageChain
-import net.mamoe.mirai.utils.MiraiExperimentalAPI
-
-object CommandManager {
-    private val registeredCommand: MutableMap<String, Command> = mutableMapOf()
-
-    fun getCommands(): Collection<Command> {
-        return registeredCommand.values
-    }
-
-
-    fun register(command: Command) {
-        val allNames = mutableListOf(command.name).also { it.addAll(command.alias) }
-        allNames.forEach {
-            if (registeredCommand.containsKey(it)) {
-                error("Command Name(or Alias) $it is already registered, consider if same functional plugin was installed")
-            }
-        }
-        allNames.forEach {
-            registeredCommand[it] = command
-        }
-    }
-
-    fun unregister(command: Command) {
-        val allNames = mutableListOf<String>(command.name).also { it.addAll(command.alias) }
-        allNames.forEach {
-            registeredCommand.remove(it)
-        }
-    }
-
-    fun unregister(commandName: String) {
-        registeredCommand.remove(commandName)
-    }
-
-    /*
-    * Index: MiraiConsole
-    * */
-    internal suspend fun runCommand(sender: CommandSender, fullCommand: String): Boolean {
-        val blocks = fullCommand.split(" ")
-        val commandHead = blocks[0].replace("/", "")
-        if (!registeredCommand.containsKey(commandHead)) {
-            return false
-        }
-        val args = blocks.subList(1, blocks.size)
-        registeredCommand[commandHead]?.run {
-            try {
-                if (onCommand(
-                        sender,
-                        blocks.subList(1, blocks.size)
-                    )
-                ) {
-                    PluginManager.onCommand(this, sender, args)
-                } else {
-                    sender.sendMessage(this.usage)
-                }
-            } catch (e: Exception) {
-                sender.sendMessage("在运行指令时出现了未知错误")
-                e.printStackTrace()
-            } finally {
-                (sender as CommandSenderImpl).flushMessage()
-            }
-        }
-        return true
-    }
-
-}
 
 interface CommandSender {
     /**
@@ -92,7 +28,7 @@ interface CommandSender {
 
     suspend fun sendMessage(message: String)
     /**
-     * 写入要发送的内容 所有内容最后会被以一条发出, 不管成功与否
+     * 写入要发送的内容 所有内容最后会被以一条发出
      */
     fun appendMessage(message: String)
 
@@ -139,21 +75,6 @@ open class ContactCommandSender(val contact: Contact) : CommandSenderImpl() {
     }
 }
 
-/**
- * 弃用中
- * */
-class GroupCommandSender(val toQuote: GroupMessage, contact: Contact) : ContactCommandSender(contact) {
-    @MiraiExperimentalAPI
-    override suspend fun sendMessage(message: String) {
-        toQuote.quoteReply(message)
-    }
-
-    @MiraiExperimentalAPI
-    override suspend fun sendMessage(messageChain: MessageChain) {
-        toQuote.quoteReply(messageChain)
-    }
-}
-
 interface Command {
     val name: String
     val alias: List<String>
@@ -161,9 +82,18 @@ interface Command {
     val usage: String
 
     suspend fun onCommand(sender: CommandSender, args: List<String>): Boolean
-    fun register()
 }
 
+inline fun Command.register() = CommandManager.register(this)
+
+
+fun registerCommand(builder: CommandBuilder.() -> Unit): Command {
+    return CommandBuilder().apply(builder).register()
+}
+
+
+// for java
+@Suppress("unused")
 abstract class BlockingCommand(
     override val name: String,
     override val alias: List<String> = listOf(),
@@ -172,7 +102,7 @@ abstract class BlockingCommand(
 ) : Command {
     /**
      * 最高优先级监听器
-     * 如果 return `false` 这次指令不会被 [PluginBase] 的全局 onCommand 监听器监听
+     * 如果 return `false`, 这次指令不会被 [PluginBase] 的全局 onCommand 监听器监听
      * */
     final override suspend fun onCommand(sender: CommandSender, args: List<String>): Boolean {
         return withContext(Dispatchers.IO) {
@@ -181,10 +111,6 @@ abstract class BlockingCommand(
     }
 
     abstract fun onCommandBlocking(sender: CommandSender, args: List<String>): Boolean
-
-    override fun register() {
-        CommandManager.register(this)
-    }
 }
 
 class AnonymousCommand internal constructor(
@@ -197,10 +123,6 @@ class AnonymousCommand internal constructor(
     override suspend fun onCommand(sender: CommandSender, args: List<String>): Boolean {
         return onCommand.invoke(sender, args)
     }
-
-    override fun register() {
-        CommandManager.register(this)
-    }
 }
 
 class CommandBuilder internal constructor() {
@@ -208,30 +130,25 @@ class CommandBuilder internal constructor() {
     var alias: List<String>? = null
     var description: String = ""
     var usage: String = "use /help for help"
-    var onCommand: (suspend CommandSender.(args: List<String>) -> Boolean)? = null
+    internal var onCommand: (suspend CommandSender.(args: List<String>) -> Boolean)? = null
 
     fun onCommand(commandProcess: suspend CommandSender.(args: List<String>) -> Boolean) {
         onCommand = commandProcess
     }
-
-    fun register(): Command {
-        if (name == null || onCommand == null) {
-            error("CommandBuilder not complete")
-        }
-        if (alias == null) {
-            alias = listOf()
-        }
-        return AnonymousCommand(
-            name!!,
-            alias!!,
-            description,
-            usage,
-            onCommand!!
-        ).also { it.register() }
-    }
-}
-
-fun registerCommand(builder: CommandBuilder.() -> Unit): Command {
-    return CommandBuilder().apply(builder).register()
 }
 
+private fun CommandBuilder.register(): AnonymousCommand {
+    if (name == null || onCommand == null) {
+        error("CommandBuilder not complete")
+    }
+    if (alias == null) {
+        alias = listOf()
+    }
+    return AnonymousCommand(
+        name!!,
+        alias!!,
+        description,
+        usage,
+        onCommand!!
+    ).also { it.register() }
+}

+ 70 - 0
mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt

@@ -0,0 +1,70 @@
+/*
+ * 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
+ */
+
+@file:Suppress("unused")
+
+package net.mamoe.mirai.console.command
+
+import net.mamoe.mirai.console.plugins.PluginManager
+
+object CommandManager {
+    private val registeredCommand: MutableMap<String, Command> = mutableMapOf()
+
+    val commands: Collection<Command> get() = registeredCommand.values
+
+    fun register(command: Command) {
+        val allNames = mutableListOf(command.name).also { it.addAll(command.alias) }
+        allNames.forEach {
+            if (registeredCommand.containsKey(it)) {
+                error("Command Name(or Alias) $it is already registered, consider if same functional plugin was installed")
+            }
+        }
+        allNames.forEach {
+            registeredCommand[it] = command
+        }
+    }
+
+    fun unregister(command: Command) {
+        (command.alias.asSequence() + command.name).forEach {
+            registeredCommand.remove(it)
+        } // label compilation failed
+    }
+
+    fun unregister(commandName: String): Boolean {
+        return registeredCommand.remove(commandName) != null
+    }
+
+    /*
+    * Index: MiraiConsole
+    */
+    internal suspend fun runCommand(sender: CommandSender, fullCommand: String): Boolean {
+        val blocks = fullCommand.split(" ")
+        val commandHead = blocks[0].replace("/", "")
+        if (!registeredCommand.containsKey(commandHead)) {
+            return false
+        }
+        val args = blocks.drop(1)
+        registeredCommand[commandHead]?.run {
+            try {
+                if (onCommand(sender, blocks.drop(1))) {
+                    PluginManager.onCommand(this, sender, args)
+                } else {
+                    sender.sendMessage(this.usage)
+                }
+            } catch (e: Exception) {
+                sender.sendMessage("在运行指令时出现了未知错误")
+                e.printStackTrace()
+            } finally {
+                (sender as CommandSenderImpl).flushMessage()
+            }
+        }
+        return true
+    }
+
+}

+ 16 - 16
mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/DefaultCommands.kt

@@ -14,7 +14,7 @@ import net.mamoe.mirai.console.MiraiConsole
 import net.mamoe.mirai.console.plugins.PluginManager
 import net.mamoe.mirai.console.utils.addManager
 import net.mamoe.mirai.console.utils.checkManager
-import net.mamoe.mirai.console.utils.getManagers
+import net.mamoe.mirai.console.utils.managers
 import net.mamoe.mirai.console.utils.removeManager
 import net.mamoe.mirai.contact.sendMessage
 import net.mamoe.mirai.event.subscribeMessages
@@ -49,7 +49,7 @@ object DefaultCommands {
                     MiraiConsole.logger("[Bot Manager]", 0, it[1] + " 不是一个Bot的ID")
                     return@onCommand false
                 }
-                val bot = MiraiConsole.getBotByUIN(botId)
+                val bot = MiraiConsole.getBotOrNull(botId)
                 if (bot == null) {
                     MiraiConsole.logger("[Bot Manager]", 0, "$botId 没有在Console中登陆")
                     return@onCommand false
@@ -88,7 +88,7 @@ object DefaultCommands {
                         MiraiConsole.logger("[Bot Manager]", 0, it[2] + "移除成功")
                     }
                     "list" -> {
-                        bot.getManagers().forEach {
+                        bot.managers.forEach {
                             MiraiConsole.logger("[Bot Manager]", 0, " -> $it")
                         }
                     }
@@ -106,7 +106,7 @@ object DefaultCommands {
                     return@onCommand false
                 }
                 if (it.size < 2) {
-                    MiraiConsole.logger("\"/login qqnumber qqpassword \" to login a bot")
+                    MiraiConsole.logger("\"/login qq password \" to login a bot")
                     MiraiConsole.logger("\"/login qq号 qq密码 \" 来登录一个BOT")
                     return@onCommand false
                 }
@@ -138,11 +138,11 @@ object DefaultCommands {
                     }
                     bot.login()
                     bot.subscribeMessages {
-                        this.startsWith("/") {
+                        startsWith("/") { message ->
                             if (bot.checkManager(this.sender.id)) {
                                 val sender = ContactCommandSender(this.subject)
                                 MiraiConsole.CommandProcessor.runCommand(
-                                    sender, it
+                                    sender, message
                                 )
                             }
                         }
@@ -159,13 +159,13 @@ object DefaultCommands {
         registerCommand {
             name = "status"
             description = "获取状态"
-            onCommand {
-                when (it.size) {
+            onCommand { args ->
+                when (args.size) {
                     0 -> {
                         sendMessage("当前有" + MiraiConsole.bots.size + "个BOT在线")
                     }
                     1 -> {
-                        val bot = it[0]
+                        val bot = args[0]
                         var find = false
                         MiraiConsole.bots.forEach {
                             if (it.get()?.uin.toString().contains(bot)) {
@@ -196,13 +196,13 @@ object DefaultCommands {
                     return@onCommand false
                 }
                 val bot: Bot? = if (it.size == 2) {
-                    if (MiraiConsole.bots.size == 0) {
+                    if (MiraiConsole.bots.isEmpty()) {
                         MiraiConsole.logger("还没有BOT登录")
                         return@onCommand false
                     }
                     MiraiConsole.bots[0].get()
                 } else {
-                    MiraiConsole.getBotByUIN(it[0].toLong())
+                    MiraiConsole.getBotOrNull(it[0].toLong())
                 }
                 if (bot == null) {
                     MiraiConsole.logger("没有找到BOT")
@@ -228,11 +228,11 @@ object DefaultCommands {
             alias = listOf("plugin")
             description = "获取插件列表"
             onCommand {
-                PluginManager.getAllPluginDescriptions().let {
-                    it.forEach {
+                PluginManager.getAllPluginDescriptions().let { descriptions ->
+                    descriptions.forEach {
                         appendMessage("\t" + it.name + " v" + it.version + " by" + it.author + " " + it.info)
                     }
-                    appendMessage("加载了" + it.size + "个插件")
+                    appendMessage("加载了" + descriptions.size + "个插件")
                     true
                 }
             }
@@ -243,10 +243,10 @@ object DefaultCommands {
             alias = listOf("commands", "help", "helps")
             description = "获取指令列表"
             onCommand {
-                CommandManager.getCommands().let {
+                CommandManager.commands.let { commands ->
                     var size = 0
                     appendMessage("")//\n
-                    it.toSet().forEach {
+                    commands.forEach {
                         ++size
                         appendMessage("-> " + it.name + " :" + it.description)
                     }

+ 24 - 26
mirai-console/src/main/kotlin/net/mamoe/mirai/console/core/MiraiCoreLoader.kt

@@ -7,15 +7,15 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
+@file:Suppress("EXPERIMENTAL_API_USAGE")
+
 package net.mamoe.mirai.console.core
 
 import io.ktor.client.HttpClient
 import io.ktor.client.engine.cio.CIO
 import io.ktor.client.request.get
-import io.ktor.client.request.url
 import io.ktor.client.statement.HttpResponse
 import io.ktor.http.URLProtocol
-import io.ktor.util.KtorExperimentalAPI
 import io.ktor.utils.io.ByteReadChannel
 import io.ktor.utils.io.jvm.javaio.copyTo
 import kotlinx.coroutines.Dispatchers
@@ -27,12 +27,11 @@ import java.net.URLClassLoader
 import kotlin.math.pow
 import kotlin.system.exitProcess
 
-@UseExperimental(KtorExperimentalAPI::class)
 val Http: HttpClient
     get() = HttpClient(CIO)
 
 object MiraiCoreLoader {
-    val coresPath by lazy {
+    private val coresPath by lazy {
         File(System.getProperty("user.dir") + "/core/").also {
             if (!it.exists()) {
                 it.mkdirs()
@@ -59,7 +58,7 @@ object MiraiCoreLoader {
     }
 
 
-    operator fun invoke(): String {
+    fun loadCore(): String {
         MiraiConsole.logger("Fetching Newest Core Version .. ")
         val newest = runBlocking {
             getNewestVersion()
@@ -82,7 +81,7 @@ object MiraiCoreLoader {
 
 
     /**
-     * 使用Protocol Lib判断最新版本
+     * 判断最新版本
      * */
     private suspend fun getNewestVersion(): String {
         try {
@@ -110,9 +109,9 @@ object MiraiCoreLoader {
     }
 
     /**
-     * 使用Protocol Lib判断当前版本
-     * 如果没有 会返回0.0.0
-     * */
+     * 判断当前版本
+     * 默认返回 "0.0.0"
+     */
     private fun getCurrentVersion(): String {
         val file = getProtocolLib()
         if (file == null || getCore() == null) return "0.0.0"
@@ -133,14 +132,18 @@ object MiraiCoreLoader {
     }
 
 
-    val lib_jcenter =
-        "https://jcenter.bintray.com/net/mamoe/mirai-core-qqandroid-jvm/{version}/:mirai-core-qqandroid-jvm-{version}.jar"
-    val lib_aliyun =
-        "https://maven.aliyun.com/nexus/content/repositories/jcenter/net/mamoe/mirai-core-qqandroid-jvm/{version}/mirai-core-qqandroid-jvm-{version}.jar"
+    @Suppress("SpellCheckingInspection")
+    private object Links {
+        internal const val libJcenter =
+            "https://jcenter.bintray.com/net/mamoe/mirai-core-qqandroid-jvm/{version}/:mirai-core-qqandroid-jvm-{version}.jar"
+        internal const val libAliyun =
+            "https://maven.aliyun.com/nexus/content/repositories/jcenter/net/mamoe/mirai-core-qqandroid-jvm/{version}/mirai-core-qqandroid-jvm-{version}.jar"
 
-    val core_jcenter = "https://jcenter.bintray.com/net/mamoe/mirai-core-jvm/{version}/:mirai-core-jvm-{version}.jar"
-    val core_aliyun =
-        "https://maven.aliyun.com/nexus/content/repositories/jcenter/net/mamoe/mirai-core-jvm/{version}/mirai-core-jvm-{version}.jar"
+        internal const val coreJcenter =
+            "https://jcenter.bintray.com/net/mamoe/mirai-core-jvm/{version}/:mirai-core-jvm-{version}.jar"
+        internal const val coreAliyun =
+            "https://maven.aliyun.com/nexus/content/repositories/jcenter/net/mamoe/mirai-core-jvm/{version}/mirai-core-jvm-{version}.jar"
+    }
 
     private suspend fun downloadCoreAndLib(version: String) {
         var fileStream = File(coresPath.absolutePath + "/" + "mirai-core-qqandroid-jvm-$version.jar").also {
@@ -150,18 +153,16 @@ object MiraiCoreLoader {
         }.outputStream()
 
         suspend fun downloadRequest(url: String, version: String): ByteReadChannel {
-            return Http.get<HttpResponse>() {
-                this.url(url.replace("{version}", version))
-            }.content
+            return Http.get<HttpResponse>(url.replace("{version}", version)).content
         }
 
         var stream = kotlin.runCatching {
             MiraiConsole.logger("Downloading newest Protocol lib from Aliyun")
-            downloadRequest(lib_aliyun, version)
+            downloadRequest(Links.libAliyun, version)
         }.getOrElse {
             kotlin.runCatching {
                 MiraiConsole.logger("Downloading newest Protocol lib from JCenter")
-                downloadRequest(lib_jcenter, version)
+                downloadRequest(Links.libJcenter, version)
             }.getOrElse { e ->
                 MiraiConsole.logger("Failed to download Protocol lib, please seeking for help")
                 e.printStackTrace()
@@ -184,11 +185,11 @@ object MiraiCoreLoader {
 
         stream = try {
             MiraiConsole.logger("Downloading newest Mirai Core from Aliyun")
-            downloadRequest(core_aliyun, version)
+            downloadRequest(Links.coreAliyun, version)
         } catch (ignored: Exception) {
             try {
                 MiraiConsole.logger("Downloading newest Mirai Core from JCenter")
-                downloadRequest(core_jcenter, version)
+                downloadRequest(Links.coreJcenter, version)
             } catch (e: Exception) {
                 MiraiConsole.logger("Failed to download Mirai Core, please seeking for help")
                 e.printStackTrace()
@@ -240,8 +241,5 @@ object MiraiCoreLoader {
 
 }
 
-internal class MiraiCoreClassLoader(file: File, parent: ClassLoader) :
-    URLClassLoader(arrayOf(file.toURI().toURL()), parent)
-
 
 

+ 42 - 28
mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/ConfigSection.kt

@@ -7,6 +7,8 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
+@file:Suppress("MemberVisibilityCanBePrivate")
+
 package net.mamoe.mirai.console.plugins
 
 import com.alibaba.fastjson.JSON
@@ -17,12 +19,14 @@ import com.moandjiezana.toml.Toml
 import com.moandjiezana.toml.TomlWriter
 import kotlinx.serialization.Serializable
 import kotlinx.serialization.UnstableDefault
+import net.mamoe.mirai.utils.MiraiInternalAPI
 import net.mamoe.mirai.utils.io.encodeToString
 import org.yaml.snakeyaml.Yaml
 import java.io.File
 import java.io.InputStream
 import java.util.*
 import java.util.concurrent.ConcurrentHashMap
+import kotlin.NoSuchElementException
 import kotlin.properties.ReadWriteProperty
 import kotlin.reflect.KClass
 import kotlin.reflect.KProperty
@@ -134,16 +138,16 @@ inline operator fun <reified T : Any> Config.setValue(thisRef: Any?, property: K
 }
 
 /* 带有默认值的代理 */
+@Suppress("unused")
 inline fun <reified T : Any> Config.withDefault(
-    noinline defaultValue: () -> T
+    crossinline defaultValue: () -> T
 ): ReadWriteProperty<Any, T> {
-    val default by lazy { defaultValue.invoke() }
     return object : ReadWriteProperty<Any, T> {
         override fun getValue(thisRef: Any, property: KProperty<*>): T {
             if ([email protected](property.name)) {//unsafe
                 return [email protected](property)
             }
-            return default
+            return defaultValue()
         }
 
         override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
@@ -153,6 +157,7 @@ inline fun <reified T : Any> Config.withDefault(
 }
 
 /* 带有默认值且如果为空会写入的代理 */
+@Suppress("unused")
 inline fun <reified T : Any> Config.withDefaultWrite(
     noinline defaultValue: () -> T
 ): WithDefaultWriteLoader<T> {
@@ -191,7 +196,7 @@ class WithDefaultWriteLoader<T : Any>(
         return object : ReadWriteProperty<Any, T> {
             override fun getValue(thisRef: Any, property: KProperty<*>): T {
                 if (config.exist(property.name)) {//unsafe
-                    return config._smartCast(property.name, _class)
+                    return config.smartCastInternal(property.name, _class)
                 }
                 return defaultValue
             }
@@ -203,12 +208,14 @@ class WithDefaultWriteLoader<T : Any>(
     }
 }
 
-inline fun <reified T : Any> Config.smartCast(property: KProperty<*>): T {
-    return _smartCast(property.name, T::class)
+@PublishedApi
+internal inline fun <reified T : Any> Config.smartCast(property: KProperty<*>): T {
+    return smartCastInternal(property.name, T::class)
 }
 
+@PublishedApi
 @Suppress("IMPLICIT_CAST_TO_ANY", "UNCHECKED_CAST")
-fun <T : Any> Config._smartCast(propertyName: String, _class: KClass<T>): T {
+internal fun <T : Any> Config.smartCastInternal(propertyName: String, _class: KClass<T>): T {
     return when (_class) {
         String::class -> this.getString(propertyName)
         Int::class -> this.getInt(propertyName)
@@ -251,70 +258,72 @@ fun <T : Any> Config._smartCast(propertyName: String, _class: KClass<T>): T {
 
 interface ConfigSection : Config, MutableMap<String, Any> {
     override fun getConfigSection(key: String): ConfigSection {
-        val content = get(key) ?: error("ConfigSection does not contain $key ")
+        val content = get(key) ?: throw NoSuchElementException(key)
         if (content is ConfigSection) {
             return content
         }
+        @Suppress("UNCHECKED_CAST")
         return ConfigSectionDelegation(
             Collections.synchronizedMap(
-                (get(key) ?: error("ConfigSection does not contain $key ")) as LinkedHashMap<String, Any>
+                (get(key) ?: throw NoSuchElementException(key)) as LinkedHashMap<String, Any>
             )
         )
     }
 
     override fun getString(key: String): String {
-        return (get(key) ?: error("ConfigSection does not contain $key ")).toString()
+        return (get(key) ?: throw NoSuchElementException(key)).toString()
     }
 
     override fun getInt(key: String): Int {
-        return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toInt()
+        return (get(key) ?: throw NoSuchElementException(key)).toString().toInt()
     }
 
     override fun getFloat(key: String): Float {
-        return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toFloat()
+        return (get(key) ?: throw NoSuchElementException(key)).toString().toFloat()
     }
 
     override fun getBoolean(key: String): Boolean {
-        return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toBoolean()
+        return (get(key) ?: throw NoSuchElementException(key)).toString().toBoolean()
     }
 
     override fun getDouble(key: String): Double {
-        return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toDouble()
+        return (get(key) ?: throw NoSuchElementException(key)).toString().toDouble()
     }
 
     override fun getLong(key: String): Long {
-        return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toLong()
+        return (get(key) ?: throw NoSuchElementException(key)).toString().toLong()
     }
 
     override fun getList(key: String): List<*> {
-        return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>)
+        return ((get(key) ?: throw NoSuchElementException(key)) as List<*>)
     }
 
     override fun getStringList(key: String): List<String> {
-        return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString() }
+        return ((get(key) ?: throw NoSuchElementException(key)) as List<*>).map { it.toString() }
     }
 
     override fun getIntList(key: String): List<Int> {
-        return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toInt() }
+        return ((get(key) ?: throw NoSuchElementException(key)) as List<*>).map { it.toString().toInt() }
     }
 
     override fun getFloatList(key: String): List<Float> {
-        return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toFloat() }
+        return ((get(key) ?: throw NoSuchElementException(key)) as List<*>).map { it.toString().toFloat() }
     }
 
     override fun getDoubleList(key: String): List<Double> {
-        return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toDouble() }
+        return ((get(key) ?: throw NoSuchElementException(key)) as List<*>).map { it.toString().toDouble() }
     }
 
     override fun getLongList(key: String): List<Long> {
-        return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toLong() }
+        return ((get(key) ?: throw NoSuchElementException(key)) as List<*>).map { it.toString().toLong() }
     }
 
     override fun getConfigSectionList(key: String): List<ConfigSection> {
-        return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map {
+        return ((get(key) ?: throw NoSuchElementException(key)) as List<*>).map {
             if (it is ConfigSection) {
                 it
             } else {
+                @Suppress("UNCHECKED_CAST")
                 ConfigSectionDelegation(
                     Collections.synchronizedMap(
                         it as MutableMap<String, Any>
@@ -334,7 +343,7 @@ interface ConfigSection : Config, MutableMap<String, Any> {
 }
 
 @Serializable
-open class ConfigSectionImpl() : ConcurrentHashMap<String, Any>(),
+open class ConfigSectionImpl : ConcurrentHashMap<String, Any>(),
     ConfigSection {
     override fun set(key: String, value: Any) {
         super.put(key, value)
@@ -370,7 +379,7 @@ open class ConfigSectionDelegation(
     private val delegate: MutableMap<String, Any>
 ) : ConfigSection, MutableMap<String, Any> by delegate {
     override fun set(key: String, value: Any) {
-        delegate.put(key, value)
+        delegate[key] = value
     }
 
     override fun contains(key: String): Boolean {
@@ -394,6 +403,7 @@ interface FileConfig : Config {
 }
 
 
+@MiraiInternalAPI
 abstract class FileConfigImpl internal constructor(
     private val rawContent: String
 ) : FileConfig,
@@ -402,6 +412,7 @@ abstract class FileConfigImpl internal constructor(
     internal var file: File? = null
 
 
+    @Suppress("unused")
     constructor(file: File) : this(file.readText()) {
         this.file = file
     }
@@ -425,7 +436,7 @@ abstract class FileConfigImpl internal constructor(
     override fun remove(key: String): Any? = content.remove(key)
 
     override fun save() {
-        if (isReadOnly()) {
+        if (isReadOnly) {
             error("Config is readonly")
         }
         if (!((file?.exists())!!)) {
@@ -434,7 +445,7 @@ abstract class FileConfigImpl internal constructor(
         file?.writeText(serialize(content))
     }
 
-    fun isReadOnly() = file == null
+    val isReadOnly: Boolean get() = file == null
 
     override fun contains(key: String): Boolean {
         return content.contains(key)
@@ -454,6 +465,7 @@ abstract class FileConfigImpl internal constructor(
 
 }
 
+@UseExperimental(MiraiInternalAPI::class)
 class JsonConfig internal constructor(
     content: String
 ) : FileConfigImpl(content) {
@@ -466,7 +478,7 @@ class JsonConfig internal constructor(
         if (content.isEmpty() || content.isBlank() || content == "{}") {
             return ConfigSectionImpl()
         }
-        return JSON.parseObject<ConfigSectionImpl>(
+        return JSON.parseObject(
             content,
             object : TypeReference<ConfigSectionImpl>() {},
             Feature.OrderedField
@@ -479,6 +491,7 @@ class JsonConfig internal constructor(
     }
 }
 
+@UseExperimental(MiraiInternalAPI::class)
 class YamlConfig internal constructor(content: String) : FileConfigImpl(content) {
     constructor(file: File) : this(file.readText()) {
         this.file = file
@@ -490,7 +503,7 @@ class YamlConfig internal constructor(content: String) : FileConfigImpl(content)
         }
         return ConfigSectionDelegation(
             Collections.synchronizedMap(
-                Yaml().load<LinkedHashMap<String, Any>>(content) as LinkedHashMap<String, Any>
+                Yaml().load(content) as LinkedHashMap<String, Any>
             )
         )
     }
@@ -501,6 +514,7 @@ class YamlConfig internal constructor(content: String) : FileConfigImpl(content)
 
 }
 
+@UseExperimental(MiraiInternalAPI::class)
 class TomlConfig internal constructor(content: String) : FileConfigImpl(content) {
     constructor(file: File) : this(file.readText()) {
         this.file = file

+ 2 - 1
mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugins/PluginManager.kt

@@ -7,6 +7,8 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
 
+@file:Suppress("unused", "unused")
+
 package net.mamoe.mirai.console.plugins
 
 import kotlinx.coroutines.CancellationException
@@ -22,7 +24,6 @@ import java.util.jar.JarFile
 
 
 object PluginManager {
-
     @Volatile
     internal var lastPluginName: String = ""
 

+ 2 - 2
mirai-console/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsoleUIPure.kt

@@ -18,8 +18,8 @@ import net.mamoe.mirai.utils.LoginSolver
 import kotlin.concurrent.thread
 
 class MiraiConsoleUIPure : MiraiConsoleUI {
-    var requesting = false
-    var requestStr = ""
+    private var requesting = false
+    private var requestStr = ""
 
     init {
         thread {

+ 10 - 9
mirai-console/src/main/kotlin/net/mamoe/mirai/console/utils/BotHelper.kt

@@ -18,32 +18,33 @@ import net.mamoe.mirai.console.plugins.withDefaultWriteSave
 import net.mamoe.mirai.console.utils.BotManagers.BOT_MANAGERS
 import java.io.File
 
-object BotManagers {
+internal object BotManagers {
     val config = File("${MiraiConsole.path}/bot.yml").loadAsConfig()
     val BOT_MANAGERS: ConfigSection by config.withDefaultWriteSave { ConfigSectionImpl() }
 }
 
-fun Bot.addManager(long: Long) {
+internal fun Bot.addManager(long: Long) {
     BOT_MANAGERS.putIfAbsent(this.uin.toString(), mutableListOf<Long>())
     BOT_MANAGERS[this.uin.toString()] =
         (BOT_MANAGERS.getLongList(this.uin.toString()) as MutableList<Long>).apply { add(long) }
     BotManagers.config.save()
 }
 
-fun Bot.removeManager(long: Long) {
+internal fun Bot.removeManager(long: Long) {
     BOT_MANAGERS.putIfAbsent(this.uin.toString(), mutableListOf<Long>())
     BOT_MANAGERS[this.uin.toString()] =
         (BOT_MANAGERS.getLongList(this.uin.toString()) as MutableList<Long>).apply { add(long) }
     BotManagers.config.save()
 }
 
-fun Bot.getManagers(): List<Long> {
-    BOT_MANAGERS.putIfAbsent(this.uin.toString(), mutableListOf<Long>())
-    return BOT_MANAGERS.getLongList(this.uin.toString())
-}
+internal val Bot.managers: List<Long>
+    get() {
+        BOT_MANAGERS.putIfAbsent(this.uin.toString(), mutableListOf<Long>())
+        return BOT_MANAGERS.getLongList(this.uin.toString())
+    }
 
-fun Bot.checkManager(long: Long): Boolean {
-    return this.getManagers().contains(long)
+internal fun Bot.checkManager(long: Long): Boolean {
+    return this.managers.contains(long)
 }