diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsole.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsole.kt index 0fdbefc1c..d5b833808 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsole.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsole.kt @@ -37,8 +37,7 @@ object MiraiConsole { val pluginManager: PluginManager get() = PluginManager - var logger: MiraiConsoleLogger = - UIPushLogger() + var logger = UIPushLogger(0) var path: String = System.getProperty("user.dir") @@ -255,11 +254,11 @@ object MiraiConsole { } } - class UIPushLogger(override val identity: String?, override var follower: MiraiLogger?) : MiraiLogger { - override fun invoke(any: Any?) { + class UIPushLogger(val identity: Long) { + operator fun invoke(any: Any? = null) { MiraiConsoleUI.start() if (any != null) { - MiraiConsoleUI.pushLog(0, "[Mirai$version $build]: $any") + MiraiConsoleUI.pushLog(identity, "[Mirai$version $build]: $any") } } } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsoleUI.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsoleUI.kt index 14c85032a..66fcbef4c 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsoleUI.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsoleUI.kt @@ -29,9 +29,9 @@ object MiraiConsoleUI { log[uin] = LimitLinkedQueue() } - fun pushLog(uin: Long, str: String) { - log[uin]!!.push(str) - } + + lateinit var terminal: Terminal + lateinit var textGraphics: TextGraphics var hasStart = false fun start() { @@ -40,275 +40,274 @@ object MiraiConsoleUI { } hasStart = true val defaultTerminalFactory = DefaultTerminalFactory() - var terminal: Terminal? = null try { terminal = defaultTerminalFactory.createTerminal() terminal.enterPrivateMode() terminal.clearScreen() terminal.setCursorVisible(false) } catch (e: Exception) { - terminal = SwingTerminalFrame("Mirai Console") - terminal.enterPrivateMode() - terminal.clearScreen() - terminal.setCursorVisible(false) - } - if (terminal == null) { - error("can not create terminal") - } - - val textGraphics: TextGraphics = terminal.newTextGraphics() - - try { - fun getLeftScreenId(): Int { - var newId = currentScreenId - 1 - if (newId < 0) { - newId = screens.size - 1 - } - return newId - } - - fun getRightScreenId(): Int { - var newId = 1 + currentScreenId - if (newId >= screens.size) { - newId = 0 - } - return newId - } - - fun getScreenName(id: Int): String { - return when (screens[id]) { - 0L -> { - "Console Screen" - } - else -> { - "Bot: ${screens[id]}" - } - } - } - - - var inited = false - fun clearRows(row: Int) { - textGraphics.putString(0, row, " ".repeat(terminal.terminalSize.columns)) - } - - fun drawFrame( - title: String - ) { - val width = terminal.terminalSize.columns - val height = terminal.terminalSize.rows - terminal.setBackgroundColor(TextColor.ANSI.DEFAULT) - if (!inited) { - val mainTitle = "Mirai Console v0.01 Core v0.14" - textGraphics.foregroundColor = TextColor.ANSI.WHITE - textGraphics.backgroundColor = TextColor.ANSI.GREEN - textGraphics.putString((width - mainTitle.length) / 2, 1, mainTitle, SGR.BOLD) - textGraphics.foregroundColor = TextColor.ANSI.DEFAULT - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - textGraphics.putString(2, 3, "-".repeat(width - 4)) - textGraphics.putString(2, 5, "-".repeat(width - 4)) - textGraphics.putString(2, height - 4, "-".repeat(width - 4)) - textGraphics.putString(2, height - 3, "|>>>") - textGraphics.putString(width - 3, height - 3, "|") - textGraphics.putString(2, height - 2, "-".repeat(width - 4)) - inited = true - } - textGraphics.foregroundColor = TextColor.ANSI.DEFAULT - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - val leftName = getScreenName(getLeftScreenId()) - clearRows(2) - textGraphics.putString((width - title.length) / 2 - "$leftName << ".length, 2, "$leftName << ") - textGraphics.foregroundColor = TextColor.ANSI.WHITE - textGraphics.backgroundColor = TextColor.ANSI.YELLOW - textGraphics.putString((width - title.length) / 2, 2, title, SGR.BOLD) - textGraphics.foregroundColor = TextColor.ANSI.DEFAULT - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - val rightName = getScreenName(getRightScreenId()) - textGraphics.putString((width + title.length) / 2 + 1, 2, ">> $rightName") - } - - fun drawMainFrame( - onlineBotCount: Number - ) { - drawFrame("Console Screen") - val width = terminal.terminalSize.columns - textGraphics.foregroundColor = TextColor.ANSI.DEFAULT - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - clearRows(4) - textGraphics.putString(2, 4, "|Online Bots: $onlineBotCount") - textGraphics.putString( - width - 2 - "Powered By Mamoe Technologies|".length, - 4, - "Powered By Mamoe Technologies|" - ) - } - - fun drawBotFrame( - qq: Long, - adminCount: Number - ) { - drawFrame("Bot: $qq") - val width = terminal.terminalSize.columns - textGraphics.foregroundColor = TextColor.ANSI.DEFAULT - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - clearRows(4) - textGraphics.putString(2, 4, "|Admins: $adminCount") - textGraphics.putString(width - 2 - "Add admins via commands|".length, 4, "Add admins via commands|") - } - - fun drawLogs(values: List) { - val width = terminal.terminalSize.columns - 6 - val heightMin = 5 - - var currentHeight = terminal.terminalSize.rows - 5 - - for (index in heightMin until currentHeight) { - clearRows(index) - } - - values.forEach { - if (currentHeight > heightMin) { - var x = it - while (currentHeight > heightMin) { - if (x.isEmpty() || x.isBlank()) break - textGraphics.foregroundColor = TextColor.ANSI.GREEN - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - val towrite = if (x.length > width) { - x.substring(0, width).also { - x = x.substring(width) - } - } else { - x.also { - x = "" - } - } - textGraphics.putString(3, currentHeight, towrite, SGR.ITALIC) - --currentHeight - } - } - } - - if (terminal is SwingTerminalFrame) { - terminal.flush() - } - } - - - var commandBuilder = StringBuilder() - - fun redrawCommand() { - val height = terminal.terminalSize.rows - val width = terminal.terminalSize.columns - clearRows(height - 3) - textGraphics.foregroundColor = TextColor.ANSI.DEFAULT - textGraphics.putString(2, height - 3, "|>>>") - textGraphics.putString(width - 3, height - 3, "|") - textGraphics.foregroundColor = TextColor.ANSI.BLUE - textGraphics.putString(7, height - 3, commandBuilder.toString()) - if (terminal is SwingTerminalFrame) { - terminal.flush() - } - } - - fun addCommandChar( - c: Char - ) { - if (commandBuilder.isEmpty() && c != '/') { - addCommandChar('/') - } - textGraphics.foregroundColor = TextColor.ANSI.BLUE - val height = terminal.terminalSize.rows - commandBuilder.append(c) - if (terminal is SwingTerminalFrame) { - redrawCommand() - } else { - textGraphics.putString(6 + commandBuilder.length, height - 3, c.toString()) - } - } - - fun deleteCommandChar() { - if (!commandBuilder.isEmpty()) { - commandBuilder = StringBuilder(commandBuilder.toString().substring(0, commandBuilder.length - 1)) - } - val height = terminal.terminalSize.rows - if (terminal is SwingTerminalFrame) { - redrawCommand() - } else { - textGraphics.putString(7 + commandBuilder.length, height - 3, " ") - } - } - - - fun emptyCommand() { - commandBuilder = StringBuilder() - redrawCommand() - if (terminal is SwingTerminal) { - terminal.flush() - } - } - - fun update() { - when (screens[currentScreenId]) { - 0L -> { - drawMainFrame(screens.size - 1) - } - else -> { - drawBotFrame(screens[currentScreenId], 0) - } - } - terminal.flush() - - } - - terminal.addResizeListener(TerminalResizeListener { terminal1: Terminal, newSize: TerminalSize -> + try { + terminal = SwingTerminalFrame("Mirai Console") + terminal.enterPrivateMode() terminal.clearScreen() - inited = false - update() - redrawCommand() - }) + terminal.setCursorVisible(false) + } catch (e: Exception) { + error("can not create terminal") + } + } + textGraphics = terminal.newTextGraphics() + terminal.addResizeListener(TerminalResizeListener { terminal1: Terminal, newSize: TerminalSize -> + terminal.clearScreen() + inited = false update() + redrawCommand() + }) - val charList = listOf(',', '.', '/', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '=', '+', '!', ' ') - thread { - while (true) { - var keyStroke: KeyStroke = terminal.readInput() + update() - when (keyStroke.keyType) { - KeyType.ArrowLeft -> { - currentScreenId = getLeftScreenId() - update() - } - KeyType.ArrowRight -> { - currentScreenId = getRightScreenId() - update() - } - KeyType.Enter -> { - emptyCommand() - } - else -> { - if (keyStroke.character != null) { - if (keyStroke.character.toInt() == 8) { - deleteCommandChar() - } - if (keyStroke.character.isLetterOrDigit() || charList.contains(keyStroke.character)) { - addCommandChar(keyStroke.character) - } + val charList = listOf(',', '.', '/', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '=', '+', '!', ' ') + thread { + while (true) { + var keyStroke: KeyStroke = terminal.readInput() + + when (keyStroke.keyType) { + KeyType.ArrowLeft -> { + currentScreenId = getLeftScreenId() + update() + } + KeyType.ArrowRight -> { + currentScreenId = getRightScreenId() + update() + } + KeyType.Enter -> { + emptyCommand() + } + else -> { + if (keyStroke.character != null) { + if (keyStroke.character.toInt() == 8) { + deleteCommandChar() + } + if (keyStroke.character.isLetterOrDigit() || charList.contains(keyStroke.character)) { + addCommandChar(keyStroke.character) } } } } } - - } catch (e: Exception) { - e.printStackTrace() } } + + fun getLeftScreenId(): Int { + var newId = currentScreenId - 1 + if (newId < 0) { + newId = screens.size - 1 + } + return newId + } + + fun getRightScreenId(): Int { + var newId = 1 + currentScreenId + if (newId >= screens.size) { + newId = 0 + } + return newId + } + + fun getScreenName(id: Int): String { + return when (screens[id]) { + 0L -> { + "Console Screen" + } + else -> { + "Bot: ${screens[id]}" + } + } + } + + + var inited = false + fun clearRows(row: Int) { + textGraphics.putString(0, row, " ".repeat(terminal.terminalSize.columns)) + } + + fun drawFrame( + title: String + ) { + val width = terminal.terminalSize.columns + val height = terminal.terminalSize.rows + terminal.setBackgroundColor(TextColor.ANSI.DEFAULT) + if (!inited) { + val mainTitle = "Mirai Console v0.01 Core v0.14" + textGraphics.foregroundColor = TextColor.ANSI.WHITE + textGraphics.backgroundColor = TextColor.ANSI.GREEN + textGraphics.putString((width - mainTitle.length) / 2, 1, mainTitle, SGR.BOLD) + textGraphics.foregroundColor = TextColor.ANSI.DEFAULT + textGraphics.backgroundColor = TextColor.ANSI.DEFAULT + textGraphics.putString(2, 3, "-".repeat(width - 4)) + textGraphics.putString(2, 5, "-".repeat(width - 4)) + textGraphics.putString(2, height - 4, "-".repeat(width - 4)) + textGraphics.putString(2, height - 3, "|>>>") + textGraphics.putString(width - 3, height - 3, "|") + textGraphics.putString(2, height - 2, "-".repeat(width - 4)) + inited = true + } + textGraphics.foregroundColor = TextColor.ANSI.DEFAULT + textGraphics.backgroundColor = TextColor.ANSI.DEFAULT + val leftName = getScreenName(getLeftScreenId()) + clearRows(2) + textGraphics.putString((width - title.length) / 2 - "$leftName << ".length, 2, "$leftName << ") + textGraphics.foregroundColor = TextColor.ANSI.WHITE + textGraphics.backgroundColor = TextColor.ANSI.YELLOW + textGraphics.putString((width - title.length) / 2, 2, title, SGR.BOLD) + textGraphics.foregroundColor = TextColor.ANSI.DEFAULT + textGraphics.backgroundColor = TextColor.ANSI.DEFAULT + val rightName = getScreenName(getRightScreenId()) + textGraphics.putString((width + title.length) / 2 + 1, 2, ">> $rightName") + } + + fun drawMainFrame( + onlineBotCount: Number + ) { + drawFrame("Console Screen") + val width = terminal.terminalSize.columns + textGraphics.foregroundColor = TextColor.ANSI.DEFAULT + textGraphics.backgroundColor = TextColor.ANSI.DEFAULT + clearRows(4) + textGraphics.putString(2, 4, "|Online Bots: $onlineBotCount") + textGraphics.putString( + width - 2 - "Powered By Mamoe Technologies|".length, + 4, + "Powered By Mamoe Technologies|" + ) + } + + fun drawBotFrame( + qq: Long, + adminCount: Number + ) { + drawFrame("Bot: $qq") + val width = terminal.terminalSize.columns + textGraphics.foregroundColor = TextColor.ANSI.DEFAULT + textGraphics.backgroundColor = TextColor.ANSI.DEFAULT + clearRows(4) + textGraphics.putString(2, 4, "|Admins: $adminCount") + textGraphics.putString(width - 2 - "Add admins via commands|".length, 4, "Add admins via commands|") + } + + fun drawLogs(values: List) { + val width = terminal.terminalSize.columns - 6 + val heightMin = 5 + + var currentHeight = terminal.terminalSize.rows - 5 + + for (index in heightMin until currentHeight) { + clearRows(index) + } + + values.forEach { + if (currentHeight > heightMin) { + var x = it + while (currentHeight > heightMin) { + if (x.isEmpty() || x.isBlank()) break + textGraphics.foregroundColor = TextColor.ANSI.GREEN + textGraphics.backgroundColor = TextColor.ANSI.DEFAULT + val towrite = if (x.length > width) { + x.substring(0, width).also { + x = x.substring(width) + } + } else { + x.also { + x = "" + } + } + textGraphics.putString(3, currentHeight, towrite, SGR.ITALIC) + --currentHeight + } + } + } + + textGraphics.putString(3, 9, "AAAAAAAAAAAAAAAAAAAAAAa", SGR.ITALIC) + terminal.flush() + } + + fun pushLog(uin: Long, str: String) { + log[uin]!!.push(str) + if (uin == screens[currentScreenId]) { + drawLogs(log[screens[currentScreenId]]!!) + } + } + + + var commandBuilder = StringBuilder() + + fun redrawCommand() { + val height = terminal.terminalSize.rows + val width = terminal.terminalSize.columns + clearRows(height - 3) + textGraphics.foregroundColor = TextColor.ANSI.DEFAULT + textGraphics.putString(2, height - 3, "|>>>") + textGraphics.putString(width - 3, height - 3, "|") + textGraphics.foregroundColor = TextColor.ANSI.BLUE + textGraphics.putString(7, height - 3, commandBuilder.toString()) + if (terminal is SwingTerminalFrame) { + terminal.flush() + } + } + + fun addCommandChar( + c: Char + ) { + if (commandBuilder.isEmpty() && c != '/') { + addCommandChar('/') + } + textGraphics.foregroundColor = TextColor.ANSI.BLUE + val height = terminal.terminalSize.rows + commandBuilder.append(c) + if (terminal is SwingTerminalFrame) { + redrawCommand() + } else { + textGraphics.putString(6 + commandBuilder.length, height - 3, c.toString()) + } + } + + fun deleteCommandChar() { + if (!commandBuilder.isEmpty()) { + commandBuilder = StringBuilder(commandBuilder.toString().substring(0, commandBuilder.length - 1)) + } + val height = terminal.terminalSize.rows + if (terminal is SwingTerminalFrame) { + redrawCommand() + } else { + textGraphics.putString(7 + commandBuilder.length, height - 3, " ") + } + } + + + fun emptyCommand() { + commandBuilder = StringBuilder() + redrawCommand() + if (terminal is SwingTerminal) { + terminal.flush() + } + } + + fun update() { + when (screens[currentScreenId]) { + 0L -> { + drawMainFrame(screens.size - 1) + } + else -> { + drawBotFrame(screens[currentScreenId], 0) + } + } + terminal.flush() + } } class LimitLinkedQueue( val limit: Int = 50 -) : LinkedList() { +) : LinkedList(), List { override fun push(e: T) { if (size >= limit) { pollLast()