Merge remote-tracking branch 'origin/master'

This commit is contained in:
jiahua.liu 2020-03-18 16:26:34 +08:00
commit c93678a60b
16 changed files with 231 additions and 67 deletions

View File

@ -44,6 +44,8 @@ dependencies {
api(group = "no.tornado", name = "tornadofx", version = "1.7.19") api(group = "no.tornado", name = "tornadofx", version = "1.7.19")
api(group = "com.jfoenix", name = "jfoenix", version = "9.0.8") api(group = "com.jfoenix", name = "jfoenix", version = "9.0.8")
testApi(group = "org.yaml", name = "snakeyaml", version = "1.25")
} }
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> { tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {

View File

@ -17,12 +17,12 @@ import tornadofx.App
import tornadofx.find import tornadofx.find
import tornadofx.launch import tornadofx.launch
object MiraiGraphicalLoader { //object MiraiGraphicalLoader {
@JvmStatic // @JvmStatic
fun main(args: Array<String>) { // fun main(args: Array<String>) {
launch<MiraiGraphicalUI>(args) // launch<MiraiGraphicalUI>(args)
} // }
} //}
class MiraiGraphicalUI : App(Decorator::class, PrimaryStyleSheet::class) { class MiraiGraphicalUI : App(Decorator::class, PrimaryStyleSheet::class) {

View File

@ -5,18 +5,17 @@ import javafx.collections.ObservableList
import javafx.stage.Modality import javafx.stage.Modality
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.graphical.model.BotModel import net.mamoe.mirai.console.graphical.model.*
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.graphical.view.VerificationCodeFragment
import net.mamoe.mirai.console.plugins.PluginManager import net.mamoe.mirai.console.plugins.PluginManager
import net.mamoe.mirai.console.utils.MiraiConsoleUI import net.mamoe.mirai.console.utils.MiraiConsoleUI
import net.mamoe.mirai.utils.LoginSolver import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
import tornadofx.* import tornadofx.*
class MiraiGraphicalUIController : Controller(), MiraiConsoleUI { class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
private val settingModel = find<GlobalSettingModel>()
private val loginSolver = GraphicalLoginSolver() private val loginSolver = GraphicalLoginSolver()
private val cache = mutableMapOf<Long, BotModel>() private val cache = mutableMapOf<Long, BotModel>()
val mainLog = observableListOf<String>() val mainLog = observableListOf<String>()
@ -34,12 +33,31 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
fun sendCommand(command: String) = MiraiConsole.CommandProcessor.runConsoleCommandBlocking(command) fun sendCommand(command: String) = MiraiConsole.CommandProcessor.runConsoleCommandBlocking(command)
override fun pushLog(identity: Long, message: String) = Platform.runLater { override fun pushLog(identity: Long, message: String) = Platform.runLater {
when (identity) { fun ObservableList<*>.trim() {
0L -> mainLog.add(message) println(size)
else -> cache[identity]?.logHistory?.add(message) println(settingModel.item.maxLongNum)
if (size > settingModel.item.maxLongNum) {
this.removeAt(0)
} }
} }
when (identity) {
0L -> mainLog.apply {
add(message)
mainLog.trim()
}
else -> cache[identity]?.logHistory?.apply {
add(message)
trim()
}
}
}
// 修改interface之后用来暂时占位
override fun pushLog(priority: LogPriority, identityStr: String, identity: Long, message: String) {
this.pushLog(identity, message)
}
override fun prePushBot(identity: Long) = Platform.runLater { override fun prePushBot(identity: Long) = Platform.runLater {
BotModel(identity).also { BotModel(identity).also {
cache[identity] = it cache[identity] = it

View File

@ -0,0 +1,17 @@
package net.mamoe.mirai.console.graphical.model
import javafx.beans.property.SimpleLongProperty
import tornadofx.ItemViewModel
import tornadofx.getValue
import tornadofx.setValue
class GlobalSetting {
val maxLogNumProperty = SimpleLongProperty(4096)
var maxLongNum: Long by maxLogNumProperty
}
class GlobalSettingModel(setting: GlobalSetting) : ItemViewModel<GlobalSetting>(setting) {
constructor() : this(GlobalSetting())
val maxLogNum = bind(GlobalSetting::maxLogNumProperty)
}

View File

@ -2,6 +2,7 @@ package net.mamoe.mirai.console.graphical.model
import com.jfoenix.controls.datamodels.treetable.RecursiveTreeObject import com.jfoenix.controls.datamodels.treetable.RecursiveTreeObject
import javafx.beans.property.SimpleBooleanProperty import javafx.beans.property.SimpleBooleanProperty
import javafx.beans.property.SimpleStringProperty
import net.mamoe.mirai.console.plugins.PluginDescription import net.mamoe.mirai.console.plugins.PluginDescription
import tornadofx.getValue import tornadofx.getValue
import tornadofx.setValue import tornadofx.setValue
@ -14,6 +15,11 @@ class PluginModel(
) : RecursiveTreeObject<PluginModel>() { ) : RecursiveTreeObject<PluginModel>() {
constructor(plugin: PluginDescription) : this(plugin.name, plugin.version, plugin.author, plugin.info) constructor(plugin: PluginDescription) : this(plugin.name, plugin.version, plugin.author, plugin.info)
val nameProperty = SimpleStringProperty(this, "nameProperty", name)
val versionProperty = SimpleStringProperty(this, "versionProperty", version)
val authorProperty = SimpleStringProperty(this, "authorProperty", author)
val descriptionProperty = SimpleStringProperty(this, "descriptionProperty", description)
val enabledProperty = SimpleBooleanProperty(this, "enabledProperty") val enabledProperty = SimpleBooleanProperty(this, "enabledProperty")
var enabled by enabledProperty var enabled by enabledProperty
} }

View File

@ -12,21 +12,48 @@ class PluginsView : View() {
val plugins = controller.pluginList val plugins = controller.pluginList
override val root = jfxTreeTableView(plugins) { override val root = jfxTreeTableView(plugins) {
isShowRoot = false
columns.addAll( columns.addAll(
JFXTreeTableColumn<PluginModel, String>("插件名").apply { JFXTreeTableColumn<PluginModel, String>("插件名").apply {
prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.1)) prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.1))
setCellValueFactory {
return@setCellValueFactory it.value.value.nameProperty
}
}, },
JFXTreeTableColumn<PluginModel, String>("版本").apply { JFXTreeTableColumn<PluginModel, String>("版本").apply {
prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.1)) prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.1))
setCellValueFactory {
return@setCellValueFactory it.value.value.versionProperty
}
}, },
JFXTreeTableColumn<PluginModel, String>("作者").apply { JFXTreeTableColumn<PluginModel, String>("作者").apply {
prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.1)) prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.1))
setCellValueFactory {
return@setCellValueFactory it.value.value.authorProperty
}
}, },
JFXTreeTableColumn<PluginModel, String>("介绍").apply { JFXTreeTableColumn<PluginModel, String>("介绍").apply {
prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.6)) prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.6))
setCellValueFactory {
return@setCellValueFactory it.value.value.descriptionProperty
}
}, },
JFXTreeTableColumn<PluginModel, String>("操作").apply { JFXTreeTableColumn<PluginModel, PluginModel>("操作").apply {
prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.08)) prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.08))
// setCellValueFactory { return@setCellValueFactory it.value.valueProperty() }
//
// setCellFactory {
// return@setCellFactory object : TreeTableCell<PluginModel, PluginModel>() {
// override fun updateItem(item: PluginModel?, empty: Boolean) {
//
// }
// }
// }
} }
) )
} }

