mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-12 22:10:14 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
94f6af56f6
14
README.md
14
README.md
@ -1,15 +1,21 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://mamoe.net" target="_blank">
|
|
||||||
<img width="160" src="http://img.mamoe.net/2020/02/16/a759783b42f72.png" alt="logo">
|
|
||||||
</a>
|
|
||||||
<h1 id="koishi"><a style="color: #39C5BB">Mirai</a></h1>
|
|
||||||
|
|
||||||
|
<img width="160" src="http://img.mamoe.net/2020/02/16/a759783b42f72.png" alt="logo"></br>
|
||||||
|
<img width="95" src="http://img.mamoe.net/2020/02/16/c4aece361224d.png" alt="title">
|
||||||
|
----
|
||||||
[](https://gitter.im/mamoe/mirai?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
[](https://gitter.im/mamoe/mirai?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
[](https://github.com/mamoe/mirai/actions)
|
[](https://github.com/mamoe/mirai/actions)
|
||||||
[](https://bintray.com/him188moe/mirai/mirai-core/)
|
[](https://bintray.com/him188moe/mirai/mirai-core/)
|
||||||
|
|
||||||
|
Mirai 是一个在全平台下运行,提供 QQ Android 和 TIM PC 协议支持的高效率机器人框架
|
||||||
|
|
||||||
|
这个项目的名字来源于
|
||||||
|
<p><a href = "http://www.kyotoanimation.co.jp/">京都动画</a>作品<a href = "https://www.bilibili.com/bangumi/media/md3365/?from=search&seid=14448313700764690387">《境界的彼方》</a>的<a href = "https://zh.moegirl.org/zh-hans/%E6%A0%97%E5%B1%B1%E6%9C%AA%E6%9D%A5">栗山未来(Kuriyama <b>Mirai</b>)</a></p>
|
||||||
|
<p><a href = "https://www.crypton.co.jp/">CRYPTON</a>以<a href = "https://www.crypton.co.jp/miku_eng">初音未来</a>为代表的创作与活动<a href = "https://magicalmirai.com/2019/index_en.html">(Magical <b>Mirai</b>)</a></p>
|
||||||
|
图标以及形象由画师<a href = "">DazeCake</a>绘制
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
## Mirai
|
||||||
**[English](README-eng.md)**
|
**[English](README-eng.md)**
|
||||||
|
|
||||||
多平台 **QQ Android 和 TimPC** 协议支持库与高效率的机器人框架.
|
多平台 **QQ Android 和 TimPC** 协议支持库与高效率的机器人框架.
|
||||||
|
@ -1,17 +1,26 @@
|
|||||||
package net.mamoe.mirai.console.graphical
|
package net.mamoe.mirai.console.graphical
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
|
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
|
||||||
import net.mamoe.mirai.console.graphical.view.PrimaryView
|
import net.mamoe.mirai.console.graphical.view.PrimaryView
|
||||||
import tornadofx.App
|
import tornadofx.App
|
||||||
|
import tornadofx.find
|
||||||
import tornadofx.launch
|
import tornadofx.launch
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
launch<MainApp>(args)
|
launch<MiraiGraphicalUI>(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MainApp: App(PrimaryView::class) {
|
class MiraiGraphicalUI: App(PrimaryView::class) {
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
MiraiConsole.start(find<MiraiGraphicalUIController>())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stop() {
|
||||||
|
super.stop()
|
||||||
|
MiraiConsole.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,36 +0,0 @@
|
|||||||
package net.mamoe.mirai.console.graphical.controller
|
|
||||||
|
|
||||||
import net.mamoe.mirai.Bot
|
|
||||||
import net.mamoe.mirai.console.MiraiConsoleUI
|
|
||||||
import net.mamoe.mirai.utils.LoginSolver
|
|
||||||
import tornadofx.Controller
|
|
||||||
|
|
||||||
class MiraiController : Controller(), MiraiConsoleUI {
|
|
||||||
override fun pushLog(identity: Long, message: String) {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun prePushBot(identity: Long) {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pushBot(bot: Bot) {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pushVersion(consoleVersion: String, consoleBuild: String, coreVersion: String) {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun requestInput(question: String): String {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pushBotAdminStatus(identity: Long, admins: List<Long>) {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createLoginSolver(): LoginSolver {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,85 @@
|
|||||||
|
package net.mamoe.mirai.console.graphical.controller
|
||||||
|
|
||||||
|
import javafx.application.Platform
|
||||||
|
import javafx.stage.Modality
|
||||||
|
import kotlinx.io.core.IoBuffer
|
||||||
|
import net.mamoe.mirai.Bot
|
||||||
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
|
import net.mamoe.mirai.console.MiraiConsoleUI
|
||||||
|
import net.mamoe.mirai.console.graphical.model.BotModel
|
||||||
|
import net.mamoe.mirai.console.graphical.model.ConsoleInfo
|
||||||
|
import net.mamoe.mirai.console.graphical.model.VerificationCodeModel
|
||||||
|
import net.mamoe.mirai.console.graphical.view.VerificationCodeFragment
|
||||||
|
import net.mamoe.mirai.utils.LoginSolver
|
||||||
|
import tornadofx.Controller
|
||||||
|
import tornadofx.Scope
|
||||||
|
import tornadofx.find
|
||||||
|
import tornadofx.observableListOf
|
||||||
|
|
||||||
|
class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
|
||||||
|
|
||||||
|
private val loginSolver = GraphicalLoginSolver()
|
||||||
|
private val cache = mutableMapOf<Long, BotModel>()
|
||||||
|
val mainLog = observableListOf<String>()
|
||||||
|
val botList = observableListOf<BotModel>()
|
||||||
|
val consoleInfo = ConsoleInfo()
|
||||||
|
|
||||||
|
fun login(qq: String, psd: String) {
|
||||||
|
MiraiConsole.CommandListener.commandChannel.offer("/login $qq $psd")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pushLog(identity: Long, message: String) = Platform.runLater {
|
||||||
|
when (identity) {
|
||||||
|
0L -> mainLog.add(message)
|
||||||
|
else -> cache[identity]?.logHistory?.add(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun prePushBot(identity: Long) = Platform.runLater {
|
||||||
|
BotModel(identity).also {
|
||||||
|
cache[identity] = it
|
||||||
|
botList.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pushBot(bot: Bot) = Platform.runLater {
|
||||||
|
cache[bot.uin]?.bot = bot
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pushVersion(consoleVersion: String, consoleBuild: String, coreVersion: String) {
|
||||||
|
Platform.runLater {
|
||||||
|
consoleInfo.consoleVersion = consoleVersion
|
||||||
|
consoleInfo.consoleBuild = consoleBuild
|
||||||
|
consoleInfo.coreVersion = coreVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun requestInput(question: String): String {
|
||||||
|
val model = VerificationCodeModel()
|
||||||
|
find<VerificationCodeFragment>(Scope(model)).openModal(
|
||||||
|
modality = Modality.APPLICATION_MODAL,
|
||||||
|
resizable = false
|
||||||
|
)
|
||||||
|
return model.code.value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pushBotAdminStatus(identity: Long, admins: List<Long>) = Platform.runLater {
|
||||||
|
cache[identity]?.admins?.setAll(admins)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createLoginSolver(): LoginSolver = loginSolver
|
||||||
|
}
|
||||||
|
|
||||||
|
class GraphicalLoginSolver : LoginSolver() {
|
||||||
|
override suspend fun onSolvePicCaptcha(bot: Bot, data: IoBuffer): String? {
|
||||||
|
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String? {
|
||||||
|
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String? {
|
||||||
|
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package net.mamoe.mirai.console.graphical.model
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
|
import net.mamoe.mirai.Bot
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
|
class BotModel(val uin: Long) {
|
||||||
|
val botProperty = SimpleObjectProperty<Bot>(null)
|
||||||
|
var bot: Bot by botProperty
|
||||||
|
|
||||||
|
val logHistory = observableListOf<String>()
|
||||||
|
val admins = observableListOf<Long>()
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package net.mamoe.mirai.console.graphical.model
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleStringProperty
|
||||||
|
import tornadofx.setValue
|
||||||
|
import tornadofx.getValue
|
||||||
|
|
||||||
|
class ConsoleInfo {
|
||||||
|
|
||||||
|
val consoleVersionProperty = SimpleStringProperty()
|
||||||
|
var consoleVersion by consoleVersionProperty
|
||||||
|
|
||||||
|
val consoleBuildProperty = SimpleStringProperty()
|
||||||
|
var consoleBuild by consoleBuildProperty
|
||||||
|
|
||||||
|
val coreVersionProperty = SimpleStringProperty()
|
||||||
|
var coreVersion by coreVersionProperty
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package net.mamoe.mirai.console.graphical.model
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleStringProperty
|
||||||
|
import tornadofx.ItemViewModel
|
||||||
|
import tornadofx.getValue
|
||||||
|
import tornadofx.setValue
|
||||||
|
|
||||||
|
class VerificationCode {
|
||||||
|
val codeProperty = SimpleStringProperty("")
|
||||||
|
var code: String by codeProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
class VerificationCodeModel(code: VerificationCode) : ItemViewModel<VerificationCode>(code) {
|
||||||
|
constructor(): this(VerificationCode())
|
||||||
|
|
||||||
|
val code = bind(VerificationCode::codeProperty)
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package net.mamoe.mirai.console.graphical.view
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleStringProperty
|
||||||
|
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
|
class LoginFragment : Fragment() {
|
||||||
|
|
||||||
|
private val controller = find<MiraiGraphicalUIController>(FX.defaultScope)
|
||||||
|
private val qq = SimpleStringProperty()
|
||||||
|
private val psd = SimpleStringProperty()
|
||||||
|
|
||||||
|
override val root = form {
|
||||||
|
fieldset("登录") {
|
||||||
|
field("QQ") {
|
||||||
|
textfield(qq)
|
||||||
|
}
|
||||||
|
field("密码") {
|
||||||
|
passwordfield(psd)
|
||||||
|
}
|
||||||
|
button("登录").action {
|
||||||
|
controller.login(qq.value, psd.value)
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,56 @@
|
|||||||
package net.mamoe.mirai.console.graphical.view
|
package net.mamoe.mirai.console.graphical.view
|
||||||
|
|
||||||
import tornadofx.View
|
import javafx.scene.control.TabPane
|
||||||
import tornadofx.borderpane
|
import javafx.stage.Modality
|
||||||
|
import net.mamoe.mirai.Bot
|
||||||
|
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
class PrimaryView : View() {
|
class PrimaryView : View() {
|
||||||
|
|
||||||
|
private val controller = find<MiraiGraphicalUIController>()
|
||||||
|
|
||||||
override val root = borderpane {
|
override val root = borderpane {
|
||||||
|
|
||||||
|
top = menubar {
|
||||||
|
menu("机器人") {
|
||||||
|
item("登录").action {
|
||||||
|
find<LoginFragment>().openModal(
|
||||||
|
modality = Modality.APPLICATION_MODAL,
|
||||||
|
resizable = false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
left = listview(controller.botList) {
|
||||||
|
fitToParentHeight()
|
||||||
|
|
||||||
|
cellFormat {
|
||||||
|
|
||||||
|
graphic = vbox {
|
||||||
|
label(it.uin.toString())
|
||||||
|
// label(stringBinding(it.botProperty) { if (value != null) value.nick else "登陆中" })
|
||||||
|
}
|
||||||
|
|
||||||
|
onDoubleClick {
|
||||||
|
(center as TabPane).tab(it.uin.toString()) {
|
||||||
|
listview(it.logHistory)
|
||||||
|
|
||||||
|
isClosable = true
|
||||||
|
select()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
center = tabpane {
|
||||||
|
tab("Main") {
|
||||||
|
listview(controller.mainLog)
|
||||||
|
|
||||||
|
isClosable = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package net.mamoe.mirai.console.graphical.view
|
||||||
|
|
||||||
|
import javafx.scene.Parent
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
|
class VerificationCodeFragment : Fragment() {
|
||||||
|
|
||||||
|
override val root = vbox {
|
||||||
|
//TODO: 显示验证码
|
||||||
|
|
||||||
|
form {
|
||||||
|
fieldset {
|
||||||
|
field("验证码") {
|
||||||
|
textfield()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<p><a href="http://www.kyotoanimation.co.jp/">京都动画</a>作品<a
|
||||||
|
href="https://www.bilibili.com/bangumi/media/md3365/?from=search&seid=14448313700764690387">《境界的彼方》</a>的<a
|
||||||
|
href="https://zh.moegirl.org/zh-hans/%E6%A0%97%E5%B1%B1%E6%9C%AA%E6%9D%A5">栗山未来(Kuriyama <b>Mirai</b>)</a></p>
|
||||||
|
<p><a href="https://www.crypton.co.jp/miku_eng">初音未来</a>的线下创作文化活动<a href="https://magicalmirai.com/2019/index_en.html">(Magical
|
||||||
|
<b>Mirai</b>)</a></p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user