Merge remote-tracking branch 'origin/master'

This commit is contained in:
Him188 2020-02-23 01:29:44 +08:00
commit 5de27d47b9
12 changed files with 516 additions and 269 deletions

View File

@ -1,5 +1,6 @@
package net.mamoe.mirai.console
import net.mamoe.mirai.console.pure.MiraiConsoleUIPure
import kotlin.concurrent.thread
class MiraiConsoleTerminalLoader {

View File

@ -19,6 +19,7 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsoleTerminalUI.LoggerDrawer.cleanPage
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.createCharImg
import net.mamoe.mirai.utils.writeChannel
@ -129,9 +130,7 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
requestResult = input
requesting = false
} else {
MiraiConsole.CommandListener.commandChannel.send(
commandBuilder.toString()
)
MiraiConsole.CommandProcessor.runConsoleCommand(commandBuilder.toString())
}
}

View File

@ -24,7 +24,7 @@ fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>() {
manifest {
attributes["Main-Class"] = "net.mamoe.mirai.console.MiraiConsolePureLoader"
attributes["Main-Class"] = "net.mamoe.mirai.console.pure.MiraiConsolePureLoader"
}
}

View File

@ -14,16 +14,17 @@ import kotlinx.coroutines.channels.Channel
import net.mamoe.mirai.Bot
import net.mamoe.mirai.api.http.MiraiHttpAPIServer
import net.mamoe.mirai.api.http.generateSessionKey
import net.mamoe.mirai.console.MiraiConsole.CommandListener.processNextCommandLine
import net.mamoe.mirai.console.MiraiConsole.CommandProcessor.processNextCommandLine
import net.mamoe.mirai.console.command.*
import net.mamoe.mirai.console.plugins.PluginManager
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.console.utils.MiraiConsoleUI
import net.mamoe.mirai.console.utils.checkManager
import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.utils.DeviceInfo
import net.mamoe.mirai.utils.FileBasedDeviceInfo
import net.mamoe.mirai.event.subscribeMessages
import net.mamoe.mirai.utils.SimpleLogger
import net.mamoe.mirai.utils.SystemDeviceInfo
import net.mamoe.mirai.utils.cryptor.ECDH
import java.io.File
import java.security.Security
@ -31,8 +32,18 @@ import java.util.*
object MiraiConsole {
val bots
get() = Bot.instances
/**
* 发布的版本号 统一修改位置
*/
val version = "v0.01"
var coreVersion = "v0.18.0"
val build = "Alpha"
/**
* 获取从Console登陆上的Bot, Bots
* */
val bots get() = Bot.instances
fun getBotByUIN(uin: Long): Bot? {
bots.forEach {
@ -43,50 +54,64 @@ object MiraiConsole {
return null
}
val pluginManager: PluginManager
get() = PluginManager
/**
* PluginManager
*/
val pluginManager: PluginManager get() = PluginManager
/**
* 与前端交互所使用的Logger
*/
var logger = UIPushLogger
/**
* Console运行路径
*/
var path: String = System.getProperty("user.dir")
private val version = "v0.01"
private var coreVersion = "v0.18.0"
private val build = "Zeta"
private var allDown = false
/**
* Console前端接口
*/
lateinit var frontEnd: MiraiConsoleUI
/**
* 启动Console
*/
var start = false
fun start(
frontEnd: MiraiConsoleUI
) {
if (start) {
return
}
start = true
/* 加载ECDH */
try {
ECDH()
} catch (ignored: Exception) {
}
Security.removeProvider("BC")
//Security.removeProvider("BC")
/* 初始化前端 */
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"
)
)
frontEnd.pushVersion(version, build, coreVersion)
logger("Mirai-console [$version $build | core version $coreVersion] is still in testing stage, major features are available")
logger("Mirai-console now running under $path")
logger("Get news in github: https://github.com/mamoe/mirai")
logger("Mirai为开源项目请自觉遵守开源项目协议")
logger("Powered by Mamoe Technologies and contributors")
/* 依次启用功能 */
DefaultCommands()
HTTPAPIAdaptar()
pluginManager.loadPlugins()
CommandListener.start()
CommandProcessor.start()
/* 通知启动完成 */
logger("Mirai-console 启动完成")
logger("\"/login qqnumber qqpassword \" to login a bot")
logger("\"/login qq号 qq密码 \" 来登录一个BOT")
@ -94,7 +119,6 @@ object MiraiConsole {
fun stop() {
PluginManager.disableAllPlugins()
allDown = true
try {
bots.forEach {
it.get()?.close()
@ -104,218 +128,44 @@ object MiraiConsole {
}
}
object HTTPAPIAdaptar {
operator fun invoke() {
if (MiraiProperties.HTTP_API_ENABLE) {
if (MiraiProperties.HTTP_API_AUTH_KEY.startsWith("InitKey")) {
logger("请尽快更改初始生成的HTTP API AUTHKEY")
}
logger("正在启动HTTPAPI; 端口=" + MiraiProperties.HTTP_API_PORT)
MiraiHttpAPIServer.logger = SimpleLogger("HTTP API") { _, message, e ->
logger("[Mirai HTTP API]", 0, message)
}
MiraiHttpAPIServer.start(
MiraiProperties.HTTP_API_PORT,
MiraiProperties.HTTP_API_AUTH_KEY
)
logger("HTTPAPI启动完成; 端口= " + MiraiProperties.HTTP_API_PORT)
}
}
}
/**
* Defaults Commands are recommend to be replaced by plugin provided commands
*/
object DefaultCommands {
operator fun invoke() {
registerCommand {
name = "login"
description = "Mirai-Console default bot login command"
onCommand {
if (it.size < 2) {
logger("\"/login qqnumber qqpassword \" to login a bot")
logger("\"/login qq号 qq密码 \" 来登录一个BOT")
return@onCommand false
}
val qqNumber = it[0].toLong()
val qqPassword = it[1]
logger("[Bot Login]", 0, "login...")
try {
frontEnd.prePushBot(qqNumber)
val bot = Bot(qqNumber, qqPassword) {
this.loginSolver = frontEnd.createLoginSolver()
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(
"[Bot Login]",
0,
"$qqNumber login failed -> " + e.message
)
}
true
}
}
registerCommand {
name = "status"
description = "Mirai-Console default status command"
onCommand {
when (it.size) {
0 -> {
logger("当前有" + bots.size + "个BOT在线")
}
1 -> {
val bot = it[0]
var find = false
bots.forEach {
if (it.get()?.uin.toString().contains(bot)) {
find = true
logger("" + it.get()?.uin + ": 在线中; 好友数量:" + it.get()?.qqs?.size + "; 群组数量:" + it.get()?.groups?.size)
}
}
if (!find) {
logger("没有找到BOT$bot")
}
}
}
true
}
}
registerCommand {
name = "say"
description = "Mirai-Console default say command"
onCommand {
if (it.size < 2) {
logger("say [好友qq号或者群号] [文本消息] //将默认使用第一个BOT")
logger("say [bot号] [好友qq号或者群号] [文本消息]")
return@onCommand false
}
val bot: Bot? = if (it.size == 2) {
if (bots.size == 0) {
logger("还没有BOT登录")
return@onCommand false
}
bots[0].get()
} else {
getBotByUIN(it[0].toLong())
}
if (bot == null) {
logger("没有找到BOT")
return@onCommand false
}
val target = it[it.size - 2].toLong()
val message = it[it.size - 1]
try {
val contact = bot[target]
runBlocking {
contact.sendMessage(message)
logger("消息已推送")
}
} catch (e: NoSuchElementException) {
logger("没有找到群或好友 号码为${target}")
return@onCommand false
}
true
}
}
registerCommand {
name = "plugins"
alias = listOf("plugin")
description = "show all plugins"
onCommand {
PluginManager.getAllPluginDescriptions().let {
println("loaded " + it.size + " plugins")
it.forEach {
logger("\t" + it.name + " v" + it.version + " by" + it.author + " " + it.info)
}
true
}
}
}
registerCommand {
name = "command"
alias = listOf("commands", "help", "helps")
description = "show all commands"
onCommand {
CommandManager.getCommands().let {
println("currently have " + it.size + " commands")
it.toSet().forEach {
logger("\t" + it.name + " :" + it.description)
}
}
true
}
}
registerCommand {
name = "about"
description = "About Mirai-Console"
onCommand {
logger("v$version $build is still in testing stage, majority feature is available")
logger(
"now running under " + System.getProperty(
"user.dir"
)
)
logger("在Github中获取项目最新进展: https://github.com/mamoe/mirai")
logger("Mirai为开源项目请自觉遵守开源项目协议")
logger("Powered by Mamoe Technologies and contributors")
true
}
}
}
}
object CommandListener : Job by {
object CommandProcessor : Job by {
GlobalScope.launch(start = CoroutineStart.LAZY) {
processNextCommandLine()
}
}() {
val commandChannel: Channel<String> = Channel()
suspend fun processNextCommandLine() {
if (allDown) {
return
}
internal class FullCommand(
val sender: CommandSender,
val commandStr: String
)
private val commandChannel: Channel<FullCommand> = Channel()
suspend fun runConsoleCommand(command: String) {
commandChannel.send(
FullCommand(ConsoleCommandSender, command)
)
}
suspend fun runCommand(sender: CommandSender, command: String) {
commandChannel.send(
FullCommand(sender, command)
)
}
fun runConsoleCommandBlocking(command: String) = runBlocking { runConsoleCommand(command) }
fun runCommandBlocking(sender: CommandSender, command: String) = runBlocking { runCommand(sender, command) }
private suspend fun processNextCommandLine() {
for (command in commandChannel) {
var fullCommand = command
if (!fullCommand.startsWith("/")) {
fullCommand = "/$fullCommand"
var commandStr = command.commandStr
if (!commandStr.startsWith("/")) {
commandStr = "/$commandStr"
}
if (!CommandManager.runCommand(ConsoleCommandSender, fullCommand)) {
logger("未知指令 $fullCommand")
if (!CommandManager.runCommand(command.sender, commandStr)) {
logger("未知指令 $commandStr")
}
}
}
@ -337,16 +187,35 @@ object MiraiConsole {
}
}
object MiraiProperties {
var config = File("$path/mirai.properties").loadAsConfig()
}
var HTTP_API_ENABLE: Boolean by config.withDefaultWrite { true }
var HTTP_API_PORT: Int by config.withDefaultWrite { 8080 }
var HTTP_API_AUTH_KEY: String by config.withDefaultWriteSave {
"InitKey" + generateSessionKey()
object MiraiProperties {
var config = File("${MiraiConsole.path}/mirai.properties").loadAsConfig()
var HTTP_API_ENABLE: Boolean by config.withDefaultWrite { true }
var HTTP_API_PORT: Int by config.withDefaultWrite { 8080 }
var HTTP_API_AUTH_KEY: String by config.withDefaultWriteSave {
"InitKey" + generateSessionKey()
}
}
object HTTPAPIAdaptar {
operator fun invoke() {
if (MiraiProperties.HTTP_API_ENABLE) {
if (MiraiProperties.HTTP_API_AUTH_KEY.startsWith("InitKey")) {
MiraiConsole.logger("请尽快更改初始生成的HTTP API AUTHKEY")
}
MiraiConsole.logger("正在启动HTTPAPI; 端口=" + MiraiProperties.HTTP_API_PORT)
MiraiHttpAPIServer.logger = SimpleLogger("HTTP API") { _, message, e ->
MiraiConsole.logger("[Mirai HTTP API]", 0, message)
}
MiraiHttpAPIServer.start(
MiraiProperties.HTTP_API_PORT,
MiraiProperties.HTTP_API_AUTH_KEY
)
MiraiConsole.logger("HTTPAPI启动完成; 端口= " + MiraiProperties.HTTP_API_PORT)
}
}
}

View File

@ -7,17 +7,23 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console
package net.mamoe.mirai.console.command
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugins.PluginManager
import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.message.GroupMessage
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.quote
import net.mamoe.mirai.message.data.toMessage
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import java.lang.StringBuilder
object CommandManager {
private val registeredCommand: MutableMap<String, Command> = mutableMapOf()
@ -50,7 +56,10 @@ object CommandManager {
registeredCommand.remove(commandName)
}
suspend fun runCommand(sender: CommandSender, fullCommand: String): Boolean {
/*
* Index: MiraiConsole
* */
internal suspend fun runCommand(sender: CommandSender, fullCommand: String): Boolean {
val blocks = fullCommand.split(" ")
val commandHead = blocks[0].replace("/", "")
if (!registeredCommand.containsKey(commandHead)) {
@ -58,12 +67,19 @@ object CommandManager {
}
val args = blocks.subList(1, blocks.size)
registeredCommand[commandHead]?.run {
if (onCommand(
sender,
blocks.subList(1, blocks.size)
)
) {
PluginManager.onCommand(this, args)
try {
if (onCommand(
sender,
blocks.subList(1, blocks.size)
)
) {
PluginManager.onCommand(this, args)
}
} catch (e: Exception) {
sender.sendMessage("在运行指令时出现了未知错误")
e.printStackTrace()
} finally {
(sender as CommandSenderImpl).flushMessage()
}
}
return true
@ -72,25 +88,46 @@ object CommandManager {
}
interface CommandSender {
/**
* 立刻发送一条Message
*/
suspend fun sendMessage(messageChain: MessageChain)
suspend fun sendMessage(message: String)
/**
* 写入要发送的内容 所有内容最后会被以一条发出, 不管成功与否
*/
fun appendMessage(message: String)
fun sendMessageBlocking(messageChain: MessageChain) = runBlocking { sendMessage(messageChain) }
fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) }
}
object ConsoleCommandSender : CommandSender {
override suspend fun sendMessage(messageChain: MessageChain) {
MiraiConsole.logger(messageChain.toString())
abstract class CommandSenderImpl : CommandSender {
private val builder = StringBuilder()
override fun appendMessage(message: String) {
builder.append(message).append("\n")
}
override suspend fun sendMessage(message: String) {
MiraiConsole.logger(message)
internal suspend fun flushMessage() {
if (!builder.isEmpty()) {
sendMessage(builder.toString().removeSuffix("\n"))
}
}
}
class ContactCommandSender(val contact: Contact) : CommandSender {
object ConsoleCommandSender : CommandSenderImpl() {
override suspend fun sendMessage(messageChain: MessageChain) {
MiraiConsole.logger("[Command]", 0, messageChain.toString())
}
override suspend fun sendMessage(message: String) {
MiraiConsole.logger("[Command]", 0, message)
}
}
open class ContactCommandSender(val contact: Contact) : CommandSenderImpl() {
override suspend fun sendMessage(messageChain: MessageChain) {
contact.sendMessage(messageChain)
}
@ -100,6 +137,20 @@ class ContactCommandSender(val contact: Contact) : CommandSender {
}
}
/**
* 弃用中
* */
class GroupCommandSender(val toQuote: GroupMessage, contact: Contact) : ContactCommandSender(contact) {
@MiraiExperimentalAPI
override suspend fun sendMessage(message: String) {
toQuote.quoteReply(message)
}
@MiraiExperimentalAPI
override suspend fun sendMessage(messageChain: MessageChain) {
toQuote.quoteReply(messageChain)
}
}
interface Command {
val name: String
@ -163,7 +214,12 @@ class CommandBuilder internal constructor() {
if (alias == null) {
alias = listOf()
}
return AnonymousCommand(name!!, alias!!, description, onCommand!!).also { it.register() }
return AnonymousCommand(
name!!,
alias!!,
description,
onCommand!!
).also { it.register() }
}
}

View File

@ -0,0 +1,272 @@
package net.mamoe.mirai.console.command
import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.plugins.PluginManager
import net.mamoe.mirai.console.utils.addManager
import net.mamoe.mirai.console.utils.checkManager
import net.mamoe.mirai.console.utils.getManagers
import net.mamoe.mirai.console.utils.removeManager
import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.event.subscribeMessages
import net.mamoe.mirai.message.GroupMessage
import net.mamoe.mirai.utils.SimpleLogger
import java.lang.StringBuilder
import java.util.NoSuchElementException
/**
* Some defaults commands are recommend to be replaced by plugin provided commands
*/
object DefaultCommands {
operator fun invoke() {
registerCommand {
name = "manager"
description = "Add a manager"
onCommand { it ->
if (this !is ConsoleCommandSender) {
sendMessage("请在后台使用该指令")
return@onCommand false
}
if (it.size < 2) {
MiraiConsole.logger("[Bot Manager]", 0, "/manager add [bot ID] [Manager ID]")
MiraiConsole.logger("[Bot Manager]", 0, "/manager remove [bot ID] [Manager ID]")
MiraiConsole.logger("[Bot Manager]", 0, "/manager list [bot ID]")
return@onCommand true
}
val botId = try {
it[1].toLong()
} catch (e: Exception) {
MiraiConsole.logger("[Bot Manager]", 0, it[1] + " 不是一个Bot的ID")
return@onCommand false
}
val bot = MiraiConsole.getBotByUIN(botId)
if (bot == null) {
MiraiConsole.logger("[Bot Manager]", 0, "$botId 没有在Console中登陆")
return@onCommand false
}
when (it[0]) {
"add" -> {
if (it.size < 3) {
MiraiConsole.logger("[Bot Manager]", 0, "/manager add [bot ID] [Manager ID]")
return@onCommand true
}
val adminID = try {
it[2].toLong()
} catch (e: Exception) {
MiraiConsole.logger("[Bot Manager]", 0, it[2] + " 不是一个ID")
return@onCommand false
}
bot.addManager(adminID)
MiraiConsole.logger("[Bot Manager]", 0, it[2] + "增加成功")
}
"remove" -> {
if (it.size < 3) {
MiraiConsole.logger("[Bot Manager]", 0, "/manager remove [bot ID] [Manager ID]")
return@onCommand true
}
val adminID = try {
it[2].toLong()
} catch (e: Exception) {
MiraiConsole.logger("[Bot Manager]", 0, it[1] + " 不是一个ID")
return@onCommand false
}
if (!bot.checkManager(adminID)) {
MiraiConsole.logger("[Bot Manager]", 0, it[2] + "本身不是一个Manager")
return@onCommand true
}
bot.removeManager(adminID)
MiraiConsole.logger("[Bot Manager]", 0, it[2] + "移除成功")
}
"list" -> {
bot.getManagers().forEach {
MiraiConsole.logger("[Bot Manager]", 0, " -> $it")
}
}
}
return@onCommand true
}
}
registerCommand {
name = "login"
description = "机器人登陆"
onCommand {
if (this !is ConsoleCommandSender) {
sendMessage("请在后台使用该指令")
return@onCommand false
}
if (it.size < 2) {
MiraiConsole.logger("\"/login qqnumber qqpassword \" to login a bot")
MiraiConsole.logger("\"/login qq号 qq密码 \" 来登录一个BOT")
return@onCommand false
}
val qqNumber = it[0].toLong()
val qqPassword = it[1]
MiraiConsole.logger("[Bot Login]", 0, "login...")
try {
MiraiConsole.frontEnd.prePushBot(qqNumber)
val bot = Bot(qqNumber, qqPassword) {
this.loginSolver = MiraiConsole.frontEnd.createLoginSolver()
this.botLoggerSupplier = {
SimpleLogger("BOT $qqNumber]") { _, message, e ->
MiraiConsole.logger("[BOT $qqNumber]", qqNumber, message)
if (e != null) {
MiraiConsole.logger("[NETWORK ERROR]", qqNumber, e.toString())//因为在一页 所以可以不打QQ
e.printStackTrace()
}
}
}
this.networkLoggerSupplier = {
SimpleLogger("BOT $qqNumber") { _, message, e ->
MiraiConsole.logger("[NETWORK]", qqNumber, message)//因为在一页 所以可以不打QQ
if (e != null) {
MiraiConsole.logger("[NETWORK ERROR]", qqNumber, e.toString())//因为在一页 所以可以不打QQ
e.printStackTrace()
}
}
}
}
bot.login()
bot.subscribeMessages {
contains("test") {
if (this is GroupMessage) {
quoteReply("Hello $senderName")
} else {
reply("Hello!")
}
}
this.startsWith("/") {
if (bot.checkManager(this.sender.id)) {
val sender = ContactCommandSender(this.subject)
MiraiConsole.CommandProcessor.runCommand(
sender, it
)
}
}
}
sendMessage("$qqNumber login successes")
MiraiConsole.frontEnd.pushBot(bot)
} catch (e: Exception) {
sendMessage("$qqNumber login failed -> " + e.message)
}
true
}
}
registerCommand {
name = "status"
description = "获取状态"
onCommand {
when (it.size) {
0 -> {
sendMessage("当前有" + MiraiConsole.bots.size + "个BOT在线")
}
1 -> {
val bot = it[0]
var find = false
MiraiConsole.bots.forEach {
if (it.get()?.uin.toString().contains(bot)) {
find = true
appendMessage("" + it.get()?.uin + ": 在线中; 好友数量:" + it.get()?.qqs?.size + "; 群组数量:" + it.get()?.groups?.size)
}
}
if (!find) {
sendMessage("没有找到BOT$bot")
}
}
}
true
}
}
registerCommand {
name = "say"
description = "聊天功能演示"
onCommand {
if (it.size < 2) {
MiraiConsole.logger("say [好友qq号或者群号] [文本消息] //将默认使用第一个BOT")
MiraiConsole.logger("say [bot号] [好友qq号或者群号] [文本消息]")
return@onCommand false
}
val bot: Bot? = if (it.size == 2) {
if (MiraiConsole.bots.size == 0) {
MiraiConsole.logger("还没有BOT登录")
return@onCommand false
}
MiraiConsole.bots[0].get()
} else {
MiraiConsole.getBotByUIN(it[0].toLong())
}
if (bot == null) {
MiraiConsole.logger("没有找到BOT")
return@onCommand false
}
val target = it[it.size - 2].toLong()
val message = it[it.size - 1]
try {
val contact = bot[target]
runBlocking {
contact.sendMessage(message)
MiraiConsole.logger("消息已推送")
}
} catch (e: NoSuchElementException) {
MiraiConsole.logger("没有找到群或好友 号码为${target}")
return@onCommand false
}
true
}
}
registerCommand {
name = "plugins"
alias = listOf("plugin")
description = "获取插件列表"
onCommand {
PluginManager.getAllPluginDescriptions().let {
it.forEach {
appendMessage("\t" + it.name + " v" + it.version + " by" + it.author + " " + it.info)
}
appendMessage("加载了" + it.size + "个插件")
true
}
}
}
registerCommand {
name = "command"
alias = listOf("commands", "help", "helps")
description = "获取指令列表"
onCommand {
CommandManager.getCommands().let {
var size = 0
it.toSet().forEach {
++size
appendMessage("-> " + it.name + " :" + it.description)
}
appendMessage("""共有${size}条指令""")
}
true
}
}
registerCommand {
name = "about"
description = "About Mirai-Console"
onCommand {
appendMessage("v${MiraiConsole.version} ${MiraiConsole.build} is still in testing stage, major features are available")
appendMessage("now running under ${MiraiConsole.path}")
appendMessage("在Github中获取项目最新进展: https://github.com/mamoe/mirai")
appendMessage("Mirai为开源项目请自觉遵守开源项目协议")
appendMessage("Powered by Mamoe Technologies and contributors")
true
}
}
}
}

View File

@ -21,6 +21,7 @@ import org.yaml.snakeyaml.Yaml
import java.io.File
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.collections.LinkedHashMap
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
@ -211,7 +212,15 @@ fun <T : Any> Config._smartCast(propertyName: String, _class: KClass<T>): T {
interface ConfigSection : Config, MutableMap<String, Any> {
override fun getConfigSection(key: String): ConfigSection {
return (get(key) ?: error("ConfigSection does not contain $key ")) as ConfigSection
val content = get(key) ?: error("ConfigSection does not contain $key ")
if (content is ConfigSection) {
return content
}
return ConfigSectionDelegation(
Collections.synchronizedMap(
(get(key) ?: error("ConfigSection does not contain $key ")) as LinkedHashMap<String, Any>
)
)
}
override fun getString(key: String): String {

View File

@ -9,7 +9,7 @@
package net.mamoe.mirai.console.plugins
import net.mamoe.mirai.console.Command
import net.mamoe.mirai.console.command.Command
import kotlinx.coroutines.*
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.utils.DefaultLogger

View File

@ -1,5 +1,6 @@
package net.mamoe.mirai.console
package net.mamoe.mirai.console.pure
import net.mamoe.mirai.console.MiraiConsole
import kotlin.concurrent.thread
class MiraiConsolePureLoader {

View File

@ -7,11 +7,12 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console
package net.mamoe.mirai.console.pure
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.Bot
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.LoginSolverInputReader
@ -29,9 +30,7 @@ class MiraiConsoleUIPure : MiraiConsoleUI {
requestStr = input
requesting = false
} else {
runBlocking {
MiraiConsole.CommandListener.commandChannel.send(input)
}
MiraiConsole.CommandProcessor.runConsoleCommandBlocking(input)
}
}
}

View File

@ -0,0 +1,41 @@
package net.mamoe.mirai.console.utils
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.MiraiProperties
import net.mamoe.mirai.console.utils.BotManagers.BOT_MANAGERS
import net.mamoe.mirai.console.plugins.ConfigSection
import net.mamoe.mirai.console.plugins.ConfigSectionImpl
import net.mamoe.mirai.console.plugins.loadAsConfig
import net.mamoe.mirai.console.plugins.withDefaultWriteSave
import java.io.File
object BotManagers {
val config = File("${MiraiConsole.path}/bot.yml").loadAsConfig()
val BOT_MANAGERS: ConfigSection by config.withDefaultWriteSave { ConfigSectionImpl() }
}
fun Bot.addManager(long: Long) {
BOT_MANAGERS.putIfAbsent(this.uin.toString(), mutableListOf<Long>())
BOT_MANAGERS[this.uin.toString()] =
(BOT_MANAGERS.getLongList(this.uin.toString()) as MutableList<Long>).apply { add(long) }
BotManagers.config.save()
}
fun Bot.removeManager(long: Long) {
BOT_MANAGERS.putIfAbsent(this.uin.toString(), mutableListOf<Long>())
BOT_MANAGERS[this.uin.toString()] =
(BOT_MANAGERS.getLongList(this.uin.toString()) as MutableList<Long>).apply { add(long) }
BotManagers.config.save()
}
fun Bot.getManagers(): List<Long> {
BOT_MANAGERS.putIfAbsent(this.uin.toString(), mutableListOf<Long>())
return BOT_MANAGERS.getLongList(this.uin.toString())
}
fun Bot.checkManager(long: Long): Boolean {
return this.getManagers().contains(long)
}

View File

@ -7,7 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.console
package net.mamoe.mirai.console.utils
import net.mamoe.mirai.Bot
import net.mamoe.mirai.utils.LoginSolver