View File

@ -1,38 +1,45 @@
package net.mamoe.mirai.console.graphical.view package net.mamoe.mirai.console.graphical.view
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
import net.mamoe.mirai.console.graphical.model.GlobalSettingModel
import net.mamoe.mirai.console.graphical.util.jfxButton import net.mamoe.mirai.console.graphical.util.jfxButton
import net.mamoe.mirai.console.graphical.util.jfxTextfield import net.mamoe.mirai.console.graphical.util.jfxTextfield
import tornadofx.View import tornadofx.*
import tornadofx.field import java.awt.Desktop
import tornadofx.fieldset import java.io.File
import tornadofx.form
class SettingsView : View() { class SettingsView : View() {
private val controller = find<MiraiGraphicalUIController>() private val controller = find<MiraiGraphicalUIController>()
private val settingModel = find<GlobalSettingModel>()
override val root = form { override val root = form {
fieldset { fieldset {
field { field {
jfxButton("撤掉") { } jfxButton("撤掉").action {
jfxButton("保存") { } settingModel.rollback()
}
jfxButton("保存").action {
settingModel.commit()
}
} }
} }
fieldset("插件目录") { fieldset("插件目录") {
field { field {
jfxTextfield("...") { isEditable = false } jfxTextfield((System.getProperty("user.dir") + "/plugins/").replace("//", "/")) { isEditable = false }
jfxButton("打开目录") jfxButton("打开目录").action {
(System.getProperty("user.dir") + "/plugins/").replace("//", "/").also { path ->
Desktop.getDesktop().takeIf { it.isSupported(Desktop.Action.OPEN) }?.open(File(path))
}
}
} }
} }
fieldset("最大日志容量") { fieldset("最大日志容量") {
field { field {
jfxTextfield("...") { jfxTextfield().bind(settingModel.maxLogNum)
}
} }
} }
} }

View File

@ -0,0 +1,6 @@
import net.mamoe.mirai.console.graphical.MiraiGraphicalUI
import tornadofx.launch
fun main(args: Array<String>) {
launch<MiraiGraphicalUI>(args)
}

View File

@ -24,6 +24,7 @@ import net.mamoe.mirai.console.MiraiConsoleTerminalUI.LoggerDrawer.drawLog
import net.mamoe.mirai.console.MiraiConsoleTerminalUI.LoggerDrawer.redrawLogs import net.mamoe.mirai.console.MiraiConsoleTerminalUI.LoggerDrawer.redrawLogs
import net.mamoe.mirai.console.utils.MiraiConsoleUI import net.mamoe.mirai.console.utils.MiraiConsoleUI
import net.mamoe.mirai.utils.LoginSolver import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
import java.awt.Image import java.awt.Image
import java.awt.image.BufferedImage import java.awt.image.BufferedImage
import java.io.File import java.io.File
@ -84,6 +85,11 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
} }
} }
// 修改interface之后用来暂时占位
override fun pushLog(priority: LogPriority, identityStr: String, identity: Long, message: String) {
this.pushLog(identity, message)
}
override fun prePushBot(identity: Long) { override fun prePushBot(identity: Long) {
log[identity] = LimitLinkedQueue(cacheLogSize) log[identity] = LimitLinkedQueue(cacheLogSize)
} }

