Commit baa3e56d authored by Him188's avatar Him188

Merge remote-tracking branch 'origin/master'

parents 25b3b2b2 1437ad70
...@@ -11,10 +11,15 @@ package net.mamoe.mirai.api.http ...@@ -11,10 +11,15 @@ package net.mamoe.mirai.api.http
import io.ktor.application.Application import io.ktor.application.Application
import io.ktor.server.cio.CIO import io.ktor.server.cio.CIO
import io.ktor.server.engine.applicationEngineEnvironment
import io.ktor.server.engine.connector
import io.ktor.server.engine.embeddedServer import io.ktor.server.engine.embeddedServer
import io.ktor.util.KtorExperimentalAPI import io.ktor.util.KtorExperimentalAPI
import net.mamoe.mirai.api.http.route.mirai import net.mamoe.mirai.api.http.route.mirai
import net.mamoe.mirai.utils.DefaultLogger import net.mamoe.mirai.utils.DefaultLogger
import org.slf4j.LoggerFactory
import org.slf4j.helpers.NOPLogger
import org.slf4j.helpers.NOPLoggerFactory
object MiraiHttpAPIServer { object MiraiHttpAPIServer {
...@@ -39,7 +44,14 @@ object MiraiHttpAPIServer { ...@@ -39,7 +44,14 @@ object MiraiHttpAPIServer {
// TODO: start是无阻塞的,理应获取启动状态后再执行后续代码 // TODO: start是无阻塞的,理应获取启动状态后再执行后续代码
try { try {
embeddedServer(CIO, port, module = Application::mirai).start() embeddedServer(CIO, environment = applicationEngineEnvironment {
this.log = NOPLoggerFactory().getLogger("NMYSL")
this.module(Application::mirai)
connector {
this.port = port
}
}).start()
logger.info("Http api server is running with authKey: ${SessionManager.authKey}") logger.info("Http api server is running with authKey: ${SessionManager.authKey}")
callback?.invoke() callback?.invoke()
......
...@@ -35,11 +35,18 @@ import net.mamoe.mirai.api.http.data.common.DTO ...@@ -35,11 +35,18 @@ import net.mamoe.mirai.api.http.data.common.DTO
import net.mamoe.mirai.api.http.data.common.VerifyDTO import net.mamoe.mirai.api.http.data.common.VerifyDTO
import net.mamoe.mirai.api.http.util.jsonParseOrNull import net.mamoe.mirai.api.http.util.jsonParseOrNull
import net.mamoe.mirai.api.http.util.toJson import net.mamoe.mirai.api.http.util.toJson
import org.slf4j.Logger
import org.slf4j.helpers.NOPLogger
import org.slf4j.helpers.NOPLoggerFactory
import org.slf4j.impl.SimpleLogger
import org.slf4j.impl.SimpleLoggerFactory
fun Application.mirai() { fun Application.mirai() {
install(DefaultHeaders) install(DefaultHeaders)
install(CallLogging) install(CallLogging) {
logger = NOPLoggerFactory().getLogger("NMSL")
}
authModule() authModule()
messageModule() messageModule()
infoModule() infoModule()
......
...@@ -19,6 +19,7 @@ import net.mamoe.mirai.api.http.generateSessionKey ...@@ -19,6 +19,7 @@ import net.mamoe.mirai.api.http.generateSessionKey
import net.mamoe.mirai.contact.sendMessage import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import java.io.File import java.io.File
import java.io.PrintStream
import kotlin.concurrent.thread import kotlin.concurrent.thread
object MiraiConsole { object MiraiConsole {
...@@ -37,8 +38,7 @@ object MiraiConsole { ...@@ -37,8 +38,7 @@ object MiraiConsole {
val pluginManager: PluginManager val pluginManager: PluginManager
get() = PluginManager get() = PluginManager
var logger: MiraiConsoleLogger = var logger = UIPushLogger(0)
UIPushLogger()
var path: String = System.getProperty("user.dir") var path: String = System.getProperty("user.dir")
...@@ -255,11 +255,11 @@ object MiraiConsole { ...@@ -255,11 +255,11 @@ object MiraiConsole {
} }
} }
class UIPushLogger(override val identity: String?, override var follower: MiraiLogger?) : MiraiLogger { class UIPushLogger(val identity: Long) {
override fun invoke(any: Any?) { operator fun invoke(any: Any? = null) {
MiraiConsoleUI.start() MiraiConsoleUI.start()
if (any != null) { if (any != null) {
MiraiConsoleUI.pushLog(0, "[Mirai$version $build]: $any") MiraiConsoleUI.pushLog(identity, "[Mirai$version $build]: $any")
} }
} }
} }
...@@ -281,6 +281,7 @@ class MiraiConsoleLoader { ...@@ -281,6 +281,7 @@ class MiraiConsoleLoader {
companion object { companion object {
@JvmStatic @JvmStatic
fun main(args: Array<String>) { fun main(args: Array<String>) {
MiraiConsole.start() MiraiConsole.start()
Runtime.getRuntime().addShutdownHook(thread(start = false) { Runtime.getRuntime().addShutdownHook(thread(start = false) {
MiraiConsole.stop() MiraiConsole.stop()
......
...@@ -11,6 +11,8 @@ import com.googlecode.lanterna.terminal.Terminal ...@@ -11,6 +11,8 @@ import com.googlecode.lanterna.terminal.Terminal
import com.googlecode.lanterna.terminal.TerminalResizeListener import com.googlecode.lanterna.terminal.TerminalResizeListener
import com.googlecode.lanterna.terminal.swing.SwingTerminal import com.googlecode.lanterna.terminal.swing.SwingTerminal
import com.googlecode.lanterna.terminal.swing.SwingTerminalFrame import com.googlecode.lanterna.terminal.swing.SwingTerminalFrame
import java.io.OutputStream
import java.io.PrintStream
import java.lang.StringBuilder import java.lang.StringBuilder
import java.util.* import java.util.*
import kotlin.concurrent.thread import kotlin.concurrent.thread
...@@ -29,9 +31,9 @@ object MiraiConsoleUI { ...@@ -29,9 +31,9 @@ object MiraiConsoleUI {
log[uin] = LimitLinkedQueue() log[uin] = LimitLinkedQueue()
} }
fun pushLog(uin: Long, str: String) {
log[uin]!!.push(str) lateinit var terminal: Terminal
} lateinit var textGraphics: TextGraphics
var hasStart = false var hasStart = false
fun start() { fun start() {
...@@ -40,275 +42,274 @@ object MiraiConsoleUI { ...@@ -40,275 +42,274 @@ object MiraiConsoleUI {
} }
hasStart = true hasStart = true
val defaultTerminalFactory = DefaultTerminalFactory() val defaultTerminalFactory = DefaultTerminalFactory()
var terminal: Terminal? = null
try { try {
terminal = defaultTerminalFactory.createTerminal() terminal = defaultTerminalFactory.createTerminal()
terminal.enterPrivateMode() terminal.enterPrivateMode()
terminal.clearScreen() terminal.clearScreen()
terminal.setCursorVisible(false) terminal.setCursorVisible(false)
} catch (e: Exception) { } catch (e: Exception) {
terminal = SwingTerminalFrame("Mirai Console") try {
terminal.enterPrivateMode() terminal = SwingTerminalFrame("Mirai Console")
terminal.clearScreen() terminal.enterPrivateMode()
terminal.setCursorVisible(false) terminal.clearScreen()
} terminal.setCursorVisible(false)
if (terminal == null) { } catch (e: Exception) {
error("can not create terminal") error("can not create terminal")
}
} }
textGraphics = terminal.newTextGraphics()
val textGraphics: TextGraphics = terminal.newTextGraphics() terminal.addResizeListener(TerminalResizeListener { terminal1: Terminal, newSize: TerminalSize ->
terminal.clearScreen()
inited = false
update()
redrawCommand()
})
try { update()
fun getLeftScreenId(): Int {
var newId = currentScreenId - 1
if (newId < 0) {
newId = screens.size - 1
}
return newId
}
fun getRightScreenId(): Int { val charList = listOf(',', '.', '/', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '=', '+', '!', ' ')
var newId = 1 + currentScreenId thread {
if (newId >= screens.size) { while (true) {
newId = 0 var keyStroke: KeyStroke = terminal.readInput()
}
return newId
}
fun getScreenName(id: Int): String { when (keyStroke.keyType) {
return when (screens[id]) { KeyType.ArrowLeft -> {
0L -> { currentScreenId = getLeftScreenId()
"Console Screen" update()
}
KeyType.ArrowRight -> {
currentScreenId = getRightScreenId()
update()
}
KeyType.Enter -> {
emptyCommand()
} }
else -> { else -> {
"Bot: ${screens[id]}" if (keyStroke.character != null) {
if (keyStroke.character.toInt() == 8) {
deleteCommandChar()
}
if (keyStroke.character.isLetterOrDigit() || charList.contains(keyStroke.character)) {
addCommandChar(keyStroke.character)
}
}
} }
} }
} }
}
}
fun getLeftScreenId(): Int {
var newId = currentScreenId - 1
if (newId < 0) {
newId = screens.size - 1
}
return newId
}
var inited = false fun getRightScreenId(): Int {
fun clearRows(row: Int) { var newId = 1 + currentScreenId
textGraphics.putString(0, row, " ".repeat(terminal.terminalSize.columns)) if (newId >= screens.size) {
} newId = 0
}
return newId
}
fun drawFrame( fun getScreenName(id: Int): String {
title: String return when (screens[id]) {
) { 0L -> {
val width = terminal.terminalSize.columns "Console Screen"
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")
} }
else -> {
fun drawMainFrame( "Bot: ${screens[id]}"
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<String>) { var inited = false
val width = terminal.terminalSize.columns - 6 fun clearRows(row: Int) {
val heightMin = 5 textGraphics.putString(0, row, " ".repeat(terminal.terminalSize.columns))
}
var currentHeight = terminal.terminalSize.rows - 5 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.15"
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")
}
for (index in heightMin until currentHeight) { fun drawMainFrame(
clearRows(index) 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|"
)
}
values.forEach { fun drawBotFrame(
if (currentHeight > heightMin) { qq: Long,
var x = it adminCount: Number
while (currentHeight > heightMin) { ) {
if (x.isEmpty() || x.isBlank()) break drawFrame("Bot: $qq")
textGraphics.foregroundColor = TextColor.ANSI.GREEN val width = terminal.terminalSize.columns
textGraphics.backgroundColor = TextColor.ANSI.DEFAULT textGraphics.foregroundColor = TextColor.ANSI.DEFAULT
val towrite = if (x.length > width) { textGraphics.backgroundColor = TextColor.ANSI.DEFAULT
x.substring(0, width).also { clearRows(4)
x = x.substring(width) textGraphics.putString(2, 4, "|Admins: $adminCount")
} textGraphics.putString(width - 2 - "Add admins via commands|".length, 4, "Add admins via commands|")
} else { }
x.also {
x = ""
}
}
textGraphics.putString(3, currentHeight, towrite, SGR.ITALIC)
--currentHeight
}
}
}
if (terminal is SwingTerminalFrame) { fun drawLogs(values: List<String>) {
terminal.flush() val width = terminal.terminalSize.columns - 6
} val heightMin = 5
}
var currentHeight = terminal.terminalSize.rows - 5
var commandBuilder = StringBuilder() for (index in heightMin until currentHeight) {
clearRows(index)
}
fun redrawCommand() { values.forEach {
val height = terminal.terminalSize.rows if (currentHeight > heightMin) {
val width = terminal.terminalSize.columns var x = it
clearRows(height - 3) while (currentHeight > heightMin) {
textGraphics.foregroundColor = TextColor.ANSI.DEFAULT if (x.isEmpty() || x.isBlank()) break
textGraphics.putString(2, height - 3, "|>>>") textGraphics.foregroundColor = TextColor.ANSI.GREEN
textGraphics.putString(width - 3, height - 3, "|") textGraphics.backgroundColor = TextColor.ANSI.DEFAULT
textGraphics.foregroundColor = TextColor.ANSI.BLUE val towrite = if (x.length > width) {
textGraphics.putString(7, height - 3, commandBuilder.toString()) x.substring(0, width).also {
if (terminal is SwingTerminalFrame) { x = x.substring(width)
terminal.flush() }
} else {
x.also {
x = ""
}
}
textGraphics.putString(3, currentHeight, towrite, SGR.ITALIC)
--currentHeight
} }
} }
}
fun addCommandChar( textGraphics.putString(3, 9, "AAAAAAAAAAAAAAAAAAAAAAa", SGR.ITALIC)
c: Char terminal.flush()
) { }
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() { fun pushLog(uin: Long, str: String) {
if (!commandBuilder.isEmpty()) { log[uin]!!.push(str)
commandBuilder = StringBuilder(commandBuilder.toString().substring(0, commandBuilder.length - 1)) if (uin == screens[currentScreenId]) {
} drawLogs(log[screens[currentScreenId]]!!)
val height = terminal.terminalSize.rows }
if (terminal is SwingTerminalFrame) { }
redrawCommand()
} else {
textGraphics.putString(7 + commandBuilder.length, height - 3, " ")
}
}
fun emptyCommand() { var commandBuilder = StringBuilder()
commandBuilder = StringBuilder()
redrawCommand()
if (terminal is SwingTerminal) {
terminal.flush()
}
}
fun update() { fun redrawCommand() {
when (screens[currentScreenId]) { val height = terminal.terminalSize.rows
0L -> { val width = terminal.terminalSize.columns
drawMainFrame(screens.size - 1) clearRows(height - 3)
} textGraphics.foregroundColor = TextColor.ANSI.DEFAULT
else -> { textGraphics.putString(2, height - 3, "|>>>")
drawBotFrame(screens[currentScreenId], 0) textGraphics.putString(width - 3, height - 3, "|")
} textGraphics.foregroundColor = TextColor.ANSI.BLUE
} textGraphics.putString(7, height - 3, commandBuilder.toString())
terminal.flush() 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())
}
}
terminal.addResizeListener(TerminalResizeListener { terminal1: Terminal, newSize: TerminalSize -> fun deleteCommandChar() {
terminal.clearScreen() if (!commandBuilder.isEmpty()) {
inited = false commandBuilder = StringBuilder(commandBuilder.toString().substring(0, commandBuilder.length - 1))
update() }
redrawCommand() val height = terminal.terminalSize.rows
}) if (terminal is SwingTerminalFrame) {
redrawCommand()
} else {
textGraphics.putString(7 + commandBuilder.length, height - 3, " ")
}
}
update()
val charList = listOf(',', '.', '/', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '=', '+', '!', ' ') fun emptyCommand() {
thread { commandBuilder = StringBuilder()
while (true) { redrawCommand()
var keyStroke: KeyStroke = terminal.readInput() if (terminal is SwingTerminal) {
terminal.flush()
}
}
when (keyStroke.keyType) { fun update() {
KeyType.ArrowLeft -> { when (screens[currentScreenId]) {
currentScreenId = getLeftScreenId() 0L -> {
update() drawMainFrame(screens.size - 1)
} }
KeyType.ArrowRight -> { else -> {
currentScreenId = getRightScreenId() drawBotFrame(screens[currentScreenId], 0)
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()
} }
terminal.flush()
} }
} }
class LimitLinkedQueue<T>( class LimitLinkedQueue<T>(
val limit: Int = 50 val limit: Int = 50
) : LinkedList<T>() { ) : LinkedList<T>(), List<T> {
override fun push(e: T) { override fun push(e: T) {
if (size >= limit) { if (size >= limit) {
pollLast() pollLast()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment