mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-02 12:50:16 +08:00
Review: misc improvements
This commit is contained in:
parent
02173d96df
commit
20e699fb31
@ -11,7 +11,7 @@ const val CONSOLE_TERMINAL = "Terminal"
|
|||||||
const val CONSOLE_GRAPHICAL = "Graphical"
|
const val CONSOLE_GRAPHICAL = "Graphical"
|
||||||
|
|
||||||
|
|
||||||
object ConsoleUpdater {
|
internal object ConsoleUpdater {
|
||||||
|
|
||||||
@Suppress("SpellCheckingInspection")
|
@Suppress("SpellCheckingInspection")
|
||||||
private object Links : HashMap<String, Map<String, String>>() {
|
private object Links : HashMap<String, Map<String, String>>() {
|
||||||
|
@ -20,7 +20,7 @@ import java.net.URLClassLoader
|
|||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
object CoreUpdator {
|
internal object CoreUpdater {
|
||||||
|
|
||||||
fun getProtocolLib(): File? {
|
fun getProtocolLib(): File? {
|
||||||
contentPath.listFiles()?.forEach { file ->
|
contentPath.listFiles()?.forEach { file ->
|
@ -1,9 +1,9 @@
|
|||||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||||
|
|
||||||
package net.mamoe.mirai.console.wrapper
|
package net.mamoe.mirai.console.wrapper
|
||||||
|
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.engine.cio.CIO
|
import io.ktor.client.engine.cio.CIO
|
||||||
import io.ktor.client.features.ClientRequestException
|
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.get
|
||||||
import io.ktor.client.statement.HttpResponse
|
import io.ktor.client.statement.HttpResponse
|
||||||
import io.ktor.utils.io.ByteReadChannel
|
import io.ktor.utils.io.ByteReadChannel
|
||||||
@ -11,14 +11,11 @@ import io.ktor.utils.io.jvm.javaio.copyTo
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
val Http: HttpClient
|
internal val Http: HttpClient = HttpClient(CIO)
|
||||||
get() = HttpClient(CIO)
|
|
||||||
|
|
||||||
|
internal inline fun <R> tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R) {
|
||||||
inline fun <R> tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R){
|
|
||||||
var lastException: Throwable? = null
|
var lastException: Throwable? = null
|
||||||
|
|
||||||
repeat(repeat) {
|
repeat(repeat) {
|
||||||
@ -38,82 +35,84 @@ inline fun <R> tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
suspend inline fun HttpClient.downloadRequest(url: String): ByteReadChannel {
|
internal suspend inline fun HttpClient.downloadRequest(url: String): ByteReadChannel {
|
||||||
return with(this.get<HttpResponse>(url)){
|
return with(this.get<HttpResponse>(url)) {
|
||||||
if(this.status.value == 404 || this.status.value == 403){
|
if (this.status.value == 404 || this.status.value == 403) {
|
||||||
error("File not found")
|
error("File not found")
|
||||||
}
|
}
|
||||||
if(this.headers["status"] !=null && this.headers["status"] == "404"){
|
if (this.headers["status"] != null && this.headers["status"] == "404") {
|
||||||
error("File not found")
|
error("File not found")
|
||||||
}
|
}
|
||||||
this.content
|
this.content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val jcenterPath = "https://jcenter.bintray.com/{group}/{project}/{version}/:{project}-{version}.{extension}"
|
private val jcenterPath = "https://jcenter.bintray.com/{group}/{project}/{version}/:{project}-{version}.{extension}"
|
||||||
private val aliyunPath = "https://maven.aliyun.com/nexus/content/repositories/jcenter/{group}/{project}/{version}/{project}-{version}.{extension}"
|
private val aliyunPath =
|
||||||
|
"https://maven.aliyun.com/nexus/content/repositories/jcenter/{group}/{project}/{version}/{project}-{version}.{extension}"
|
||||||
|
|
||||||
private fun String.buildPath(
|
private fun String.buildPath(
|
||||||
groupName: String,
|
groupName: String,
|
||||||
projectName: String,
|
projectName: String,
|
||||||
version: String,
|
version: String,
|
||||||
extension: String
|
extension: String
|
||||||
):String{
|
): String {
|
||||||
return this
|
return this
|
||||||
.replace(
|
.replace(
|
||||||
"{group}",groupName
|
"{group}", groupName
|
||||||
)
|
)
|
||||||
.replace(
|
.replace(
|
||||||
"{project}",projectName
|
"{project}", projectName
|
||||||
)
|
)
|
||||||
.replace(
|
.replace(
|
||||||
"{extension}",extension
|
"{extension}", extension
|
||||||
)
|
)
|
||||||
.replace(
|
.replace(
|
||||||
"{version}",version
|
"{version}", version
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun HttpClient.downloadMaven(
|
internal suspend fun HttpClient.downloadMaven(
|
||||||
groupName: String,
|
groupName: String,
|
||||||
projectName: String,
|
projectName: String,
|
||||||
version: String,
|
version: String,
|
||||||
extension: String
|
extension: String
|
||||||
):ByteReadChannel{
|
): ByteReadChannel {
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
downloadRequest(
|
downloadRequest(
|
||||||
aliyunPath.buildPath(groupName,projectName,version,extension)
|
aliyunPath.buildPath(groupName, projectName, version, extension)
|
||||||
)
|
)
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
downloadRequest(
|
downloadRequest(
|
||||||
jcenterPath.buildPath(groupName,projectName,version,extension)
|
jcenterPath.buildPath(groupName, projectName, version, extension)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend inline fun HttpClient.downloadMavenArchive(
|
internal suspend inline fun HttpClient.downloadMavenArchive(
|
||||||
groupName: String,
|
groupName: String,
|
||||||
projectName: String,
|
projectName: String,
|
||||||
version: String
|
version: String
|
||||||
):ByteReadChannel{
|
): ByteReadChannel {
|
||||||
return downloadMaven(groupName,projectName,version,"jar")
|
return downloadMaven(groupName, projectName, version, "jar")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend inline fun HttpClient.downloadMavenPom(
|
internal suspend inline fun HttpClient.downloadMavenPom(
|
||||||
groupName: String,
|
groupName: String,
|
||||||
projectName: String,
|
projectName: String,
|
||||||
version: String
|
version: String
|
||||||
):ByteReadChannel{
|
): ByteReadChannel {
|
||||||
return downloadMaven(groupName,projectName,version,"pom")
|
return downloadMaven(groupName, projectName, version, "pom")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun HttpClient.downloadMavenPomAsString(
|
internal suspend fun HttpClient.downloadMavenPomAsString(
|
||||||
groupName: String,
|
groupName: String,
|
||||||
projectName: String,
|
projectName: String,
|
||||||
version: String
|
version: String
|
||||||
):String{
|
): String {
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
this.get<String>(
|
this.get<String>(
|
||||||
aliyunPath.buildPath(groupName,projectName,version,"pom")
|
aliyunPath.buildPath(groupName, projectName, version, "pom")
|
||||||
)
|
)
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
this.get(
|
this.get(
|
||||||
@ -123,12 +122,11 @@ suspend fun HttpClient.downloadMavenPomAsString(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 只要填content path后面的就可以
|
* 只要填 content path 后面的就可以
|
||||||
*/
|
*/
|
||||||
suspend fun ByteReadChannel.saveToContent(filepath:String){
|
internal suspend fun ByteReadChannel.saveToContent(filepath: String) {
|
||||||
val fileStream = File(contentPath.absolutePath + "/" + filepath).also {
|
val fileStream = File(contentPath.absolutePath + "/" + filepath).also {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
it.createNewFile()
|
it.createNewFile()
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,10 @@
|
|||||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||||
package net.mamoe.mirai.console.wrapper
|
package net.mamoe.mirai.console.wrapper
|
||||||
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -56,31 +59,31 @@ object WrapperMain {
|
|||||||
println("Starting version check...")
|
println("Starting version check...")
|
||||||
runBlocking {
|
runBlocking {
|
||||||
launch {
|
launch {
|
||||||
CoreUpdator.versionCheck()
|
CoreUpdater.versionCheck()
|
||||||
}
|
}
|
||||||
launch {
|
launch {
|
||||||
ConsoleUpdater.versionCheck(type)
|
ConsoleUpdater.versionCheck(type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println("Version check complete, starting Mirai")
|
println("Version check complete, starting Mirai")
|
||||||
println("Core :" + CoreUpdator.getCore()!!)
|
println("Core :" + CoreUpdater.getCore()!!)
|
||||||
println("Protocol:" + CoreUpdator.getProtocolLib()!!)
|
println("Protocol:" + CoreUpdater.getProtocolLib()!!)
|
||||||
println("Console :" + ConsoleUpdater.getFile()!! )
|
println("Console :" + ConsoleUpdater.getFile()!!)
|
||||||
println("Root :" + System.getProperty("user.dir") + "/")
|
println("Root :" + System.getProperty("user.dir") + "/")
|
||||||
|
|
||||||
val loader = MiraiClassLoader(
|
val loader = MiraiClassLoader(
|
||||||
CoreUpdator.getCore()!!,
|
CoreUpdater.getCore()!!,
|
||||||
CoreUpdator.getProtocolLib()!!,
|
CoreUpdater.getProtocolLib()!!,
|
||||||
ConsoleUpdater.getFile()!!,
|
ConsoleUpdater.getFile()!!,
|
||||||
this.javaClass.classLoader
|
this.javaClass.classLoader
|
||||||
)
|
)
|
||||||
when(type) {
|
when (type) {
|
||||||
CONSOLE_PURE -> {
|
CONSOLE_PURE -> {
|
||||||
loader.loadClass("net.mamoe.mirai.BotFactoryJvm")
|
loader.loadClass("net.mamoe.mirai.BotFactoryJvm")
|
||||||
loader.loadClass(
|
loader.loadClass(
|
||||||
"net.mamoe.mirai.console.pure.MiraiConsolePureLoader"
|
"net.mamoe.mirai.console.pure.MiraiConsolePureLoader"
|
||||||
).getMethod("load", String::class.java,String::class.java)
|
).getMethod("load", String::class.java, String::class.java)
|
||||||
.invoke(null,CoreUpdator.getCurrentVersion(),ConsoleUpdater.getCurrentVersion())
|
.invoke(null, CoreUpdater.getCurrentVersion(), ConsoleUpdater.getCurrentVersion())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ import net.mamoe.mirai.message.data.Message
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 指令发送者
|
* 指令发送者
|
||||||
|
*
|
||||||
|
* @see AbstractCommandSender 请继承于该抽象类
|
||||||
*/
|
*/
|
||||||
interface CommandSender {
|
interface CommandSender {
|
||||||
/**
|
/**
|
||||||
@ -35,7 +37,7 @@ interface CommandSender {
|
|||||||
fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) }
|
fun sendMessageBlocking(message: String) = runBlocking { sendMessage(message) }
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class CommandSenderImpl : CommandSender {
|
abstract class AbstractCommandSender : CommandSender {
|
||||||
internal val builder = StringBuilder()
|
internal val builder = StringBuilder()
|
||||||
|
|
||||||
override fun appendMessage(message: String) {
|
override fun appendMessage(message: String) {
|
||||||
@ -52,7 +54,7 @@ abstract class CommandSenderImpl : CommandSender {
|
|||||||
/**
|
/**
|
||||||
* 控制台指令执行者. 代表由控制台执行指令
|
* 控制台指令执行者. 代表由控制台执行指令
|
||||||
*/
|
*/
|
||||||
object ConsoleCommandSender : CommandSenderImpl() {
|
object ConsoleCommandSender : AbstractCommandSender() {
|
||||||
override suspend fun sendMessage(messageChain: Message) {
|
override suspend fun sendMessage(messageChain: Message) {
|
||||||
MiraiConsole.logger("[Command]", 0, messageChain.toString())
|
MiraiConsole.logger("[Command]", 0, messageChain.toString())
|
||||||
}
|
}
|
||||||
@ -71,7 +73,7 @@ object ConsoleCommandSender : CommandSenderImpl() {
|
|||||||
* 联系人指令执行者. 代表由一个 QQ 用户执行指令
|
* 联系人指令执行者. 代表由一个 QQ 用户执行指令
|
||||||
*/
|
*/
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
open class ContactCommandSender(val contact: Contact) : CommandSenderImpl() {
|
open class ContactCommandSender(val contact: Contact) : AbstractCommandSender() {
|
||||||
override suspend fun sendMessage(messageChain: Message) {
|
override suspend fun sendMessage(messageChain: Message) {
|
||||||
contact.sendMessage(messageChain)
|
contact.sendMessage(messageChain)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,9 @@ import java.net.URLClassLoader
|
|||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.coroutines.EmptyCoroutineContext
|
import kotlin.coroutines.EmptyCoroutineContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所有插件的基类
|
||||||
|
*/
|
||||||
abstract class PluginBase
|
abstract class PluginBase
|
||||||
@JvmOverloads constructor(coroutineContext: CoroutineContext = EmptyCoroutineContext) : CoroutineScope {
|
@JvmOverloads constructor(coroutineContext: CoroutineContext = EmptyCoroutineContext) : CoroutineScope {
|
||||||
|
|
||||||
@ -34,7 +36,7 @@ abstract class PluginBase
|
|||||||
* 插件被分配的数据目录。数据目录会与插件名称同名。
|
* 插件被分配的数据目录。数据目录会与插件名称同名。
|
||||||
*/
|
*/
|
||||||
val dataFolder: File by lazy {
|
val dataFolder: File by lazy {
|
||||||
File(PluginManager.pluginsPath + "/" + PluginManager.lastPluginName).also {
|
File(PluginManager.pluginsPath + "/" + pluginName).also {
|
||||||
it.mkdir()
|
it.mkdir()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,31 +71,13 @@ abstract class PluginBase
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal fun enable() {
|
|
||||||
this.onEnable()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载一个data folder中的Config
|
* 加载一个 [dataFolder] 中的 [Config]
|
||||||
* 这个config是read-write的
|
|
||||||
*/
|
*/
|
||||||
fun loadConfig(fileName: String): Config {
|
fun loadConfig(fileName: String): Config {
|
||||||
return Config.load(dataFolder.absolutePath + "/" + fileName)
|
return Config.load(dataFolder.absolutePath + "/" + fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmOverloads
|
|
||||||
internal fun disable(throwable: CancellationException? = null) {
|
|
||||||
this.coroutineContext[Job]!!.cancelChildren(throwable)
|
|
||||||
try {
|
|
||||||
this.onDisable()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logger.info(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal var pluginName: String = ""
|
|
||||||
|
|
||||||
val logger: MiraiLogger by lazy {
|
val logger: MiraiLogger by lazy {
|
||||||
SimpleLogger("Plugin $pluginName") { priority, message, e ->
|
SimpleLogger("Plugin $pluginName") { priority, message, e ->
|
||||||
val identityString = "[${pluginName}]"
|
val identityString = "[${pluginName}]"
|
||||||
@ -120,16 +104,34 @@ abstract class PluginBase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载 resource 中的 [Config]
|
* 加载 resource 中的 [Config]
|
||||||
* 这个 [Config] 是 read-only 的
|
* 这个 [Config] 是只读的
|
||||||
*/
|
*/
|
||||||
fun getResourcesConfig(fileName: String): Config {
|
fun getResourcesConfig(fileName: String): Config {
|
||||||
if (!fileName.contains(".")) {
|
require(fileName.contains(".")) { "Unknown Config Type" }
|
||||||
error("Unknown Config Type")
|
|
||||||
}
|
|
||||||
return Config.load(getResources(fileName) ?: error("No such file: $fileName"), fileName.substringAfter('.'))
|
return Config.load(getResources(fileName) ?: error("No such file: $fileName"), fileName.substringAfter('.'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// internal
|
||||||
|
|
||||||
|
internal fun enable() {
|
||||||
|
this.onEnable()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun disable(throwable: CancellationException? = null) {
|
||||||
|
this.coroutineContext[Job]!!.cancelChildren(throwable)
|
||||||
|
try {
|
||||||
|
this.onDisable()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logger.info(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal var pluginName: String = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插件描述
|
||||||
|
*/
|
||||||
class PluginDescription(
|
class PluginDescription(
|
||||||
val name: String,
|
val name: String,
|
||||||
val author: String,
|
val author: String,
|
||||||
|
@ -66,8 +66,7 @@ class MiraiConsoleUIPure : MiraiConsoleUI {
|
|||||||
|
|
||||||
override fun pushLog(priority: LogPriority, identityStr: String, identity: Long, message: String) {
|
override fun pushLog(priority: LogPriority, identityStr: String, identity: Long, message: String) {
|
||||||
var priorityStr = "[${priority.name}]"
|
var priorityStr = "[${priority.name}]"
|
||||||
val _message = message + COLOR_RESET
|
/*
|
||||||
/**
|
|
||||||
* 通过ANSI控制码添加颜色
|
* 通过ANSI控制码添加颜色
|
||||||
* 更多的颜色定义在 [MiraiConsoleUIPure] 的 companion
|
* 更多的颜色定义在 [MiraiConsoleUIPure] 的 companion
|
||||||
*/
|
*/
|
||||||
@ -86,7 +85,7 @@ class MiraiConsoleUIPure : MiraiConsoleUI {
|
|||||||
|
|
||||||
else -> priorityStr
|
else -> priorityStr
|
||||||
}
|
}
|
||||||
println("\u001b[0m " + sdf.format(Date()) + " $priorityStr $identityStr $_message")
|
println("\u001b[0m " + sdf.format(Date()) + " $priorityStr $identityStr ${message + COLOR_RESET}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun prePushBot(identity: Long) {
|
override fun prePushBot(identity: Long) {
|
||||||
|
@ -2,25 +2,25 @@ package net.mamoe.mirai.console.scheduler
|
|||||||
|
|
||||||
import net.mamoe.mirai.console.plugins.PluginBase
|
import net.mamoe.mirai.console.plugins.PluginBase
|
||||||
|
|
||||||
interface SchedulerTask<T:PluginBase>{
|
interface SchedulerTask<T : PluginBase> {
|
||||||
abstract fun onTick(i:Long)
|
abstract fun onTick(i: Long)
|
||||||
abstract fun onRun()
|
abstract fun onRun()
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RepeatTask<T:PluginBase>(
|
abstract class RepeatTask<T : PluginBase>(
|
||||||
val intervalInMs: Int
|
val intervalInMs: Int
|
||||||
):SchedulerTask<T>{
|
) : SchedulerTask<T> {
|
||||||
|
|
||||||
override fun onTick(i: Long) {
|
override fun onTick(i: Long) {
|
||||||
if(i%intervalInMs == 0L){
|
if (i % intervalInMs == 0L) {
|
||||||
onRun()
|
onRun()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object{
|
companion object {
|
||||||
fun <T:PluginBase> of(
|
fun <T : PluginBase> of(
|
||||||
intervalInMs: Int, runnable: () -> Unit
|
intervalInMs: Int, runnable: () -> Unit
|
||||||
):RepeatTask<T>{
|
): RepeatTask<T> {
|
||||||
return AnonymousRepeatTask<T>(
|
return AnonymousRepeatTask<T>(
|
||||||
intervalInMs, runnable
|
intervalInMs, runnable
|
||||||
)
|
)
|
||||||
@ -28,42 +28,18 @@ abstract class RepeatTask<T:PluginBase>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class AnonymousRepeatTask<T: PluginBase>(
|
internal class AnonymousRepeatTask<T : PluginBase>(
|
||||||
intervalInMs: Int, private val runnable: () -> Unit
|
intervalInMs: Int, private val runnable: () -> Unit
|
||||||
): RepeatTask<T>(intervalInMs){
|
) : RepeatTask<T>(intervalInMs) {
|
||||||
override fun onRun() {
|
override fun onRun() {
|
||||||
runnable.invoke()
|
runnable.invoke()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T:PluginBase> T.repeatTask(
|
fun <T : PluginBase> T.repeatTask(
|
||||||
intervalInMs: Int, runnable: () -> Unit
|
intervalInMs: Int, runnable: () -> Unit
|
||||||
):RepeatTask<T>{
|
): RepeatTask<T> {
|
||||||
return AnonymousRepeatTask<T>(
|
return AnonymousRepeatTask<T>(
|
||||||
intervalInMs, runnable
|
intervalInMs, runnable
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun <T> repeatTask(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class X: PluginBase() {
|
|
||||||
override fun onLoad() {
|
|
||||||
//kotlin
|
|
||||||
this.repeatTask(5){
|
|
||||||
|
|
||||||
}
|
|
||||||
//java1
|
|
||||||
RepeatTask.of<X>(5){
|
|
||||||
|
|
||||||
}
|
|
||||||
//java2
|
|
||||||
class Xtask:RepeatTask<X>(5){
|
|
||||||
override fun onRun() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,15 +14,14 @@ import net.mamoe.mirai.utils.LoginSolver
|
|||||||
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
|
import net.mamoe.mirai.utils.SimpleLogger.LogPriority
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 只需要实现一个这个 传入MiraiConsole 就可以绑定UI层与Console层
|
* 只需要实现一个这个传入 MiraiConsole 就可以绑定 UI 层与 Console 层
|
||||||
* 注意线程
|
* 需要保证线程安全
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface MiraiConsoleUI {
|
interface MiraiConsoleUI {
|
||||||
/**
|
/**
|
||||||
* 让UI层展示一条log
|
* 让 UI 层展示一条 log
|
||||||
*
|
*
|
||||||
* identity:log所属的screen, Main=0; Bot=Bot.uin
|
* identity:log 所属的 screen, Main=0; Bot=Bot.uin
|
||||||
*/
|
*/
|
||||||
fun pushLog(
|
fun pushLog(
|
||||||
identity: Long,
|
identity: Long,
|
||||||
@ -37,14 +36,14 @@ interface MiraiConsoleUI {
|
|||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 让UI层准备接受新增的一个BOT
|
* 让 UI 层准备接受新增的一个BOT
|
||||||
*/
|
*/
|
||||||
fun prePushBot(
|
fun prePushBot(
|
||||||
identity: Long
|
identity: Long
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 让UI层接受一个新的bot
|
* 让 UI 层接受一个新的bot
|
||||||
* */
|
* */
|
||||||
fun pushBot(
|
fun pushBot(
|
||||||
bot: Bot
|
bot: Bot
|
||||||
@ -58,14 +57,13 @@ interface MiraiConsoleUI {
|
|||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 让UI层提供一个Input
|
* 让 UI 层提供一个输入, 相当于 [readLine]
|
||||||
* 这个Input 不 等于 Command
|
|
||||||
*/
|
*/
|
||||||
suspend fun requestInput(hint:String): String
|
suspend fun requestInput(hint: String): String
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 让UI层更新BOT管理员的数据
|
* 让 UI 层更新 bot 管理员的数据
|
||||||
*/
|
*/
|
||||||
fun pushBotAdminStatus(
|
fun pushBotAdminStatus(
|
||||||
identity: Long,
|
identity: Long,
|
||||||
@ -73,7 +71,7 @@ interface MiraiConsoleUI {
|
|||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 由UI层创建一个LoginSolver
|
* 由 UI 层创建一个 [LoginSolver]
|
||||||
*/
|
*/
|
||||||
fun createLoginSolver(): LoginSolver
|
fun createLoginSolver(): LoginSolver
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user