View File

@ -11,14 +11,16 @@ const val CONSOLE_TERMINAL = "Terminal"
const val CONSOLE_GRAPHICAL = "Graphical" const val CONSOLE_GRAPHICAL = "Graphical"
object ConsoleUpdator{ object ConsoleUpdater {
@Suppress("SpellCheckingInspection") @Suppress("SpellCheckingInspection")
private object Links : HashMap<String, Map<String, String>>() { private object Links : HashMap<String, Map<String, String>>() {
init { init {
put(CONSOLE_PURE, mapOf( put(
CONSOLE_PURE, mapOf(
"version" to "/net/mamoe/mirai-console/" "version" to "/net/mamoe/mirai-console/"
)) )
)
} }
} }

View File

@ -59,19 +59,19 @@ object WrapperMain {
CoreUpdator.versionCheck() CoreUpdator.versionCheck()
} }
launch { launch {
ConsoleUpdator.versionCheck(type) ConsoleUpdater.versionCheck(type)
} }
} }
println("Version check complete, starting Mirai") println("Version check complete, starting Mirai")
println("Core :" + CoreUpdator.getCore()!!) println("Core :" + CoreUpdator.getCore()!!)
println("Protocol:" + CoreUpdator.getProtocolLib()!!) println("Protocol:" + CoreUpdator.getProtocolLib()!!)
println("Console :" + ConsoleUpdator.getFile()!! ) println("Console :" + ConsoleUpdater.getFile()!! )
println("Root :" + System.getProperty("user.dir") + "/") println("Root :" + System.getProperty("user.dir") + "/")
val loader = MiraiClassLoader( val loader = MiraiClassLoader(
CoreUpdator.getCore()!!, CoreUpdator.getCore()!!,
CoreUpdator.getProtocolLib()!!, CoreUpdator.getProtocolLib()!!,
ConsoleUpdator.getFile()!!, ConsoleUpdater.getFile()!!,
this.javaClass.classLoader this.javaClass.classLoader
) )
when(type) { when(type) {
@ -80,7 +80,7 @@ object WrapperMain {
loader.loadClass( loader.loadClass(
"net.mamoe.mirai.console.pure.MiraiConsolePureLoader" "net.mamoe.mirai.console.pure.MiraiConsolePureLoader"
).getMethod("load", String::class.java,String::class.java) ).getMethod("load", String::class.java,String::class.java)
.invoke(null,CoreUpdator.getCurrentVersion(),ConsoleUpdator.getCurrentVersion()) .invoke(null,CoreUpdator.getCurrentVersion(),ConsoleUpdater.getCurrentVersion())
} }
} }
} }

