From d403d5d79c735483e3867047b8ac84736b6bdf04 Mon Sep 17 00:00:00 2001 From: Him188 Date: Thu, 10 Sep 2020 08:49:03 +0800 Subject: [PATCH] Remove mirai-console-terminal --- frontend/mirai-console-terminal/README.md | 6 - .../mirai-console-terminal/build.gradle.kts | 49 -- .../console/MiraiConsoleTerminalFrontEnd.kt | 727 ------------------ .../console/MiraiConsoleTerminalLoader.kt | 40 - 4 files changed, 822 deletions(-) delete mode 100644 frontend/mirai-console-terminal/README.md delete mode 100644 frontend/mirai-console-terminal/build.gradle.kts delete mode 100644 frontend/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalFrontEnd.kt delete mode 100644 frontend/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalLoader.kt diff --git a/frontend/mirai-console-terminal/README.md b/frontend/mirai-console-terminal/README.md deleted file mode 100644 index bd7980bfe..000000000 --- a/frontend/mirai-console-terminal/README.md +++ /dev/null @@ -1,6 +0,0 @@ -### Mirai Console Terminal -支持windows/mac/linux -在terminal环境下的Console, 由控制台富文本实现简易UI -优点: 可以在linux环境下运行/简洁使用效率高 -缺点: 需要有略微的terminal知识 -所使用插件系统与graphical版本一致 可以来回切换 \ No newline at end of file diff --git a/frontend/mirai-console-terminal/build.gradle.kts b/frontend/mirai-console-terminal/build.gradle.kts deleted file mode 100644 index cea7f593a..000000000 --- a/frontend/mirai-console-terminal/build.gradle.kts +++ /dev/null @@ -1,49 +0,0 @@ -plugins { - id("kotlinx-serialization") - id("kotlin") - id("java") -} - - -apply(plugin = "com.github.johnrengelman.shadow") - -version = Versions.Mirai.console - -tasks.withType { - manifest { - attributes["Main-Class"] = "net.mamoe.mirai.console.MiraiConsoleTerminalLoader" - } -} - -kotlin { - sourceSets { - all { - - languageSettings.useExperimentalAnnotation("kotlin.Experimental") - languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn") - languageSettings.progressiveMode = true - languageSettings.useExperimentalAnnotation("net.mamoe.mirai.utils.MiraiInternalAPI") - } - } -} - -dependencies { - compileOnly("net.mamoe:mirai-core-qqandroid:${Versions.core}") - api(project(":mirai-console")) - api(group = "com.googlecode.lanterna", name = "lanterna", version = "3.0.2") -} -val compileKotlin: org.jetbrains.kotlin.gradle.tasks.KotlinCompile by tasks -compileKotlin.kotlinOptions { - jvmTarget = "1.8" -} -val compileTestKotlin: org.jetbrains.kotlin.gradle.tasks.KotlinCompile by tasks -compileTestKotlin.kotlinOptions { - jvmTarget = "1.8" -} -java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} -tasks.withType(JavaCompile::class.java) { - options.encoding = "UTF8" -} diff --git a/frontend/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalFrontEnd.kt b/frontend/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalFrontEnd.kt deleted file mode 100644 index 215b452d4..000000000 --- a/frontend/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalFrontEnd.kt +++ /dev/null @@ -1,727 +0,0 @@ -/* - * Copyright 2019-2020 Mamoe Technologies and contributors. - * - * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. - * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link. - * - * https://github.com/mamoe/mirai/blob/master/LICENSE - */ - -@file:Suppress("MemberVisibilityCanBePrivate") - -package net.mamoe.mirai.console - -import com.googlecode.lanterna.SGR -import com.googlecode.lanterna.TerminalSize -import com.googlecode.lanterna.TextColor -import com.googlecode.lanterna.graphics.TextGraphics -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.swing.SwingTerminal -import com.googlecode.lanterna.terminal.swing.SwingTerminalFrame -import kotlinx.coroutines.* -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.use -import net.mamoe.mirai.Bot -import net.mamoe.mirai.console.MiraiConsoleTerminalFrontEnd.LoggerDrawer.cleanPage -import net.mamoe.mirai.console.MiraiConsoleTerminalFrontEnd.LoggerDrawer.drawLog -import net.mamoe.mirai.console.MiraiConsoleTerminalFrontEnd.LoggerDrawer.redrawLogs -import net.mamoe.mirai.console.command.CommandManager -import net.mamoe.mirai.console.command.ConsoleCommandSender -import net.mamoe.mirai.console.utils.MiraiConsoleFrontEnd -import net.mamoe.mirai.utils.LoginSolver -import net.mamoe.mirai.utils.SimpleLogger.LogPriority -import java.awt.Image -import java.awt.image.BufferedImage -import java.io.File -import java.io.OutputStream -import java.io.PrintStream -import java.io.RandomAccessFile -import java.nio.ByteBuffer -import java.nio.charset.Charset -import java.util.* -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.ConcurrentLinkedDeque -import javax.imageio.ImageIO -import kotlin.concurrent.thread -import kotlin.coroutines.CoroutineContext -import kotlin.system.exitProcess - -/** - * 此文件不推荐任何人看 - * 可能导致 - * 1:心肌梗死 - * 2:呼吸困难 - * 3:想要重写但是发现改任何一个看似不合理的地方都会崩 - * - * @author NaturalHG - * - */ - -val String.actualLength: Int get() = this.sumBy { if (it.isChineseChar) 2 else 1 } - - -fun String.getSubStringIndexByActualLength(widthMax: Int): Int { - return this.sumBy { if (it.isChineseChar) 2 else 1 }.coerceAtMost(widthMax).coerceAtLeast(2) -} - -val Char.isChineseChar: Boolean - get() { - return this.toString().isChineseChar - } - -val String.isChineseChar: Boolean - get() { - return this.matches(Regex("[\u4e00-\u9fa5]")) - } - - -object MiraiConsoleTerminalFrontEnd : MiraiConsoleFrontEnd { - const val cacheLogSize = 50 - var mainTitle = "Mirai Console v0.01 Core v0.15" - - override fun pushVersion(consoleVersion: String, consoleBuild: String, coreVersion: String) { - mainTitle = "Mirai Console(Terminal) $consoleVersion $consoleBuild Core $coreVersion" - } - - override fun pushLog(identity: Long, message: String) { - log[identity]!!.push(message) - if (identity == screens[currentScreenId]) { - drawLog(message) - } - } - - // 修改interface之后用来暂时占位 - override fun pushLog(priority: LogPriority, identityStr: String, identity: Long, message: String) { - this.pushLog(identity, message) - } - - override fun prePushBot(identity: Long) { - log[identity] = LimitLinkedQueue(cacheLogSize) - } - - override fun pushBot(bot: Bot) { - botAdminCount[bot.id] = 0 - screens.add(bot.id) - drawFrame(this.getScreenName(currentScreenId)) - if (terminal is SwingTerminalFrame) { - terminal.flush() - } - } - - @Volatile - var requesting = false - private var requestResult: String? = null - override suspend fun requestInput(hint:String): String { - if(hint.isNotEmpty()){ - this.pushLog(0, hint) - } - requesting = true - while (requesting) { - delay(100) - } - return requestResult!! - } - - - private fun provideInput(input: String) { - if (requesting) { - requestResult = input - requesting = false - } else { - CommandManager.runCommand(ConsoleCommandSender, commandBuilder.toString()) - } - } - - - override fun pushBotAdminStatus(identity: Long, admins: List) { - botAdminCount[identity] = admins.size - } - - override fun createLoginSolver(): LoginSolver { - return object : LoginSolver() { - override suspend fun onSolvePicCaptcha(bot: Bot, data: ByteArray): String? { - val tempFile: File = createTempFile(suffix = ".png").apply { deleteOnExit() } - withContext(Dispatchers.IO) { - tempFile.createNewFile() - pushLog(0, "[Login Solver]需要图片验证码登录, 验证码为 4 字母") - try { - tempFile.writeChannel().apply { - writeFully(ByteBuffer.wrap(data)) - close() - } - pushLog(0, "请查看文件 ${tempFile.absolutePath}") - } catch (e: Exception) { - error("[Login Solver]验证码无法保存[Error0001]") - } - } - - lateinit var toLog: String - tempFile.inputStream().use { - val img = ImageIO.read(it) - toLog += img?.createCharImg((terminal.terminalSize.columns / 1.5).toInt()) ?: "无法创建字符图片. 请查看文件\n" - } - return requestInput("$toLog[Login Solver]请输验证码. ${tempFile.absolutePath}") - .takeUnless { it.isEmpty() || it.length != 4 } - .also { - pushLog(0, "[Login Solver]正在提交[$it]中...") - } - } - - override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String? { - pushLog(0, "[Login Solver]需要滑动验证码") - pushLog(0, "[Login Solver]请在任意浏览器中打开以下链接并完成验证码. ") - pushLog(0, url) - return requestInput("[Login Solver]完成后请输入任意字符 ").also { - pushLog(0, "[Login Solver]正在提交中") - } - } - - override suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String? { - pushLog(0, "[Login Solver]需要进行账户安全认证") - pushLog(0, "[Login Solver]该账户有[设备锁]/[不常用登录地点]/[不常用设备登录]的问题") - pushLog(0, "[Login Solver]完成以下账号认证即可成功登录|理论本认证在mirai每个账户中最多出现1次") - pushLog(0, "[Login Solver]请将该链接在QQ浏览器中打开并完成认证, 成功后输入任意字符") - pushLog(0, "[Login Solver]这步操作将在后续的版本中优化") - pushLog(0, url) - return requestInput("").also { - pushLog(0, "[Login Solver]正在提交中...") - } - } - - } - } - - private val log = ConcurrentHashMap>().also { - it[0L] = LimitLinkedQueue(cacheLogSize) - } - - private val botAdminCount = ConcurrentHashMap() - - private val screens = mutableListOf(0L) - private var currentScreenId = 0 - - - lateinit var terminal: Terminal - lateinit var textGraphics: TextGraphics - - private var hasStart = false - private lateinit var internalPrinter: PrintStream - fun start() { - if (hasStart) { - return - } - - internalPrinter = System.out - - - hasStart = true - val defaultTerminalFactory = DefaultTerminalFactory(internalPrinter, System.`in`, Charset.defaultCharset()) - try { - terminal = defaultTerminalFactory.createTerminal() - terminal.enterPrivateMode() - terminal.clearScreen() - terminal.setCursorVisible(false) - } catch (e: Exception) { - try { - terminal = SwingTerminalFrame("Mirai Console") - terminal.enterPrivateMode() - terminal.clearScreen() - terminal.setCursorVisible(false) - } catch (e: Exception) { - error("can not create terminal") - } - } - textGraphics = terminal.newTextGraphics() - - /* - var lastRedrawTime = 0L - var lastNewWidth = 0 - var lastNewHeight = 0 - - terminal.addResizeListener(TerminalResizeListener { terminal1: Terminal, newSize: TerminalSize -> - try { - if (lastNewHeight == newSize.rows - && - lastNewWidth == newSize.columns - ) { - return@TerminalResizeListener - } - lastNewHeight = newSize.rows - lastNewWidth = newSize.columns - terminal.clearScreen() - if(terminal !is SwingTerminalFrame) { - Thread.sleep(300) - } - update() - redrawCommand() - redrawLogs(log[screens[currentScreenId]]!!) - }catch (ignored:Exception){ - - } - }) - - */ - var lastJob: Job? = null - terminal.addResizeListener { _: Terminal, _: TerminalSize -> - lastJob = GlobalScope.launch { - try { - delay(300) - if (lastJob == coroutineContext[Job]) { - @Suppress("BlockingMethodInNonBlockingContext") - terminal.clearScreen() - //inited = false - update() - redrawCommand() - redrawLogs(log[screens[currentScreenId]]!!) - } - } catch (e: Exception) { - pushLog(0, "[UI ERROR] ${e.message}") - } - } - } - - if (terminal !is SwingTerminalFrame) { - System.setOut(PrintStream(object : OutputStream() { - var builder = java.lang.StringBuilder() - override fun write(b: Int) { - with(b.toChar()) { - if (this == '\n') { - pushLog(0, builder.toString()) - builder = java.lang.StringBuilder() - } else { - builder.append(this) - } - } - } - })) - } - - System.setErr(System.out) - - try { - update() - } catch (e: Exception) { - pushLog(0, "[UI ERROR] ${e.message}") - } - - val charList = listOf(',', '.', '/', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '=', '+', '!', ' ') - thread { - while (true) { - try { - val keyStroke: KeyStroke = terminal.readInput() - - when (keyStroke.keyType) { - KeyType.ArrowLeft -> { - currentScreenId = - getLeftScreenId() - clearRows(2) - cleanPage() - update() - } - KeyType.ArrowRight -> { - currentScreenId = - getRightScreenId() - clearRows(2) - cleanPage() - update() - } - KeyType.Enter -> { - provideInput(commandBuilder.toString()) - emptyCommand() - } - KeyType.Escape -> { - exit() - } - 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) { - pushLog(0, "[UI ERROR] ${e.message}") - } - } - } - } - - private fun getLeftScreenId(): Int { - var newId = currentScreenId - 1 - if (newId < 0) { - newId = screens.size - 1 - } - return newId - } - - private fun getRightScreenId(): Int { - var newId = 1 + currentScreenId - if (newId >= screens.size) { - newId = 0 - } - return newId - } - - private fun getScreenName(id: Int): String { - return when (screens[id]) { - 0L -> { - "Console Screen" - } - else -> { - "Bot: ${screens[id]}" - } - } - } - - - 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) - - textGraphics.foregroundColor = TextColor.ANSI.WHITE - textGraphics.backgroundColor = TextColor.ANSI.GREEN - 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)) - 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)) - - textGraphics.foregroundColor = TextColor.ANSI.DEFAULT - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - val leftName = - getScreenName(getLeftScreenId()) - // clearRows(2) - 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.foregroundColor = TextColor.ANSI.DEFAULT - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - val rightName = - getScreenName(getRightScreenId()) - textGraphics.putString((width + title.actualLength) / 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|".actualLength, - 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|".actualLength, 4, "Add admins via commands|") - } - - - object LoggerDrawer { - var currentHeight = 6 - - fun drawLog(string: String, flush: Boolean = true) { - val maxHeight = terminal.terminalSize.rows - 4 - val heightNeed = (string.actualLength / (terminal.terminalSize.columns - 6)) + 1 - if (heightNeed - 1 > maxHeight) { - pushLog(0, "[UI ERROR]: 您的屏幕太小, 有一条超长LOG无法显示") - return//拒绝打印 - } - if (currentHeight + heightNeed > maxHeight) { - cleanPage()//翻页 - } - if (string.contains("\n")) { - string.split("\n").forEach { _ -> - drawLog(string, false) - } - } else { - val width = terminal.terminalSize.columns - 6 - var x = string - while (true) { - if (x == "") { - break - } - val toWrite = if (x.actualLength > width) { - val index = x.getSubStringIndexByActualLength(width) - x.substring(0, index).also { - x = if (index < x.length) { - x.substring(index) - } else { - "" - } - } - } else { - x.also { - x = "" - } - } - try { - textGraphics.foregroundColor = TextColor.ANSI.GREEN - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - textGraphics.putString( - 3, - currentHeight, toWrite, SGR.ITALIC - ) - } catch (ignored: Exception) { - // - } - ++currentHeight - } - } - if (flush && terminal is SwingTerminalFrame) { - terminal.flush() - } - } - - - fun cleanPage() { - for (index in 6 until terminal.terminalSize.rows - 4) { - clearRows(index) - } - currentHeight = 6 - } - - - fun redrawLogs(toDraw: Queue) { - //this.cleanPage() - currentHeight = 6 - var logsToDraw = 0 - var vara = 0 - val toPrint = mutableListOf() - toDraw.forEach { - val heightNeed = (it.actualLength / (terminal.terminalSize.columns - 6)) + 1 - vara += heightNeed - if (currentHeight + vara < terminal.terminalSize.rows - 4) { - logsToDraw++ - toPrint.add(it) - } else { - return@forEach - } - } - toPrint.reversed().forEach { - drawLog(it, false) - } - if (terminal is SwingTerminalFrame) { - terminal.flush() - } - } - } - - - private var commandBuilder = StringBuilder() - private 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.WHITE - textGraphics.backgroundColor = TextColor.ANSI.BLACK - textGraphics.putString(7, height - 3, commandBuilder.toString()) - if (terminal is SwingTerminalFrame) { - terminal.flush() - } - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - } - - private fun addCommandChar( - c: Char - ) { - if (!requesting && commandBuilder.isEmpty() && c != '/') { - addCommandChar('/') - } - textGraphics.foregroundColor = TextColor.ANSI.WHITE - textGraphics.backgroundColor = TextColor.ANSI.BLACK - val height = terminal.terminalSize.rows - commandBuilder.append(c) - if (terminal is SwingTerminalFrame) { - redrawCommand() - } else { - textGraphics.putString(6 + commandBuilder.length, height - 3, c.toString()) - } - textGraphics.backgroundColor = TextColor.ANSI.DEFAULT - } - - private fun deleteCommandChar() { - if (commandBuilder.isNotEmpty()) { - 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, " ") - } - } - - - private var lastEmpty: Job? = null - private fun emptyCommand() { - commandBuilder = StringBuilder() - if (terminal is SwingTerminal) { - redrawCommand() - terminal.flush() - } else { - lastEmpty = GlobalScope.launch { - try { - delay(100) - if (lastEmpty == coroutineContext[Job]) { - withContext(Dispatchers.IO) { - terminal.clearScreen() - } - //inited = false - update() - redrawCommand() - redrawLogs(log[screens[currentScreenId]]!!) - } - } catch (e: Exception) { - pushLog(0, "[UI ERROR] ${e.message}") - } - } - } - } - - private fun update() { - when (screens[currentScreenId]) { - 0L -> { - drawMainFrame(screens.size - 1) - } - else -> { - drawBotFrame( - screens[currentScreenId], - 0 - ) - } - } - redrawLogs(log[screens[currentScreenId]]!!) - } - - fun exit() { - try { - terminal.exitPrivateMode() - terminal.close() - exitProcess(0) - } catch (ignored: Exception) { - - } - } -} - - -class LimitLinkedQueue( - private val limit: Int = 50 -) : ConcurrentLinkedDeque() { - override fun push(e: T) { - if (size >= limit) { - this.pollLast() - } - return super.push(e) - } -} - -/** - * @author NaturalHG - */ -private fun BufferedImage.createCharImg(outputWidth: Int = 100, ignoreRate: Double = 0.95): String { - val newHeight = (this.height * (outputWidth.toDouble() / this.width)).toInt() - val tmp = this.getScaledInstance(outputWidth, newHeight, Image.SCALE_SMOOTH) - val image = BufferedImage(outputWidth, newHeight, BufferedImage.TYPE_INT_ARGB) - val g2d = image.createGraphics() - g2d.drawImage(tmp, 0, 0, null) - fun gray(rgb: Int): Int { - val r = rgb and 0xff0000 shr 16 - val g = rgb and 0x00ff00 shr 8 - val b = rgb and 0x0000ff - return (r * 30 + g * 59 + b * 11 + 50) / 100 - } - - fun grayCompare(g1: Int, g2: Int): Boolean = - kotlin.math.min(g1, g2).toDouble() / kotlin.math.max(g1, g2) >= ignoreRate - - val background = gray(image.getRGB(0, 0)) - - return buildString(capacity = height) { - - val lines = mutableListOf() - - var minXPos = outputWidth - var maxXPos = 0 - - for (y in 0 until image.height) { - val builderLine = StringBuilder() - for (x in 0 until image.width) { - val gray = gray(image.getRGB(x, y)) - if (grayCompare(gray, background)) { - builderLine.append(" ") - } else { - builderLine.append("#") - if (x < minXPos) { - minXPos = x - } - if (x > maxXPos) { - maxXPos = x - } - } - } - if (builderLine.toString().isBlank()) { - continue - } - lines.add(builderLine) - } - for (line in lines) { - append(line.substring(minXPos, maxXPos)).append("\n") - } - } -} - -// Copied from Ktor CIO -private fun File.writeChannel( - coroutineContext: CoroutineContext = Dispatchers.IO -): ByteWriteChannel = GlobalScope.reader(CoroutineName("file-writer") + coroutineContext, autoFlush = true) { - @Suppress("BlockingMethodInNonBlockingContext") - RandomAccessFile(this@writeChannel, "rw").use { file -> - val copied = channel.copyTo(file.channel) - file.setLength(copied) // truncate tail that could remain from the previously written data - } -}.channel diff --git a/frontend/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalLoader.kt b/frontend/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalLoader.kt deleted file mode 100644 index 7cf2e3603..000000000 --- a/frontend/mirai-console-terminal/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleTerminalLoader.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2019-2020 Mamoe Technologies and contributors. - * - * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. - * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link. - * - * https://github.com/mamoe/mirai/blob/master/LICENSE - */ - -package net.mamoe.mirai.console - -import net.mamoe.mirai.console.pure.MiraiConsoleUIPure -import kotlin.concurrent.thread - -class MiraiConsoleTerminalLoader { - companion object { - @JvmStatic - fun main(args: Array) { - if (args.contains("pure") || args.contains("-pure") || System.getProperty( - "os.name", - "" - ).toLowerCase().contains("windows") - ) { - println("[MiraiConsoleTerminalLoader]: 将以Pure[兼容模式]启动Console") - MiraiConsole.start(MiraiConsoleUIPure()) - } else { - MiraiConsoleTerminalFrontEnd.start() - thread { - MiraiConsole.start( - MiraiConsoleTerminalFrontEnd - ) - } - } - Runtime.getRuntime().addShutdownHook(thread(start = false) { - MiraiConsole.stop() - MiraiConsoleTerminalFrontEnd.exit() - }) - } - } -} \ No newline at end of file