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 = "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> {

View File

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

View File

@ -5,18 +5,17 @@ import javafx.collections.ObservableList
import javafx.stage.Modality
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.graphical.model.BotModel
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.model.*
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 net.mamoe.mirai.utils.SimpleLogger.LogPriority
import tornadofx.*
class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
private val settingModel = find<GlobalSettingModel>()
private val loginSolver = GraphicalLoginSolver()
private val cache = mutableMapOf<Long, BotModel>()
val mainLog = observableListOf<String>()
@ -34,10 +33,29 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
fun sendCommand(command: String) = MiraiConsole.CommandProcessor.runConsoleCommandBlocking(command)
override fun pushLog(identity: Long, message: String) = Platform.runLater {
when (identity) {
0L -> mainLog.add(message)
else -> cache[identity]?.logHistory?.add(message)
fun ObservableList<*>.trim() {
println(size)
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 {

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 javafx.beans.property.SimpleBooleanProperty
import javafx.beans.property.SimpleStringProperty
import net.mamoe.mirai.console.plugins.PluginDescription
import tornadofx.getValue
import tornadofx.setValue
@ -14,6 +15,11 @@ class PluginModel(
) : RecursiveTreeObject<PluginModel>() {
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")
var enabled by enabledProperty
}

View File

@ -12,21 +12,48 @@ class PluginsView : View() {
val plugins = controller.pluginList
override val root = jfxTreeTableView(plugins) {
isShowRoot = false
columns.addAll(
JFXTreeTableColumn<PluginModel, String>("插件名").apply {
prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.1))
setCellValueFactory {
return@setCellValueFactory it.value.value.nameProperty
}
},
JFXTreeTableColumn<PluginModel, String>("版本").apply {
prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.1))
setCellValueFactory {
return@setCellValueFactory it.value.value.versionProperty
}
},
JFXTreeTableColumn<PluginModel, String>("作者").apply {
prefWidthProperty().bind(this@jfxTreeTableView.widthProperty().multiply(0.1))
setCellValueFactory {
return@setCellValueFactory it.value.value.authorProperty
}
},
JFXTreeTableColumn<PluginModel, String>("介绍").apply {
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))
// 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
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.jfxTextfield
import tornadofx.View
import tornadofx.field
import tornadofx.fieldset
import tornadofx.form
import tornadofx.*
import java.awt.Desktop
import java.io.File
class SettingsView : View() {
private val controller = find<MiraiGraphicalUIController>()
private val settingModel = find<GlobalSettingModel>()
override val root = form {
fieldset {
field {
jfxButton("撤掉") { }
jfxButton("保存") { }
jfxButton("撤掉").action {
settingModel.rollback()
}
jfxButton("保存").action {
settingModel.commit()
}
}
}
fieldset("插件目录") {
field {
jfxTextfield("...") { isEditable = false }
jfxButton("打开目录")
jfxTextfield((System.getProperty("user.dir") + "/plugins/").replace("//", "/")) { isEditable = false }
jfxButton("打开目录").action {
(System.getProperty("user.dir") + "/plugins/").replace("//", "/").also { path ->
Desktop.getDesktop().takeIf { it.isSupported(Desktop.Action.OPEN) }?.open(File(path))
}
}
}
}
fieldset("最大日志容量") {
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.utils.MiraiConsoleUI
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
@ -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) {
log[identity] = LimitLinkedQueue(cacheLogSize)
}

View File

@ -11,24 +11,26 @@ const val CONSOLE_TERMINAL = "Terminal"
const val CONSOLE_GRAPHICAL = "Graphical"
object ConsoleUpdator{
object ConsoleUpdater {
@Suppress("SpellCheckingInspection")
private object Links:HashMap<String,Map<String,String>>() {
init {
put(CONSOLE_PURE, mapOf(
"version" to "/net/mamoe/mirai-console/"
))
}
private object Links : HashMap<String, Map<String, String>>() {
init {
put(
CONSOLE_PURE, mapOf(
"version" to "/net/mamoe/mirai-console/"
)
)
}
}
var consoleType = CONSOLE_PURE
fun getFile():File?{
fun getFile(): File? {
contentPath.listFiles()?.forEach { file ->
if (file != null && file.extension == "jar") {
if(file.name.contains("mirai-console")) {
if (file.name.contains("mirai-console")) {
when (consoleType) {
CONSOLE_PURE -> {
return file
@ -40,7 +42,7 @@ object ConsoleUpdator{
return null
}
suspend fun versionCheck(type:String) {
suspend fun versionCheck(type: String) {
this.consoleType = type
println("Fetching Newest Console Version of $type")
val newest = getNewestVersion()
@ -55,23 +57,23 @@ object ConsoleUpdator{
}
private suspend fun getNewestVersion():String{
private suspend fun getNewestVersion(): String {
try {
return """>([0-9])*\.([0-9])*\.([0-9])*/""".toRegex().findAll(
Http.get<String> {
url {
protocol = URLProtocol.HTTPS
host = "jcenter.bintray.com"
path(Links[consoleType]!!["version"] ?: error("Unknown Console Type"))
Http.get<String> {
url {
protocol = URLProtocol.HTTPS
host = "jcenter.bintray.com"
path(Links[consoleType]!!["version"] ?: error("Unknown Console Type"))
}
}
}
).asSequence()
).asSequence()
.map { it.value.drop(1).dropLast(1) }
.maxBy {
it.split('.').foldRightIndexed(0) { index: Int, s: String, acc: Int ->
acc + 100.0.pow(2 - index).toInt() * (s.toIntOrNull() ?: 0)
}
}!!
it.split('.').foldRightIndexed(0) { index: Int, s: String, acc: Int ->
acc + 100.0.pow(2 - index).toInt() * (s.toIntOrNull() ?: 0)
}
}!!
} catch (e: Exception) {
println("Failed to fetch newest Console version, please seek for help")
e.printStackTrace()
@ -80,9 +82,9 @@ object ConsoleUpdator{
}
}
fun getCurrentVersion():String{
fun getCurrentVersion(): String {
val file = getFile()
if(file != null) {
if (file != null) {
val numberVersion = """([0-9])*\.([0-9])*\.([0-9])*""".toRegex().find(file.name)?.value
if (numberVersion != null) {
return numberVersion + file.name.substringAfter(numberVersion).substringBefore(".jar")
@ -91,7 +93,7 @@ object ConsoleUpdator{
return "0.0.0"
}
private fun getProjectName():String{
private fun getProjectName(): String {
return if (consoleType == CONSOLE_PURE) {
"mirai-console"
} else {
@ -99,12 +101,12 @@ object ConsoleUpdator{
}
}
private suspend fun downloadConsole(version:String){
tryNTimesOrQuit(3,"Failed to download Console, please seek for help") {
Http.downloadMavenArchive("net/mamoe",getProjectName(),version)
private suspend fun downloadConsole(version: String) {
tryNTimesOrQuit(3, "Failed to download Console, please seek for help") {
Http.downloadMavenArchive("net/mamoe", getProjectName(), version)
.saveToContent("${getProjectName()}-$version.jar")
}
LibManager.clearLibs()
LibManager.addDependencyRequest("net/mamoe",getProjectName(),version)
LibManager.addDependencyRequest("net/mamoe", getProjectName(), version)
}
}

View File

@ -59,19 +59,19 @@ object WrapperMain {
CoreUpdator.versionCheck()
}
launch {
ConsoleUpdator.versionCheck(type)
ConsoleUpdater.versionCheck(type)
}
}
println("Version check complete, starting Mirai")
println("Core :" + CoreUpdator.getCore()!!)
println("Protocol:" + CoreUpdator.getProtocolLib()!!)
println("Console :" + ConsoleUpdator.getFile()!! )
println("Console :" + ConsoleUpdater.getFile()!! )
println("Root :" + System.getProperty("user.dir") + "/")
val loader = MiraiClassLoader(
CoreUpdator.getCore()!!,
CoreUpdator.getProtocolLib()!!,
ConsoleUpdator.getFile()!!,
ConsoleUpdater.getFile()!!,
this.javaClass.classLoader
)
when(type) {
@ -80,7 +80,7 @@ object WrapperMain {
loader.loadClass(
"net.mamoe.mirai.console.pure.MiraiConsolePureLoader"
).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.plugins.PluginManager
import net.mamoe.mirai.console.utils.MiraiConsoleUI
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
import net.mamoe.mirai.utils.cryptor.ECDH
@ -27,7 +28,7 @@ object MiraiConsole {
* 发布的版本名
*/
const val build = "Pkmon"
lateinit var version:String
lateinit var version: String
/**
* 获取从Console登陆上的Bot, Bots
@ -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) {
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) {
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.sendMessage
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
interface CommandSender {
/**
* 立刻发送一条Message
*/
suspend fun sendMessage(messageChain: MessageChain)
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.command.Command
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.SimpleLogger
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
import java.io.File
import java.io.InputStream
import java.net.URLClassLoader
@ -85,7 +87,7 @@ abstract class PluginBase
this.coroutineContext[Job]!!.cancelChildren(throwable)
try {
this.onDisable()
}catch (e:Exception){
} catch (e: Exception) {
logger.info(e)
}
}
@ -93,10 +95,11 @@ abstract class PluginBase
internal var pluginName: String = ""
val logger: MiraiLogger by lazy {
SimpleLogger("Plugin $pluginName") { _, message, e ->
MiraiConsole.logger("[${pluginName}]", 0, message)
SimpleLogger("Plugin $pluginName") { priority, message, e ->
val identityString = "[${pluginName}]"
MiraiConsole.logger(priority, identityString, 0, message)
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.utils.DefaultLoginSolver
import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
import java.text.SimpleDateFormat
import java.util.*
import kotlin.concurrent.thread
@ -24,6 +25,22 @@ class MiraiConsoleUIPure : MiraiConsoleUI {
private var requesting = false
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 {
thread {
while (true) {
@ -38,11 +55,39 @@ class MiraiConsoleUIPure : MiraiConsoleUI {
}
}
val sdf by lazy{
val sdf by lazy {
SimpleDateFormat("HH:mm:ss")
}
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) {

View File

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