View File

@ -19,6 +19,7 @@ import net.mamoe.mirai.console.command.ConsoleCommandSender
import net.mamoe.mirai.console.command.DefaultCommands import net.mamoe.mirai.console.command.DefaultCommands
import net.mamoe.mirai.console.plugins.PluginManager import net.mamoe.mirai.console.plugins.PluginManager
import net.mamoe.mirai.console.utils.MiraiConsoleUI import net.mamoe.mirai.console.utils.MiraiConsoleUI
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
import net.mamoe.mirai.utils.cryptor.ECDH import net.mamoe.mirai.utils.cryptor.ECDH
@ -162,15 +163,28 @@ object MiraiConsole {
) )
} }
operator fun invoke(priority: LogPriority, identityStr: String, identity: Long, any: Any? = null) {
if (any != null) {
frontEnd.pushLog(priority, identityStr, identity, "$any")
}
}
operator fun invoke(priority: LogPriority, identityStr: String, identity: Long, e: Exception? = null) {
if (e != null) {
frontEnd.pushLog(priority, identityStr, identity, "${e.stackTrace}")
}
}
// 设置默认的pushLog输出为 INFO 类型
operator fun invoke(identityStr: String, identity: Long, any: Any? = null) { operator fun invoke(identityStr: String, identity: Long, any: Any? = null) {
if (any != null) { if (any != null) {
frontEnd.pushLog(identity, "$identityStr: $any") frontEnd.pushLog(LogPriority.INFO, identityStr, identity, "$any")
} }
} }
operator fun invoke(identityStr: String, identity: Long, e: Exception? = null) { operator fun invoke(identityStr: String, identity: Long, e: Exception? = null) {
if (e != null) { if (e != null) {
frontEnd.pushLog(identity, "$identityStr: ${e.stackTrace}") frontEnd.pushLog(LogPriority.INFO, identityStr, identity, "${e.stackTrace}")
} }
} }
} }

View File

