mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-01 12:00:34 +08:00
Merge branch 'master' of https://github.com/mamoe/mirai
This commit is contained in:
commit
1b3b543c64
@ -63,6 +63,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
private lateinit var channel: PlatformSocket
|
private lateinit var channel: PlatformSocket
|
||||||
|
|
||||||
private var _packetReceiverJob: Job? = null
|
private var _packetReceiverJob: Job? = null
|
||||||
|
private var heartbeatJob: Job? = null
|
||||||
|
|
||||||
private val packetReceiveLock: Mutex = Mutex()
|
private val packetReceiveLock: Mutex = Mutex()
|
||||||
|
|
||||||
@ -90,11 +91,13 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun relogin() {
|
override suspend fun relogin() {
|
||||||
|
heartbeatJob?.cancel()
|
||||||
if (::channel.isInitialized) {
|
if (::channel.isInitialized) {
|
||||||
if (channel.isOpen) {
|
if (channel.isOpen) {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
registerClientOnline()
|
registerClientOnline()
|
||||||
}.exceptionOrNull() ?: return
|
}.exceptionOrNull() ?: return
|
||||||
|
logger.info("Cannot do fast relogin. Trying slow relogin")
|
||||||
}
|
}
|
||||||
channel.close()
|
channel.close()
|
||||||
}
|
}
|
||||||
@ -157,7 +160,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun registerClientOnline() {
|
private suspend fun registerClientOnline() {
|
||||||
StatSvc.Register(bot.client).sendAndExpect<StatSvc.Register.Response>(6000) // it's slow
|
StatSvc.Register(bot.client).sendAndExpect<StatSvc.Register.Response>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseExperimental(MiraiExperimentalAPI::class, ExperimentalTime::class)
|
@UseExperimental(MiraiExperimentalAPI::class, ExperimentalTime::class)
|
||||||
@ -250,7 +253,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
|
|
||||||
joinAll(friendListJob, groupJob)
|
joinAll(friendListJob, groupJob)
|
||||||
|
|
||||||
this@QQAndroidBotNetworkHandler.launch(CoroutineName("Heartbeat")) {
|
heartbeatJob = this@QQAndroidBotNetworkHandler.launch(CoroutineName("Heartbeat")) {
|
||||||
while (this.isActive) {
|
while (this.isActive) {
|
||||||
delay(bot.configuration.heartbeatPeriodMillis)
|
delay(bot.configuration.heartbeatPeriodMillis)
|
||||||
val failException = doHeartBeat()
|
val failException = doHeartBeat()
|
||||||
|
@ -32,7 +32,7 @@ actual class PlatformSocket : Closeable {
|
|||||||
actual val isOpen: Boolean
|
actual val isOpen: Boolean
|
||||||
get() = socket.isConnected
|
get() = socket.isConnected
|
||||||
|
|
||||||
override fun close() = socket.close()
|
actual override fun close() = socket.close()
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal lateinit var writeChannel: BufferedOutputStream
|
internal lateinit var writeChannel: BufferedOutputStream
|
||||||
|
@ -38,7 +38,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
|
|||||||
private val botJob = SupervisorJob(configuration.parentCoroutineContext[Job])
|
private val botJob = SupervisorJob(configuration.parentCoroutineContext[Job])
|
||||||
override val coroutineContext: CoroutineContext =
|
override val coroutineContext: CoroutineContext =
|
||||||
configuration.parentCoroutineContext + botJob + (configuration.parentCoroutineContext[CoroutineExceptionHandler]
|
configuration.parentCoroutineContext + botJob + (configuration.parentCoroutineContext[CoroutineExceptionHandler]
|
||||||
?: CoroutineExceptionHandler { _, e -> e.logStacktrace("An exception was thrown under a coroutine of Bot") })
|
?: CoroutineExceptionHandler { _, e -> logger.error("An exception was thrown under a coroutine of Bot", e) })
|
||||||
|
|
||||||
@Suppress("CanBePrimaryConstructorProperty") // for logger
|
@Suppress("CanBePrimaryConstructorProperty") // for logger
|
||||||
final override val account: BotAccount = account
|
final override val account: BotAccount = account
|
||||||
|
@ -16,6 +16,7 @@ import kotlinx.coroutines.GlobalScope
|
|||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
import net.mamoe.mirai.event.internal.Handler
|
import net.mamoe.mirai.event.internal.Handler
|
||||||
import net.mamoe.mirai.event.internal.subscribeInternal
|
import net.mamoe.mirai.event.internal.subscribeInternal
|
||||||
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -96,6 +97,7 @@ interface Listener<in E : Event> : CompletableJob {
|
|||||||
* @see subscribeGroupMessages 监听群消息 DSL
|
* @see subscribeGroupMessages 监听群消息 DSL
|
||||||
* @see subscribeFriendMessages 监听好友消息 DSL
|
* @see subscribeFriendMessages 监听好友消息 DSL
|
||||||
*/
|
*/
|
||||||
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
inline fun <reified E : Event> CoroutineScope.subscribe(crossinline handler: suspend E.(E) -> ListeningStatus): Listener<E> =
|
inline fun <reified E : Event> CoroutineScope.subscribe(crossinline handler: suspend E.(E) -> ListeningStatus): Listener<E> =
|
||||||
E::class.subscribeInternal(Handler { it.handler(it); })
|
E::class.subscribeInternal(Handler { it.handler(it); })
|
||||||
|
|
||||||
@ -107,6 +109,7 @@ inline fun <reified E : Event> CoroutineScope.subscribe(crossinline handler: sus
|
|||||||
*
|
*
|
||||||
* @see subscribe 获取更多说明
|
* @see subscribe 获取更多说明
|
||||||
*/
|
*/
|
||||||
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
inline fun <reified E : Event> CoroutineScope.subscribeAlways(crossinline listener: suspend E.(E) -> Unit): Listener<E> =
|
inline fun <reified E : Event> CoroutineScope.subscribeAlways(crossinline listener: suspend E.(E) -> Unit): Listener<E> =
|
||||||
E::class.subscribeInternal(Handler { it.listener(it); ListeningStatus.LISTENING })
|
E::class.subscribeInternal(Handler { it.listener(it); ListeningStatus.LISTENING })
|
||||||
|
|
||||||
@ -118,6 +121,7 @@ inline fun <reified E : Event> CoroutineScope.subscribeAlways(crossinline listen
|
|||||||
*
|
*
|
||||||
* @see subscribe 获取更多说明
|
* @see subscribe 获取更多说明
|
||||||
*/
|
*/
|
||||||
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
inline fun <reified E : Event> CoroutineScope.subscribeOnce(crossinline listener: suspend E.(E) -> Unit): Listener<E> =
|
inline fun <reified E : Event> CoroutineScope.subscribeOnce(crossinline listener: suspend E.(E) -> Unit): Listener<E> =
|
||||||
E::class.subscribeInternal(Handler { it.listener(it); ListeningStatus.STOPPED })
|
E::class.subscribeInternal(Handler { it.listener(it); ListeningStatus.STOPPED })
|
||||||
|
|
||||||
@ -129,6 +133,7 @@ inline fun <reified E : Event> CoroutineScope.subscribeOnce(crossinline listener
|
|||||||
*
|
*
|
||||||
* @see subscribe 获取更多说明
|
* @see subscribe 获取更多说明
|
||||||
*/
|
*/
|
||||||
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
inline fun <reified E : Event, T> CoroutineScope.subscribeUntil(valueIfStop: T, crossinline listener: suspend E.(E) -> T): Listener<E> =
|
inline fun <reified E : Event, T> CoroutineScope.subscribeUntil(valueIfStop: T, crossinline listener: suspend E.(E) -> T): Listener<E> =
|
||||||
E::class.subscribeInternal(Handler { if (it.listener(it) == valueIfStop) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
|
E::class.subscribeInternal(Handler { if (it.listener(it) == valueIfStop) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
|
||||||
|
|
||||||
@ -141,6 +146,7 @@ inline fun <reified E : Event, T> CoroutineScope.subscribeUntil(valueIfStop: T,
|
|||||||
*
|
*
|
||||||
* @see subscribe 获取更多说明
|
* @see subscribe 获取更多说明
|
||||||
*/
|
*/
|
||||||
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
inline fun <reified E : Event, T> CoroutineScope.subscribeWhile(valueIfContinue: T, crossinline listener: suspend E.(E) -> T): Listener<E> =
|
inline fun <reified E : Event, T> CoroutineScope.subscribeWhile(valueIfContinue: T, crossinline listener: suspend E.(E) -> T): Listener<E> =
|
||||||
E::class.subscribeInternal(Handler { if (it.listener(it) != valueIfContinue) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
|
E::class.subscribeInternal(Handler { if (it.listener(it) != valueIfContinue) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class BotConfiguration {
|
|||||||
/**
|
/**
|
||||||
* 心跳周期. 过长会导致被服务器断开连接.
|
* 心跳周期. 过长会导致被服务器断开连接.
|
||||||
*/
|
*/
|
||||||
var heartbeatPeriodMillis: Long = 30.secondsToMillis
|
var heartbeatPeriodMillis: Long = 60.secondsToMillis
|
||||||
/**
|
/**
|
||||||
* 每次心跳时等待结果的时间.
|
* 每次心跳时等待结果的时间.
|
||||||
* 一旦心跳超时, 整个网络服务将会重启 (将消耗约 5s). 除正在进行的任务 (如图片上传) 会被中断外, 事件和插件均不受影响.
|
* 一旦心跳超时, 整个网络服务将会重启 (将消耗约 5s). 除正在进行的任务 (如图片上传) 会被中断外, 事件和插件均不受影响.
|
||||||
|
@ -11,7 +11,6 @@ package net.mamoe.mirai.utils.io
|
|||||||
|
|
||||||
import kotlinx.io.core.ByteReadPacket
|
import kotlinx.io.core.ByteReadPacket
|
||||||
import kotlinx.io.core.Closeable
|
import kotlinx.io.core.Closeable
|
||||||
import kotlinx.io.errors.IOException
|
|
||||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,4 +36,6 @@ expect class PlatformSocket() : Closeable {
|
|||||||
suspend fun read(): ByteReadPacket
|
suspend fun read(): ByteReadPacket
|
||||||
|
|
||||||
val isOpen: Boolean
|
val isOpen: Boolean
|
||||||
|
|
||||||
|
override fun close()
|
||||||
}
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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.event.internal
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import net.mamoe.mirai.event.Event
|
||||||
|
import net.mamoe.mirai.event.Listener
|
||||||
|
import net.mamoe.mirai.event.ListeningStatus
|
||||||
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||||
|
import java.util.function.Consumer
|
||||||
|
import java.util.function.Function
|
||||||
|
|
||||||
|
@MiraiInternalAPI
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
fun <E : Event> Class<E>._subscribeEventForJaptOnly(scope: CoroutineScope, onEvent: Function<E, ListeningStatus>): Listener<E> {
|
||||||
|
return this.kotlin.subscribeInternal(scope.Handler { onEvent.apply(it) })
|
||||||
|
}
|
||||||
|
|
||||||
|
@MiraiInternalAPI
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
fun <E : Event> Class<E>._subscribeEventForJaptOnly(scope: CoroutineScope, onEvent: Consumer<E>): Listener<E> {
|
||||||
|
return this.kotlin.subscribeInternal(scope.Handler { onEvent.accept(it); ListeningStatus.LISTENING; })
|
||||||
|
}
|
@ -32,7 +32,7 @@ actual class PlatformSocket : Closeable {
|
|||||||
actual val isOpen: Boolean
|
actual val isOpen: Boolean
|
||||||
get() = socket.isConnected
|
get() = socket.isConnected
|
||||||
|
|
||||||
override fun close() {
|
actual override fun close() {
|
||||||
if (::socket.isInitialized) {
|
if (::socket.isInitialized) {
|
||||||
socket.close()
|
socket.close()
|
||||||
}
|
}
|
||||||
|
39
mirai-japt/src/main/java/net/mamoe/mirai/japt/Events.java
Normal file
39
mirai-japt/src/main/java/net/mamoe/mirai/japt/Events.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.japt;
|
||||||
|
|
||||||
|
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 net.mamoe.mirai.japt.internal.EventsImplKt;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public final class Events {
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static <E extends Event> Listener<E> subscribeAlways(@NotNull Class<E> eventClass, @NotNull Consumer<E> onEvent) {
|
||||||
|
return EventInternalJvmKt._subscribeEventForJaptOnly(eventClass, GlobalScope.INSTANCE, onEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static <E extends Event> E broadcast(@NotNull E event) {
|
||||||
|
return EventsImplKt.broadcast(event);
|
||||||
|
}
|
||||||
|
}
|
@ -7,16 +7,10 @@
|
|||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.mamoe.mirai.event
|
package net.mamoe.mirai.japt.internal
|
||||||
|
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import net.mamoe.mirai.event.Event
|
||||||
|
import net.mamoe.mirai.event.broadcast
|
||||||
|
|
||||||
// TODO 添加更多
|
internal fun <E : Event> broadcast(e: E): E = runBlocking { e.broadcast() }
|
||||||
/**
|
|
||||||
* Jvm 调用实现(阻塞)
|
|
||||||
*/
|
|
||||||
object Events {
|
|
||||||
/*
|
|
||||||
@JvmStatic
|
|
||||||
fun <E : Event> subscribe(type: Class<E>, handler: suspend (E) -> ListeningStatus) =
|
|
||||||
runBlocking { type.kotlin.subscribe(handler) }*/
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user