mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-22 13:46:13 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
a0c00cc930
@ -3,7 +3,7 @@ kotlin.code.style=official
|
|||||||
# config
|
# config
|
||||||
miraiVersion=0.24.1
|
miraiVersion=0.24.1
|
||||||
miraiConsoleVersion=0.3.2
|
miraiConsoleVersion=0.3.2
|
||||||
miraiConsoleWrapperVersion=0.0.1
|
miraiConsoleWrapperVersion=0.1.1
|
||||||
kotlin.incremental.multiplatform=true
|
kotlin.incremental.multiplatform=true
|
||||||
kotlin.parallel.tasks.in.project=true
|
kotlin.parallel.tasks.in.project=true
|
||||||
# kotlin
|
# kotlin
|
||||||
|
@ -39,7 +39,15 @@ inline fun <R> tryNTimesOrQuit(repeat: Int, errorHint: String, block: (Int) -> R
|
|||||||
|
|
||||||
|
|
||||||
suspend inline fun HttpClient.downloadRequest(url: String): ByteReadChannel {
|
suspend inline fun HttpClient.downloadRequest(url: String): ByteReadChannel {
|
||||||
return this.get<HttpResponse>(url).content
|
return with(this.get<HttpResponse>(url)){
|
||||||
|
if(this.status.value == 404 || this.status.value == 403){
|
||||||
|
error("File not found")
|
||||||
|
}
|
||||||
|
if(this.headers["status"] !=null && this.headers["status"] == "404"){
|
||||||
|
error("File not found")
|
||||||
|
}
|
||||||
|
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}"
|
||||||
@ -77,7 +85,7 @@ suspend fun HttpClient.downloadMaven(
|
|||||||
)
|
)
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
downloadRequest(
|
downloadRequest(
|
||||||
aliyunPath.buildPath(groupName,projectName,version,extension)
|
jcenterPath.buildPath(groupName,projectName,version,extension)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,20 +112,13 @@ suspend fun HttpClient.downloadMavenPomAsString(
|
|||||||
version: String
|
version: String
|
||||||
):String{
|
):String{
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
Http.get<String>(
|
this.get<String>(
|
||||||
aliyunPath.buildPath(groupName,projectName,version,"pom")
|
aliyunPath.buildPath(groupName,projectName,version,"pom")
|
||||||
)
|
)
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
try {
|
this.get(
|
||||||
Http.get(
|
|
||||||
aliyunPath.buildPath(groupName, projectName, version, "pom")
|
aliyunPath.buildPath(groupName, projectName, version, "pom")
|
||||||
)
|
)
|
||||||
}catch (e:Exception){
|
|
||||||
if(e.message?.contains("404 Not Found") == true) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,17 +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 io.ktor.client.HttpClient
|
|
||||||
import io.ktor.client.engine.cio.CIO
|
|
||||||
import io.ktor.client.request.get
|
|
||||||
import io.ktor.client.statement.HttpResponse
|
|
||||||
import io.ktor.utils.io.ByteReadChannel
|
|
||||||
import io.ktor.utils.io.jvm.javaio.copyTo
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.system.exitProcess
|
|
||||||
|
|
||||||
|
|
||||||
val contentPath by lazy {
|
val contentPath by lazy {
|
||||||
@ -33,6 +26,12 @@ val contentPath by lazy {
|
|||||||
object WrapperMain {
|
object WrapperMain {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
GlobalScope.launch{
|
||||||
|
while (true) {
|
||||||
|
delay(1000*60*5)
|
||||||
|
System.gc()
|
||||||
|
}
|
||||||
|
}
|
||||||
println("You are running Mirai-Console-Wrapper under " + System.getProperty("user.dir"))
|
println("You are running Mirai-Console-Wrapper under " + System.getProperty("user.dir"))
|
||||||
|
|
||||||
var type = WrapperProperties.determineConsoleType(WrapperProperties.content)
|
var type = WrapperProperties.determineConsoleType(WrapperProperties.content)
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.console.events;
|
||||||
|
|
||||||
|
import kotlinx.coroutines.GlobalScope;
|
||||||
|
import net.mamoe.mirai.event.Event;
|
||||||
|
import net.mamoe.mirai.event.Listener;
|
||||||
|
import net.mamoe.mirai.event.ListeningStatus;
|
||||||
|
import net.mamoe.mirai.event.internal.EventInternalJvmKt;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件处理
|
||||||
|
*/
|
||||||
|
public final class Events {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听一个事件, 当 {@code onEvent} 返回 {@link ListeningStatus#STOPPED} 时停止监听.
|
||||||
|
* 机器人离线后不会停止监听.
|
||||||
|
*
|
||||||
|
* @param eventClass 事件类
|
||||||
|
* @param onEvent 事件处理. 返回 {@link ListeningStatus#LISTENING} 时继续监听.
|
||||||
|
* @param <E> 事件类型
|
||||||
|
* @return 事件监听器. 可调用 {@link Listener#complete()} 或 {@link Listener#completeExceptionally(Throwable)} 让监听正常停止或异常停止.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static <E extends Event> Listener<E> subscribe(@NotNull Class<E> eventClass, @NotNull Function<E, ListeningStatus> onEvent) {
|
||||||
|
return EventInternalJvmKt._subscribeEventForJaptOnly(eventClass, GlobalScope.INSTANCE, onEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听一个事件, 直到手动停止.
|
||||||
|
* 机器人离线后不会停止监听.
|
||||||
|
*
|
||||||
|
* @param eventClass 事件类
|
||||||
|
* @param onEvent 事件处理. 返回 {@link ListeningStatus#LISTENING} 时继续监听.
|
||||||
|
* @param <E> 事件类型
|
||||||
|
* @return 事件监听器. 可调用 {@link Listener#complete()} 或 {@link Listener#completeExceptionally(Throwable)} 让监听正常停止或异常停止.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static <E extends Event> Listener<E> subscribeAlways(@NotNull Class<E> eventClass, @NotNull Consumer<E> onEvent) {
|
||||||
|
return EventInternalJvmKt._subscribeEventForJaptOnly(eventClass, GlobalScope.INSTANCE, onEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻塞地广播一个事件.
|
||||||
|
*
|
||||||
|
* @param event 事件
|
||||||
|
* @param <E> 事件类型
|
||||||
|
* @return {@code event} 本身
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static <E extends Event> E broadcast(@NotNull E event) {
|
||||||
|
return EventsImplKt.broadcast(event);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.console.events;
|
||||||
|
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import net.mamoe.mirai.event.Event
|
||||||
|
import net.mamoe.mirai.event.broadcast
|
||||||
|
|
||||||
|
internal fun <E : Event> broadcast(e: E): E = runBlocking { e.broadcast() }
|
@ -83,7 +83,11 @@ abstract class PluginBase
|
|||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
internal fun disable(throwable: CancellationException? = null) {
|
internal fun disable(throwable: CancellationException? = null) {
|
||||||
this.coroutineContext[Job]!!.cancelChildren(throwable)
|
this.coroutineContext[Job]!!.cancelChildren(throwable)
|
||||||
|
try {
|
||||||
this.onDisable()
|
this.onDisable()
|
||||||
|
}catch (e:Exception){
|
||||||
|
logger.info(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal var pluginName: String = ""
|
internal var pluginName: String = ""
|
||||||
|
@ -42,7 +42,11 @@ object PluginManager {
|
|||||||
|
|
||||||
fun onCommand(command: Command, sender: CommandSender, args: List<String>) {
|
fun onCommand(command: Command, sender: CommandSender, args: List<String>) {
|
||||||
nameToPluginBaseMap.values.forEach {
|
nameToPluginBaseMap.values.forEach {
|
||||||
|
try {
|
||||||
it.onCommand(command, sender, args)
|
it.onCommand(command, sender, args)
|
||||||
|
}catch (e:Exception){
|
||||||
|
logger.info(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +198,27 @@ object PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nameToPluginBaseMap.values.forEach {
|
nameToPluginBaseMap.values.forEach {
|
||||||
|
try {
|
||||||
|
it.onLoad()
|
||||||
|
}catch (ignored:Exception){
|
||||||
|
if(ignored is CancellationException) {
|
||||||
|
logger.info(ignored)
|
||||||
|
logger.info(it.pluginName + "Failed to load, disabling it")
|
||||||
|
it.disable(ignored)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nameToPluginBaseMap.values.forEach {
|
||||||
|
try {
|
||||||
it.enable()
|
it.enable()
|
||||||
|
}catch (ignored:Exception){
|
||||||
|
logger.info(ignored)
|
||||||
|
logger.info(it.pluginName + "Failed to enable, disabling it")
|
||||||
|
if(ignored is CancellationException) {
|
||||||
|
it.disable(ignored)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("""加载了${nameToPluginBaseMap.size}个插件""")
|
logger.info("""加载了${nameToPluginBaseMap.size}个插件""")
|
||||||
@ -213,7 +237,7 @@ object PluginManager {
|
|||||||
* 根据插件名字找Jar的文件
|
* 根据插件名字找Jar的文件
|
||||||
* null => 没找到
|
* null => 没找到
|
||||||
*/
|
*/
|
||||||
fun getJarPath(pluginName: String): File? {
|
fun getJarFileByName(pluginName: String): File? {
|
||||||
File(pluginsPath).listFiles()?.forEach { file ->
|
File(pluginsPath).listFiles()?.forEach { file ->
|
||||||
if (file != null && file.extension == "jar") {
|
if (file != null && file.extension == "jar") {
|
||||||
val jar = JarFile(file)
|
val jar = JarFile(file)
|
||||||
@ -240,7 +264,7 @@ object PluginManager {
|
|||||||
* null => 没找到
|
* null => 没找到
|
||||||
*/
|
*/
|
||||||
fun getFileInJarByName(pluginName: String, toFind: String): InputStream? {
|
fun getFileInJarByName(pluginName: String, toFind: String): InputStream? {
|
||||||
val jarFile = getJarPath(pluginName) ?: return null
|
val jarFile = getJarFileByName(pluginName) ?: return null
|
||||||
val jar = JarFile(jarFile)
|
val jar = JarFile(jarFile)
|
||||||
val toFindFile =
|
val toFindFile =
|
||||||
jar.entries().asSequence().filter { it.name == toFind }.firstOrNull() ?: return null
|
jar.entries().asSequence().filter { it.name == toFind }.firstOrNull() ?: return null
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
package net.mamoe.mirai.console.scheduler
|
||||||
|
|
||||||
|
import net.mamoe.mirai.console.plugins.PluginBase
|
||||||
|
|
||||||
|
interface SchedulerTask<T:PluginBase>{
|
||||||
|
abstract fun onTick(i:Long)
|
||||||
|
abstract fun onRun()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class RepeatTask<T:PluginBase>(
|
||||||
|
val intervalInMs: Int
|
||||||
|
):SchedulerTask<T>{
|
||||||
|
|
||||||
|
override fun onTick(i: Long) {
|
||||||
|
if(i%intervalInMs == 0L){
|
||||||
|
onRun()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object{
|
||||||
|
fun <T:PluginBase> of(
|
||||||
|
intervalInMs: Int, runnable: () -> Unit
|
||||||
|
):RepeatTask<T>{
|
||||||
|
return AnonymousRepeatTask<T>(
|
||||||
|
intervalInMs, runnable
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AnonymousRepeatTask<T: PluginBase>(
|
||||||
|
intervalInMs: Int, private val runnable: () -> Unit
|
||||||
|
): RepeatTask<T>(intervalInMs){
|
||||||
|
override fun onRun() {
|
||||||
|
runnable.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T:PluginBase> T.repeatTask(
|
||||||
|
intervalInMs: Int, runnable: () -> Unit
|
||||||
|
):RepeatTask<T>{
|
||||||
|
return AnonymousRepeatTask<T>(
|
||||||
|
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() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user