@ -19,14 +19,17 @@ import net.mamoe.mirai.console.plugins.PluginBase
import net.mamoe.mirai.contact.Contact import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.contact.sendMessage import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
interface CommandSender { interface CommandSender {
/** /**
* 立刻发送一条Message * 立刻发送一条Message
*/ */
suspend fun sendMessage(messageChain: MessageChain) suspend fun sendMessage(messageChain: MessageChain)
suspend fun sendMessage(message: String) suspend fun sendMessage(message: String)
/** /**
* 写入要发送的内容 所有内容最后会被以一条发出 * 写入要发送的内容 所有内容最后会被以一条发出
*/ */

View File

@ -15,8 +15,10 @@ import kotlinx.coroutines.*
import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.command.Command import net.mamoe.mirai.console.command.Command
import net.mamoe.mirai.console.command.CommandSender import net.mamoe.mirai.console.command.CommandSender
import net.mamoe.mirai.console.pure.MiraiConsoleUIPure
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.SimpleLogger import net.mamoe.mirai.utils.SimpleLogger
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
import java.net.URLClassLoader import java.net.URLClassLoader
@ -93,10 +95,11 @@ abstract class PluginBase
internal var pluginName: String = "" internal var pluginName: String = ""
val logger: MiraiLogger by lazy { val logger: MiraiLogger by lazy {
SimpleLogger("Plugin $pluginName") { _, message, e -> SimpleLogger("Plugin $pluginName") { priority, message, e ->
MiraiConsole.logger("[${pluginName}]", 0, message) val identityString = "[${pluginName}]"
MiraiConsole.logger(priority, identityString, 0, message)
if (e != null) { if (e != null) {
MiraiConsole.logger("[${pluginName}]", 0, e) MiraiConsole.logger(priority, identityString, 0, e)
} }
} }
} }

View File

@ -15,6 +15,7 @@ import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.utils.MiraiConsoleUI import net.mamoe.mirai.console.utils.MiraiConsoleUI
import net.mamoe.mirai.utils.DefaultLoginSolver import net.mamoe.mirai.utils.DefaultLoginSolver
import net.mamoe.mirai.utils.LoginSolver import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import kotlin.concurrent.thread import kotlin.concurrent.thread
@ -24,6 +25,22 @@ class MiraiConsoleUIPure : MiraiConsoleUI {
private var requesting = false private var requesting = false
private var requestStr = "" private var requestStr = ""
@Suppress("unused")
companion object {
// ANSI color codes
const val COLOR_RED = "\u001b[38;5;196m"
const val COLOR_CYAN = "\u001b[38;5;87m"
const val COLOR_GREEN = "\u001b[38;5;82m"
// use a dark yellow(more like orange) instead of light one to save Solarized-light users
const val COLOR_YELLOW = "\u001b[38;5;220m"
const val COLOR_GREY = "\u001b[38;5;244m"
const val COLOR_BLUE = "\u001b[38;5;27m"
const val COLOR_NAVY = "\u001b[38;5;24m" // navy uniform blue
const val COLOR_PINK = "\u001b[38;5;207m"
const val COLOR_RESET = "\u001b[39;49m"
}
init { init {
thread { thread {
while (true) { while (true) {
@ -41,10 +58,38 @@ class MiraiConsoleUIPure : MiraiConsoleUI {
val sdf by lazy { val sdf by lazy {
SimpleDateFormat("HH:mm:ss") SimpleDateFormat("HH:mm:ss")
} }
override fun pushLog(identity: Long, message: String) { override fun pushLog(identity: Long, message: String) {
println("\u001b[0m " + sdf.format(Date()) + " $message") println("\u001b[0m " + sdf.format(Date()) + " $message")
} }
override fun pushLog(priority: LogPriority, identityStr: String, identity: Long, message: String) {
var priorityStr = "[${priority.name}]"
val _message = message + COLOR_RESET
if (MiraiConsole.frontEnd is MiraiConsoleUIPure) {
/**
* 通过ANSI控制码添加颜色
* 更多的颜色定义在 [MiraiConsoleUIPure] companion
*/
priorityStr = when (priority) {
LogPriority.ERROR
-> COLOR_RED + priorityStr + COLOR_RESET
LogPriority.WARNING
-> COLOR_RED + priorityStr + COLOR_RESET
LogPriority.VERBOSE
-> COLOR_NAVY + priorityStr + COLOR_RESET
LogPriority.DEBUG
-> COLOR_PINK + priorityStr + COLOR_RESET
else -> priorityStr
}
println("\u001b[0m " + sdf.format(Date()) + " $priorityStr $identityStr $_message")
}
}
override fun prePushBot(identity: Long) { override fun prePushBot(identity: Long) {
} }

View File

@ -11,6 +11,7 @@ package net.mamoe.mirai.console.utils
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.utils.LoginSolver import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
/** /**
* 只需要实现一个这个 传入MiraiConsole 就可以绑定UI层与Console层 * 只需要实现一个这个 传入MiraiConsole 就可以绑定UI层与Console层
@ -28,6 +29,13 @@ interface MiraiConsoleUI {
message: String message: String
) )
fun pushLog(
priority: LogPriority,
identityStr: String,
identity: Long,
message: String
)
/** /**
* 让UI层准备接受新增的一个BOT * 让UI层准备接受新增的一个BOT
*/ */