Commit eb866066 authored by Him188's avatar Him188

Merge remote-tracking branch 'origin/master'

parents dcddcc92 bd381b80
......@@ -120,7 +120,7 @@ JVM 上启动需 80M 内存, 每多一个机器人实例需要 30M 内存.
现在体验低付出高效率的 Mirai
```kotlin
val bot = TIMPC.Bot(qqId, password).alsoLogin()
val bot = Bot(qqId, password).alsoLogin()
bot.subscribeMessages {
"你好" reply "你好!"
"profile" reply { sender.queryProfile() }
......
### Mirai Console Graphical
支持windows/mac
有正式UI界面实现的CONSOLE
优点: 适合新手/完全不懂编程的/界面美丽
缺点: 不能在linux服务器运行
所使用插件系统与terminal版本一致 可以来回切换
\ No newline at end of file
plugins {
id("kotlinx-serialization")
id("kotlin")
id("java")
}
apply(plugin = "com.github.johnrengelman.shadow")
val kotlinVersion: String by rootProject.ext
val atomicFuVersion: String by rootProject.ext
val coroutinesVersion: String by rootProject.ext
val kotlinXIoVersion: String by rootProject.ext
val coroutinesIoVersion: String by rootProject.ext
val klockVersion: String by rootProject.ext
val ktorVersion: String by rootProject.ext
val serializationVersion: String by rootProject.ext
fun kotlinx(id: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$id:$version"
fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
dependencies {
api(project(":mirai-core"))
api(project(":mirai-core-qqandroid"))
api(project(":mirai-api-http"))
api(project(":mirai-console"))
runtimeOnly(files("../mirai-core-qqandroid/build/classes/kotlin/jvm/main"))
api(group = "no.tornado", name = "tornadofx", version = "1.7.19")
api("org.bouncycastle:bcprov-jdk15on:1.64")
// classpath is not set correctly by IDE
}
\ No newline at end of file
### Mirai Console Terminal
支持windows/mac/linux
在terminal环境下的Console, 由控制台富文本实现简易UI
优点: 可以在linux环境下运行/简洁使用效率高
缺点: 需要有略微的terminal知识
所使用插件系统与graphical版本一致 可以来回切换
\ No newline at end of file
plugins {
id("kotlinx-serialization")
id("kotlin")
id("java")
}
apply(plugin = "com.github.johnrengelman.shadow")
tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>() {
manifest {
attributes["Main-Class"] = "net.mamoe.mirai.console.MiraiConsoleTerminalLoader"
}
}
val kotlinVersion: String by rootProject.ext
val atomicFuVersion: String by rootProject.ext
val coroutinesVersion: String by rootProject.ext
val kotlinXIoVersion: String by rootProject.ext
val coroutinesIoVersion: String by rootProject.ext
val klockVersion: String by rootProject.ext
val ktorVersion: String by rootProject.ext
val serializationVersion: String by rootProject.ext
fun kotlinx(id: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$id:$version"
fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
dependencies {
api(project(":mirai-core"))
api(project(":mirai-core-qqandroid"))
api(project(":mirai-api-http"))
api(project(":mirai-console"))
runtimeOnly(files("../mirai-core-qqandroid/build/classes/kotlin/jvm/main"))
runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main"))
api(group = "com.googlecode.lanterna", name = "lanterna", version = "3.0.2")
api("org.bouncycastle:bcprov-jdk15on:1.64")
// classpath is not set correctly by IDE
}
\ No newline at end of file
package net.mamoe.mirai.console
import kotlin.concurrent.thread
class MiraiConsoleTerminalLoader {
companion object {
@JvmStatic
fun main(args: Array<String>) {
MiraiConsoleTerminalUI.start()
thread {
MiraiConsole.start(
MiraiConsoleTerminalUI
)
}
Runtime.getRuntime().addShutdownHook(thread(start = false) {
MiraiConsole.stop()
})
}
}
}
\ No newline at end of file
......@@ -8,12 +8,6 @@ plugins {
apply(plugin = "com.github.johnrengelman.shadow")
tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>() {
manifest {
attributes["Main-Class"] = "net.mamoe.mirai.console.MiraiConsoleLoader"
}
}
val kotlinVersion: String by rootProject.ext
val atomicFuVersion: String by rootProject.ext
val coroutinesVersion: String by rootProject.ext
......
......@@ -11,7 +11,6 @@ package net.mamoe.mirai.console
import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.Bot
import net.mamoe.mirai.alsoLogin
import net.mamoe.mirai.api.http.MiraiHttpAPIServer
import net.mamoe.mirai.api.http.generateSessionKey
import net.mamoe.mirai.console.plugins.PluginManager
......@@ -19,7 +18,7 @@ import net.mamoe.mirai.console.plugins.loadAsConfig
import net.mamoe.mirai.console.plugins.withDefaultWrite
import net.mamoe.mirai.console.plugins.withDefaultWriteSave
import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.utils.SimpleLogger
import net.mamoe.mirai.utils.*
import java.io.File
import java.util.*
import java.util.concurrent.LinkedBlockingQueue
......@@ -46,12 +45,19 @@ object MiraiConsole {
var path: String = System.getProperty("user.dir")
val version = "0.01"
var coreVersion = "0.15"
val version = "v0.01"
var coreVersion = "v0.15.1"
val build = "Beta"
fun start() {
logger("Mirai-console [v$version $build | core version v$coreVersion] is still in testing stage, majority feature is available")
lateinit var frontEnd: MiraiConsoleUI
fun start(
frontEnd: MiraiConsoleUI
) {
this.frontEnd = frontEnd
frontEnd.pushVersion(
version, build, coreVersion
)
logger("Mirai-console [$version $build | core version $coreVersion] is still in testing stage, majority feature is available")
logger(
"Mirai-console now running under " + System.getProperty(
"user.dir"
......@@ -115,12 +121,47 @@ object MiraiConsole {
logger("[Bot Login]", 0, "login...")
try {
runBlocking {
Bot(qqNumber, qqPassword).alsoLogin()
frontEnd.prePushBot(qqNumber)
val bot = Bot(qqNumber, qqPassword) {
this.loginSolver = DefaultLoginSolver(object : LoginSolverInputReader {
override suspend fun read(question: String): String? {
return frontEnd.requestInput(question)
}
},
SimpleLogger("Login Helper") { _, message, e ->
logger("[Login Helper]", qqNumber, message)
if (e != null) {
logger("[NETWORK ERROR]", qqNumber, e.toString())//因为在一页 所以可以不打QQ
e.printStackTrace()
}
}
)
this.botLoggerSupplier = {
SimpleLogger("BOT $qqNumber]") { _, message, e ->
logger("[BOT $qqNumber]", qqNumber, message)
if (e != null) {
logger("[NETWORK ERROR]", qqNumber, e.toString())//因为在一页 所以可以不打QQ
e.printStackTrace()
}
}
}
this.networkLoggerSupplier = {
SimpleLogger("BOT $qqNumber") { _, message, e ->
logger("[NETWORK]", qqNumber, message)//因为在一页 所以可以不打QQ
if (e != null) {
logger("[NETWORK ERROR]", qqNumber, e.toString())//因为在一页 所以可以不打QQ
e.printStackTrace()
}
}
}
}
bot.login()
logger(
"[Bot Login]",
0,
"$qqNumber login successes"
)
frontEnd.pushBot(bot)
}
} catch (e: Exception) {
logger(
......@@ -128,7 +169,6 @@ object MiraiConsole {
0,
"$qqNumber login failed -> " + e.message
)
e.printStackTrace()
}
true
}
......@@ -283,7 +323,7 @@ object MiraiConsole {
operator fun invoke(identityStr: String, identity: Long, any: Any? = null) {
if (any != null) {
MiraiConsoleUI.pushLog(identity, "$identityStr: $any")
frontEnd.pushLog(identity, "$identityStr: $any")
}
}
}
......@@ -301,18 +341,5 @@ object MiraiConsole {
}
class MiraiConsoleLoader {
companion object {
@JvmStatic
fun main(args: Array<String>) {
MiraiConsoleUI.start()
MiraiConsole.start()
Runtime.getRuntime().addShutdownHook(thread(start = false) {
MiraiConsole.stop()
})
}
}
}
......@@ -39,53 +39,79 @@ import kotlin.coroutines.EmptyCoroutineContext
actual var defaultLoginSolver: LoginSolver = DefaultLoginSolver()
internal class DefaultLoginSolver : LoginSolver() {
interface LoginSolverInputReader{
suspend fun read(question:String):String?
suspend operator fun invoke(question: String):String?{
return read(question)
}
}
class DefaultLoginSolverInputReader: LoginSolverInputReader{
override suspend fun read(question: String): String? {
return readLine()
}
}
class DefaultLoginSolver(
val reader: LoginSolverInputReader = DefaultLoginSolverInputReader(),
val overrideLogger:MiraiLogger? = null
) : LoginSolver() {
fun getLogger(bot: Bot):MiraiLogger{
if(overrideLogger!=null){
return overrideLogger
}
return bot.logger
}
override suspend fun onSolvePicCaptcha(bot: Bot, data: IoBuffer): String? = loginSolverLock.withLock {
val logger = getLogger(bot)
val tempFile: File = createTempFile(suffix = ".png").apply { deleteOnExit() }
withContext(Dispatchers.IO) {
tempFile.createNewFile()
bot.logger.info("需要图片验证码登录, 验证码为 4 字母")
logger.info("需要图片验证码登录, 验证码为 4 字母")
try {
tempFile.writeChannel().apply { writeFully(data); close() }
bot.logger.info("将会显示字符图片. 若看不清字符图片, 请查看文件 ${tempFile.absolutePath}")
logger.info("将会显示字符图片. 若看不清字符图片, 请查看文件 ${tempFile.absolutePath}")
} catch (e: Exception) {
bot.logger.info("无法写出验证码文件(${e.message}), 请尝试查看以上字符图片")
logger.info("无法写出验证码文件(${e.message}), 请尝试查看以上字符图片")
}
tempFile.inputStream().use {
val img = ImageIO.read(it)
if (img == null) {
bot.logger.info("无法创建字符图片. 请查看文件")
logger.info("无法创建字符图片. 请查看文件")
} else {
bot.logger.info(img.createCharImg())
logger.info(img.createCharImg())
}
}
}
bot.logger.info("请输入 4 位字母验证码. 若要更换验证码, 请直接回车")
return readLine()!!.takeUnless { it.isEmpty() || it.length != 4 }.also {
bot.logger.info("正在提交[$it]中...")
logger.info("请输入 4 位字母验证码. 若要更换验证码, 请直接回车")
return reader("请输入 4 位字母验证码. 若要更换验证码, 请直接回车")!!.takeUnless { it.isEmpty() || it.length != 4 }.also {
logger.info("正在提交[$it]中...")
}
}
override suspend fun onSolveSliderCaptcha(bot: Bot, url: String): String? = loginSolverLock.withLock {
bot.logger.info("需要滑动验证码")
bot.logger.info("请在任意浏览器中打开以下链接并完成验证码. ")
bot.logger.info("完成后请输入任意字符 ")
bot.logger.info(url)
return readLine().also {
bot.logger.info("正在提交中...")
val logger = getLogger(bot)
logger.info("需要滑动验证码")
logger.info("请在任意浏览器中打开以下链接并完成验证码. ")
logger.info("完成后请输入任意字符 ")
logger.info(url)
return reader("完成后请输入任意字符").also {
logger.info("正在提交中...")
}
}
override suspend fun onSolveUnsafeDeviceLoginVerify(bot: Bot, url: String): String? = loginSolverLock.withLock {
bot.logger.info("需要进行账户安全认证")
bot.logger.info("该账户有[设备锁]/[不常用登陆地点]/[不常用设备登陆]的问题")
bot.logger.info("完成以下账号认证即可成功登陆|理论本认证在mirai每个账户中最多出现1次")
bot.logger.info("请将该链接在QQ浏览器中打开并完成认证, 成功后输入任意字符")
bot.logger.info("这步操作将在后续的版本中优化")
bot.logger.info(url)
return readLine().also {
bot.logger.info("正在提交中...")
val logger = getLogger(bot)
logger.info("需要进行账户安全认证")
logger.info("该账户有[设备锁]/[不常用登陆地点]/[不常用设备登陆]的问题")
logger.info("完成以下账号认证即可成功登陆|理论本认证在mirai每个账户中最多出现1次")
logger.info("请将该链接在QQ浏览器中打开并完成认证, 成功后输入任意字符")
logger.info("这步操作将在后续的版本中优化")
logger.info(url)
return reader("完成后请输入任意字符").also {
logger.info("正在提交中...")
}
}
......
......@@ -44,6 +44,8 @@ include(':mirai-core-qqandroid')
include(':mirai-japt')
include(':mirai-console')
include(':mirai-console-graphical')
include(':mirai-console-terminal')
//include(':mirai-api')
include(':mirai-api-http')
include(':mirai-demos:mirai-demo-1')
......
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