Commit cf5deb78 authored by Him188's avatar Him188

Merge remote-tracking branch 'origin/master'

parents 10583776 1735eab9
......@@ -11,20 +11,22 @@ buildscript {
// Do try to waste your time.
classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath("com.github.jengelman.gradle.plugins:shadow:5.2.0")
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion"
classpath "org.jetbrains.kotlinx:atomicfu-gradle-plugin:$atomicFuVersion"
}
}
def keyProps = new Properties()
def keyFile = file("local.properties")
if (keyFile.exists()) keyFile.withInputStream { keyProps.load(it) }
if (!keyProps.getProperty("sdk.dir", "").isEmpty()) {
project.ext.set("isAndroidSDKAvailable", true)
} else {
project.ext.set("isAndroidSDKAvailable", false)
}
try {
def keyProps = new Properties()
def keyFile = file("local.properties")
if (keyFile.exists()) keyFile.withInputStream { keyProps.load(it) }
if (!keyProps.getProperty("sdk.dir", "").isEmpty()) {
project.ext.set("isAndroidSDKAvailable", true)
} else {
project.ext.set("isAndroidSDKAvailable", false)
}
}catch(Exception e){}
allprojects {
group = "net.mamoe"
version = getProperty("mirai_version")
......
#Thu Feb 06 14:10:33 CST 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
......
plugins {
id("com.github.johnrengelman.shadow") version "5.2.0"
id("kotlinx-serialization")
id("kotlin")
id("java")
}
apply(plugin = "com.github.johnrengelman.shadow")
apply(plugin = "java-library")
tasks.withType<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>() {
manifest {
attributes["Main-Class"] = "net.mamoe.mirai.MiraiConsoleLoader"
}
}
val kotlinVersion: String by rootProject.ext
val atomicFuVersion: String by rootProject.ext
val coroutinesVersion: String by rootProject.ext
......
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.UnstableDefault
import net.mamoe.mirai.Bot
import net.mamoe.mirai.alsoLogin
import net.mamoe.mirai.api.http.generateSessionKey
import net.mamoe.mirai.plugin.*
import java.io.File
import kotlin.concurrent.thread
object MiraiConsole {
val bots
get() = Bot.instances
val pluginManager: PluginManager
get() = PluginManager
var logger: MiraiConsoleLogger = DefaultLogger
var path: String = System.getProperty("user.dir")
val version = "0.13"
val build = "Beta"
fun start() {
logger("Mirai-console v${version} $build is still in testing stage, majority feature is available")
logger("Mirai-console v${version} $build 还处于测试阶段, 大部分功能可用")
logger()
logger("Mirai-console now running under " + System.getProperty("user.dir"))
logger("Mirai-console 正在 " + System.getProperty("user.dir") + "下运行")
logger()
logger("Get news in github: https://github.com/mamoe/mirai")
logger("在Github中获取项目最新进展: https://github.com/mamoe/mirai")
logger("Mirai为开源项目,请自觉遵守开源项目协议")
logger("Powered by Mamoe Technology")
logger()
CommandManager.register(DefaultCommands.DefaultLoginCommand())
pluginManager.loadPlugins()
CommandListener.start()
println(MiraiProperties.HTTP_API_ENABLE)
logger("\"/login qqnumber qqpassword \" to login a bot")
logger("\"/login qq号 qq密码 \" 来登陆一个BOT")
}
fun stop() {
PluginManager.disableAllPlugins()
}
/**
* Defaults Commands are recommend to be replaced by plugin provided commands
*/
object DefaultCommands {
class DefaultLoginCommand : Command(
"login"
) {
override fun onCommand(args: List<String>): Boolean {
if (args.size < 2) {
println("\"/login qqnumber qqpassword \" to login a bot")
println("\"/login qq号 qq密码 \" 来登录一个BOT")
return false
}
val qqNumber = args[0].toLong()
val qqPassword = args[1]
println("login...")
try {
runBlocking {
Bot(qqNumber, qqPassword).alsoLogin()
}
} catch (e: Exception) {
println("$qqNumber login failed")
}
return true
}
}
}
object CommandListener {
fun start() {
thread {
processNextCommandLine()
}
}
tailrec fun processNextCommandLine() {
val fullCommand = readLine()
if (fullCommand != null && fullCommand.startsWith("/")) {
if (!CommandManager.runCommand(fullCommand)) {
logger("unknown command $fullCommand")
logger("未知指令 $fullCommand")
}
}
processNextCommandLine();
}
}
interface MiraiConsoleLogger {
operator fun invoke(any: Any? = null)
}
object DefaultLogger : MiraiConsoleLogger {
override fun invoke(any: Any?) {
if (any != null) {
println("[Mirai${version} $build]: " + any.toString())
}
}
}
object MiraiProperties {
var config = File("$path/mirai.json").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".also {
logger("Mirai HTTPAPI auth key 已随机生成 请注意修改")
} + generateSessionKey()
}
}
}
fun main() {
MiraiConsole.start()
Runtime.getRuntime().addShutdownHook(thread(start = false) {
MiraiConsole.stop()
})
}
package net.mamoe.mirai
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
......@@ -7,17 +9,21 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
import net.mamoe.mirai.plugin.PluginManager
import net.mamoe.mirai.plugins.PluginManager
object CommandManager {
private val registeredCommand: MutableMap<String, Command> = mutableMapOf()
private val registeredCommand: MutableMap<String, ICommand> = mutableMapOf()
fun getCommands(): Collection<ICommand> {
return registeredCommand.values
}
fun register(command: Command) {
val allNames = mutableListOf<String>(command.name).also { it.addAll(command.alias) }
fun register(command: ICommand) {
val allNames = mutableListOf(command.name).also { it.addAll(command.alias) }
allNames.forEach {
if (registeredCommand.containsKey(it)) {
error("Command Name(or Alias) $it is already registered, consider if same function plugin was installed")
error("net.mamoe.mirai.Command Name(or Alias) $it is already registered, consider if same function plugin was installed")
}
}
allNames.forEach {
......@@ -25,13 +31,17 @@ object CommandManager {
}
}
fun unregister(command: Command) {
fun unregister(command: ICommand) {
val allNames = mutableListOf<String>(command.name).also { it.addAll(command.alias) }
allNames.forEach {
registeredCommand.remove(it)
}
}
fun unregister(commandName: String) {
registeredCommand.remove(commandName)
}
fun runCommand(fullCommand: String): Boolean {
val blocks = fullCommand.split(" ")
val commandHead = blocks[0].replace("/", "")
......@@ -52,17 +62,69 @@ object CommandManager {
}
interface ICommand {
val name: String
val alias: List<String>
val description: String
fun onCommand(args: List<String>): Boolean
fun register()
}
abstract class Command(
val name: String,
val alias: List<String> = listOf(),
val description: String = ""
) {
override val name: String,
override val alias: List<String> = listOf(),
override val description: String = ""
) : ICommand {
/**
* 最高优先级监听器
* 如果return [false] 这次指令不会被[PluginBase]的全局onCommand监听器监听
* */
open fun onCommand(args: List<String>): Boolean {
open override fun onCommand(args: List<String>): Boolean {
return true
}
override fun register() {
CommandManager.register(this)
}
}
class AnonymousCommand internal constructor(
override val name: String,
override val alias: List<String>,
override val description: String,
val onCommand: ICommand.(args: List<String>) -> Boolean
) : ICommand {
override fun onCommand(args: List<String>): Boolean {
return onCommand.invoke(this, args)
}
override fun register() {
CommandManager.register(this)
}
}
class CommandBuilder internal constructor() {
var name: String? = null
var alias: List<String>? = null
var description: String = ""
var onCommand: (ICommand.(args: List<String>) -> Boolean)? = null
fun onCommand(commandProcess: ICommand.(args: List<String>) -> Boolean) {
onCommand = commandProcess
}
fun register(): ICommand {
if (name == null || onCommand == null) {
error("net.mamoe.mirai.CommandBuilder not complete")
}
if (alias == null) {
alias = listOf()
}
return AnonymousCommand(name!!, alias!!, description, onCommand!!).also { it.register() }
}
}
fun buildCommand(builder: CommandBuilder.() -> Unit): ICommand {
return CommandBuilder().apply(builder).register()
}
This diff is collapsed.
......@@ -7,7 +7,7 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.plugin
package net.mamoe.mirai.plugins
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
......@@ -16,7 +16,6 @@ import com.alibaba.fastjson.parser.Feature
import kotlinx.serialization.*
import java.io.File
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentSkipListMap
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
......@@ -61,6 +60,14 @@ interface Config {
}
return when (file.extension.toLowerCase()) {
"json" -> JsonConfig(file)
"yml" -> YamlConfig(file)
"yaml" -> YamlConfig(file)
"mirai" -> YamlConfig(file)
"ini" -> IniConfig(file)
"toml" -> IniConfig(file)
"properties" -> IniConfig(file)
"property" -> IniConfig(file)
"data" -> IniConfig(file)
else -> error("Unsupported file config type ${file.extension.toLowerCase()}")
}
}
......@@ -328,4 +335,26 @@ class JsonConfig internal constructor(file: File) : FileConfigImpl(file) {
override fun serialize(config: ConfigSection): String {
return JSONObject.toJSONString(config)
}
}
\ No newline at end of file
}
class YamlConfig internal constructor(file: File) : FileConfigImpl(file) {
override fun deserialize(content: String): ConfigSection {
TODO("崔崔还没有写") //To change body of created functions use File | Settings | File Templates.
}
override fun serialize(config: ConfigSection): String {
TODO("崔崔还没有写") //To change body of created functions use File | Settings | File Templates.
}
}
class IniConfig internal constructor(file: File) : FileConfigImpl(file) {
override fun deserialize(content: String): ConfigSection {
TODO("崔崔还没有写") //To change body of created functions use File | Settings | File Templates.
}
override fun serialize(config: ConfigSection): String {
TODO("崔崔还没有写") //To change body of created functions use File | Settings | File Templates.
}
}
......@@ -7,12 +7,10 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.plugin
package net.mamoe.mirai.plugins
import Command
import net.mamoe.mirai.ICommand
import kotlinx.coroutines.*
import kotlinx.serialization.UnstableDefault
import kotlinx.serialization.json.Json
import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.io.encodeToString
......@@ -58,7 +56,7 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope {
/**
* 当任意指令被使用
*/
open fun onCommand(command: Command, args: List<String>) {
open fun onCommand(command: ICommand, args: List<String>) {
}
......@@ -162,13 +160,18 @@ object PluginManager {
//已完成加载的
private val nameToPluginBaseMap: MutableMap<String, PluginBase> = mutableMapOf()
private val pluginDescriptions: MutableMap<String, PluginDescription> = mutableMapOf()
fun onCommand(command: Command, args: List<String>) {
this.nameToPluginBaseMap.values.forEach {
fun onCommand(command: ICommand, args: List<String>) {
nameToPluginBaseMap.values.forEach {
it.onCommand(command, args)
}
}
fun getAllPluginDescriptions(): Collection<PluginDescription> {
return pluginDescriptions.values
}
/**
* 尝试加载全部插件
*/
......@@ -176,6 +179,8 @@ object PluginManager {
val pluginsFound: MutableMap<String, PluginDescription> = mutableMapOf()
val pluginsLocation: MutableMap<String, File> = mutableMapOf()
logger.info("""开始加载${pluginsPath}下的插件""")
File(pluginsPath).listFiles()?.forEach { file ->
if (file != null && file.extension == "jar") {
val jar = JarFile(file)
......@@ -254,11 +259,17 @@ object PluginManager {
try {
val pluginClass = try {
PluginClassLoader((pluginsLocation[description.name]!!), this.javaClass.classLoader)
PluginClassLoader(
(pluginsLocation[description.name]!!),
this.javaClass.classLoader
)
.loadClass(description.basePath)
} catch (e: ClassNotFoundException) {
logger.info("failed to find Main: " + description.basePath + " checking if it's kotlin's path")
PluginClassLoader((pluginsLocation[description.name]!!), this.javaClass.classLoader)
PluginClassLoader(
(pluginsLocation[description.name]!!),
this.javaClass.classLoader
)
.loadClass("${description.basePath}Kt")
}
return try {
......@@ -269,6 +280,7 @@ object PluginManager {
logger.info(description.info)
nameToPluginBaseMap[description.name] = plugin
pluginDescriptions[description.name] = description
plugin.init(description)
true
} catch (e: ClassCastException) {
......@@ -289,6 +301,9 @@ object PluginManager {
nameToPluginBaseMap.values.forEach {
it.enable()
}
logger.info("""加载了${nameToPluginBaseMap.size}个插件""")
}
......
plugins {
kotlin("jvm")
java
id("com.github.johnrengelman.shadow") version "5.2.0"
id("com.github.johnrengelman.shadow")
}
version = "1.0.0"
......
......@@ -14,7 +14,7 @@ import kotlinx.coroutines.GlobalScope
import net.mamoe.mirai.event.events.BotOnlineEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeMessages
import net.mamoe.mirai.plugin.PluginBase
import net.mamoe.mirai.plugins.PluginBase
import net.mamoe.mirai.utils.MiraiExperimentalAPI
class ImageSenderMain : PluginBase() {
......
......@@ -59,7 +59,7 @@ if (versionPos==-1){
def javaVersionNum = javaVersion.substring(0, versionPos).toInteger()
if (javaVersionNum >= 11) {
println("jdk版本为 "+ javaVersionNum)
include(':mirai-debug')
//include(':mirai-debug')
} else {
println("当前使用的 JDK 版本为 ${System.getProperty("java.version")}, 最低需要 JDK 11 才能引入模块 `:mirai-debug`")
}
......
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