1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-04-25 04:50:26 +08:00

Make interface Event the base type of a event, remove interface Subscribable

This commit is contained in:
Him188 2020-02-11 11:56:42 +08:00
parent 474c5686e6
commit 7891ffc136
15 changed files with 135 additions and 128 deletions
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid
mirai-core/src
commonMain/kotlin/net.mamoe.mirai
jvmMain/kotlin/net/mamoe/mirai/event
jvmTest/kotlin/net/mamoe/mirai/event
mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman

View File

@ -295,7 +295,7 @@ internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain {
}
@UseExperimental(MiraiInternalAPI::class)
@UseExperimental(MiraiInternalAPI::class, ExperimentalUnsignedTypes::class)
internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChain) {
this.forEach {
when {

View File

@ -21,10 +21,13 @@ import kotlinx.io.core.use
import net.mamoe.mirai.contact.ContactList
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.events.ForceOfflineEvent
import net.mamoe.mirai.data.MultiPacket
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.event.*
import net.mamoe.mirai.event.BroadcastControllable
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.ForceOfflineEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.qqandroid.GroupImpl
import net.mamoe.mirai.qqandroid.MemberImpl
@ -350,7 +353,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
// broadcast
if (packet is Subscribable) {
if (packet is Event) {
if (packet is BroadcastControllable) {
if (packet.shouldBroadcast) packet.broadcast()
} else {

View File

@ -12,7 +12,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet
import kotlinx.io.core.*
import kotlinx.io.pool.useInstance
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
@ -20,7 +20,6 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.OnlinePush
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.*
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.ConfigPushSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.Heartbeat
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
@ -59,7 +58,7 @@ internal abstract class OutgoingPacketFactory<TPacket : Packet>(
final override val receivingCommandName: String get() = commandName
/**
* **解码**服务器的回复数据包. 返回的包若是 [Subscribable], 则会 broadcast.
* **解码**服务器的回复数据包. 返回的包若是 [Event], 则会 broadcast.
*/
abstract suspend fun ByteReadPacket.decode(bot: QQAndroidBot): TPacket
@ -85,7 +84,7 @@ internal abstract class IncomingPacketFactory<TPacket : Packet>(
val responseCommandName: String = ""
) : PacketFactory<TPacket>() {
/**
* **解码**服务器的回复数据包. 返回的包若是 [Subscribable], 则会 broadcast.
* **解码**服务器的回复数据包. 返回的包若是 [Event], 则会 broadcast.
*/
abstract suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): TPacket

View File

@ -9,11 +9,11 @@
package net.mamoe.mirai.data
import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.event.Event
/**
* 事件包. 可被监听.
*
* @see Subscribable
* @see Event
*/
interface EventPacket : Subscribable, Packet
interface EventPacket : Event, Packet

View File

@ -11,6 +11,7 @@ package net.mamoe.mirai.data
/**
* 从服务器收到的包解析之后的结构化数据.
* 它是一个数据包工厂的处理的返回值.
*/
interface Packet {
/**

View File

@ -17,61 +17,44 @@ import net.mamoe.mirai.event.internal.broadcastInternal
import net.mamoe.mirai.utils.MiraiInternalAPI
/**
* 可被监听的.
* 可被监听的, 可以是任何 class object.
*
* 可以是任何 class object.
* 若监听这个类, 监听器将会接收所有事件的广播.
*
* @see subscribeAlways
* @see subscribeWhile
*
* @see subscribeMessages
*/
interface Subscribable
/**
* 所有事件的基类.
* 若监听这个类, 监听器将会接收所有事件的广播.
*
* @see [broadcast] 广播事件
* @see [subscribe] 监听事件
*/
abstract class Event : Subscribable {
interface Event
/**
* 可被取消的事件
*/
abstract class CancellableEvent : Event {
/**
* 事件是否已取消. 事件需实现 [Cancellable] 才可以被取消, 否则这个字段为常量值 false
* 事件是否已取消.
*/
val cancelled: Boolean get() = _cancelled
private var _cancelled: Boolean = false
get() = field.takeIf { this is Cancellable } ?: false
private set(value) =
if (this is Cancellable) field = value
else throw UnsupportedOperationException()
/**
* 取消事件. 事件需实现 [Cancellable] 才可以被取消
*
* @throws UnsupportedOperationException 如果事件没有实现 [Cancellable]
* 取消事件.
*/
fun cancel() {
_cancelled = true
}
}
/**
* 实现这个接口的事件([Event])可以被取消. 在广播中取消不会影响广播过程.
*/
interface Cancellable : Subscribable {
val cancelled: Boolean
fun cancel()
}
/**
* 广播一个事件的唯一途径.
*/
@UseExperimental(MiraiInternalAPI::class)
suspend fun <E : Subscribable> E.broadcast(): E = apply {
suspend fun <E : Event> E.broadcast(): E = apply {
if (this is BotEvent && !(this.bot as BotImpl<*>).onEvent(this)) {
return@apply
}
@ -81,7 +64,7 @@ suspend fun <E : Subscribable> E.broadcast(): E = apply {
/**
* 可控制是否需要广播这个事件包
*/
interface BroadcastControllable : Subscribable {
interface BroadcastControllable : Event {
val shouldBroadcast: Boolean
get() = true
}

View File

@ -39,7 +39,7 @@ enum class ListeningStatus {
* 事件监听器.
* [subscribe] 等方法返回.
*/
interface Listener<in E : Subscribable> : CompletableJob {
interface Listener<in E : Event> : CompletableJob {
suspend fun onEvent(event: E): ListeningStatus
}
@ -47,7 +47,7 @@ interface Listener<in E : Subscribable> : CompletableJob {
/**
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
* 每当 [事件广播][Subscribable.broadcast] , [handler] 都会被执行.
* 每当 [事件广播][Event.broadcast] , [handler] 都会被执行.
*
* [handler] 返回 [ListeningStatus.STOPPED] 时停止监听.
* [Listener] complete 时结束.
@ -57,7 +57,7 @@ interface Listener<in E : Subscribable> : CompletableJob {
* 例如:
* ```kotlin
* runBlocking { // this: CoroutineScope
* subscribe<Subscribable> { /* 一些处理 */ } // 返回 Listener, 即 CompletableJob
* subscribe<Event> { /* 一些处理 */ } // 返回 Listener, 即 CompletableJob
* }
* foo()
* ```
@ -66,7 +66,7 @@ interface Listener<in E : Subscribable> : CompletableJob {
*
* 要创建一个全局都存在的监听, 即守护协程, 请在 [GlobalScope] 下调用本函数:
* ```kotlin
* GlobalScope.subscribe<Subscribable> { /* 一些处理 */ }
* GlobalScope.subscribe<Event> { /* 一些处理 */ }
* ```
*
*
@ -75,52 +75,52 @@ interface Listener<in E : Subscribable> : CompletableJob {
* bot.subscribe<Subscribe> { /* 一些处理 */ }
* ```
*/
inline fun <reified E : Subscribable> 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) })
/**
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
* 每当 [事件广播][Subscribable.broadcast] , [listener] 都会被执行.
* 每当 [事件广播][Event.broadcast] , [listener] 都会被执行.
*
* 仅当 [Listener] complete 时结束.
*
* @see subscribe 获取更多说明
*/
inline fun <reified E : Subscribable> 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 })
/**
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
* 仅在第一次 [事件广播][Subscribable.broadcast] , [listener] 会被执行.
* 仅在第一次 [事件广播][Event.broadcast] , [listener] 会被执行.
*
* 在这之前, 可通过 [Listener.complete] 来停止监听.
*
* @see subscribe 获取更多说明
*/
inline fun <reified E : Subscribable> 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 })
/**
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
* 每当 [事件广播][Subscribable.broadcast] , [listener] 都会被执行, 直到 [listener] 的返回值 [equals] [valueIfStop]
* 每当 [事件广播][Event.broadcast] , [listener] 都会被执行, 直到 [listener] 的返回值 [equals] [valueIfStop]
*
* 可在任意时刻通过 [Listener.complete] 来停止监听.
*
* @see subscribe 获取更多说明
*/
inline fun <reified E : Subscribable, 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 })
/**
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
* 每当 [事件广播][Subscribable.broadcast] , [listener] 都会被执行,
* 每当 [事件广播][Event.broadcast] , [listener] 都会被执行,
* 如果 [listener] 的返回值 [equals] [valueIfContinue], 则继续监听, 否则停止
*
* 可在任意时刻通过 [Listener.complete] 来停止监听.
*
* @see subscribe 获取更多说明
*/
inline fun <reified E : Subscribable, 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 })
// endregion
@ -146,7 +146,7 @@ inline fun <reified E : Subscribable, T> CoroutineScope.subscribeWhile(valueIfCo
*/
@ListenersBuilderDsl
@Suppress("MemberVisibilityCanBePrivate", "unused")
inline class ListenerBuilder<out E : Subscribable>(
inline class ListenerBuilder<out E : Event>(
@PublishedApi internal inline val handlerConsumer: CoroutineCoroutineScope.(Listener<E>) -> Unit
) {
fun CoroutineCoroutineScope.handler(listener: suspend E.(E) -> ListeningStatus) {

View File

@ -13,86 +13,120 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.utils.WeakRef
import kotlin.properties.Delegates
abstract class BotEvent : Event {
private lateinit var _bot: Bot
open val bot: Bot get() = _bot
constructor(bot: Bot) : super() {
this._bot = bot
}
constructor() : super()
/**
* 有关一个 [Bot] 的事件
*/
interface BotEvent : Event {
val bot: Bot
}
class BotLoginSucceedEvent(bot: Bot) : BotEvent(bot)
/**
* [Bot] 登录完成, 好友列表, 群组列表初始化完成
*/
data class BotLoginSucceedEvent(override val bot: Bot) : BotEvent
class BotOfflineEvent(bot: Bot) : BotEvent(bot)
/**
* [Bot] 离线.
*/
data class BotOfflineEvent(override val bot: Bot) : BotEvent
class BotReadyEvent(bot: Bot) : BotEvent(bot)
/**
* 被挤下线
*/
data class ForceOfflineEvent(
override val bot: Bot,
val title: String,
val tips: String
) : BotEvent, Packet
interface GroupEvent {
/**
* 有关群的事件
*/
interface GroupEvent : BotEvent {
val group: Group
override val bot: Bot
get() = group.bot
}
class AddGroupEvent(bot: Bot, override val group: Group) : BotEvent(bot), GroupEvent
data class AddGroupEvent(override val group: Group) : BotEvent, GroupEvent
class RemoveGroupEvent(bot: Bot, override val group: Group) : BotEvent(bot), GroupEvent
data class RemoveGroupEvent(override val group: Group) : BotEvent, GroupEvent
class BotGroupPermissionChangeEvent(
bot: Bot,
data class BotGroupPermissionChangeEvent(
override val group: Group,
val origin: MemberPermission,
val new: MemberPermission
) : BotEvent(bot), GroupEvent
) : BotEvent, GroupEvent
interface GroupSettingChangeEvent<T> : GroupEvent {
val operator: Member
val origin: T
val new: T
override val group: Group
get() = operator.group
}
class GroupNameChangeEvent(
bot: Bot,
override val group: Group,
data class GroupNameChangeEvent(
override val operator: Member,
override val origin: String,
override val new: String
) : BotEvent(bot), GroupSettingChangeEvent<String>
) : BotEvent, GroupSettingChangeEvent<String>
class GroupMuteAllEvent(
bot: Bot,
override val group: Group,
/**
* "全员禁言" 功能开启
*/
data class GroupMuteAllEvent(
override val operator: Member,
override val origin: Boolean,
override val new: Boolean
) : BotEvent(bot), GroupSettingChangeEvent<Boolean>
) : BotEvent, GroupSettingChangeEvent<Boolean>
class GroupConfessTalkEvent(
bot: Bot,
override val group: Group,
data class GroupConfessTalkEvent(
override val operator: Member,
override val origin: Boolean,
override val new: Boolean
) : BotEvent(bot), GroupSettingChangeEvent<Boolean>
) : BotEvent, GroupSettingChangeEvent<Boolean>
/**
* 有关群成员的事件
*/
interface GroupMemberEvent : GroupEvent {
val member: Member
override val group: Group
get() = member.group
}
class MemberJoinEvent(bot: Bot, override val member: Member) : BotEvent(bot), GroupMemberEvent
/**
* 成员加入群的事件
*/
data class MemberJoinEvent(override val member: Member) : BotEvent, GroupMemberEvent
class MemberLeftEvent(bot: Bot, override val member: Member) : BotEvent(bot), GroupMemberEvent
/**
* 成员离开群的事件
*/
sealed class MemberLeftEvent : BotEvent, GroupMemberEvent {
/**
* 成员被踢出群
*/
data class Kick(override val member: Member, val operator: Member) : MemberLeftEvent()
class MemberMuteEvent(bot: Bot, override val member: Member) : BotEvent(bot), GroupMemberEvent
/**
* 成员主动离开
*/
data class Quit(override val member: Member) : MemberLeftEvent()
}
class MemberPermissionChangeEvent(
bot: Bot,
data class MemberPermissionChangeEvent(
override val bot: Bot,
override val member: Member,
val origin: MemberPermission,
val new: MemberPermission
) : BotEvent(bot), GroupMemberEvent
) : BotEvent, GroupMemberEvent

View File

@ -1,13 +0,0 @@
package net.mamoe.mirai.event.events
import net.mamoe.mirai.Bot
import net.mamoe.mirai.data.Packet
/**
* 被挤下线
*/
data class ForceOfflineEvent(
override val bot: Bot,
val title: String,
val tips: String
) : BotEvent(), Packet

View File

@ -7,10 +7,11 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.data
package net.mamoe.mirai.event.events
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.data.EventPacket
// region mute

View File

@ -10,9 +10,9 @@
package net.mamoe.mirai.event.internal
import kotlinx.coroutines.*
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.Listener
import net.mamoe.mirai.event.ListeningStatus
import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.utils.LockFreeLinkedList
import net.mamoe.mirai.utils.MiraiDebugAPI
import net.mamoe.mirai.utils.MiraiLogger
@ -29,14 +29,14 @@ import kotlin.reflect.KClass
var EventDisabled = false
@PublishedApi
internal fun <L : Listener<E>, E : Subscribable> KClass<out E>.subscribeInternal(listener: L): L {
internal fun <L : Listener<E>, E : Event> KClass<out E>.subscribeInternal(listener: L): L {
this.listeners().addLast(listener)
return listener
}
@PublishedApi
@Suppress("FunctionName")
internal fun <E : Subscribable> CoroutineScope.Handler(handler: suspend (E) -> ListeningStatus): Handler<E> {
internal fun <E : Event> CoroutineScope.Handler(handler: suspend (E) -> ListeningStatus): Handler<E> {
return Handler(coroutineContext[Job], coroutineContext, handler)
}
@ -45,7 +45,7 @@ private inline fun inline(block: () -> Unit) = block()
* 事件处理器.
*/
@PublishedApi
internal class Handler<in E : Subscribable>
internal class Handler<in E : Event>
@PublishedApi internal constructor(parentJob: Job?, private val subscriberContext: CoroutineContext, @JvmField val handler: suspend (E) -> ListeningStatus) :
Listener<E>, CompletableJob by Job(parentJob) {
@ -79,21 +79,21 @@ internal class Handler<in E : Subscribable>
/**
* 这个事件类的监听器 list
*/
internal fun <E : Subscribable> KClass<out E>.listeners(): EventListeners<E> = EventListenerManager.get(this)
internal fun <E : Event> KClass<out E>.listeners(): EventListeners<E> = EventListenerManager.get(this)
internal class EventListeners<E : Subscribable> : LockFreeLinkedList<Listener<E>>()
internal class EventListeners<E : Event> : LockFreeLinkedList<Listener<E>>()
/**
* 管理每个事件 class [EventListeners].
* [EventListeners] lazy : 它们只会在被需要的时候才创建和存储.
*/
internal object EventListenerManager {
private data class Registry<E : Subscribable>(val clazz: KClass<E>, val listeners: EventListeners<E>)
private data class Registry<E : Event>(val clazz: KClass<E>, val listeners: EventListeners<E>)
private val registries = LockFreeLinkedList<Registry<*>>()
@Suppress("UNCHECKED_CAST")
internal fun <E : Subscribable> get(clazz: KClass<out E>): EventListeners<E> {
internal fun <E : Event> get(clazz: KClass<out E>): EventListeners<E> {
return registries.filteringGetOrAdd({ it.clazz == clazz }) {
Registry(
clazz,
@ -105,7 +105,7 @@ internal object EventListenerManager {
// inline: NO extra Continuation
@Suppress("UNCHECKED_CAST")
internal suspend inline fun Subscribable.broadcastInternal() {
internal suspend inline fun Event.broadcastInternal() {
if (EventDisabled) return
callAndRemoveIfRequired(this::class.listeners())
@ -113,18 +113,18 @@ internal suspend inline fun Subscribable.broadcastInternal() {
var supertypes = this::class.supertypes
while (true) {
val superSubscribableType = supertypes.firstOrNull {
it.classifier as? KClass<out Subscribable> != null
it.classifier as? KClass<out Event> != null
}
superSubscribableType?.let {
callAndRemoveIfRequired((it.classifier as KClass<out Subscribable>).listeners())
callAndRemoveIfRequired((it.classifier as KClass<out Event>).listeners())
}
supertypes = (superSubscribableType?.classifier as? KClass<*>)?.supertypes ?: return
}
}
private suspend inline fun <E : Subscribable> E.callAndRemoveIfRequired(listeners: EventListeners<E>) {
private suspend inline fun <E : Event> E.callAndRemoveIfRequired(listeners: EventListeners<E>) {
// atomic foreach
listeners.forEach {
if (it.onEvent(this) == ListeningStatus.STOPPED) {

View File

@ -59,14 +59,14 @@ interface Message {
infix fun eq(other: Message): Boolean = this == other
/**
* [stringValue] [other] 比较
* [toString] [other] 比较
*/
infix fun eq(other: String): Boolean = this.toString() == other
operator fun contains(sub: String): Boolean = false
/**
* [this] 连接到 [tail] 的头部. 类似于字符串相加.
* `this` 连接到 [tail] 的头部. 类似于字符串相加.
*
* :
* ```kotlin
@ -92,7 +92,7 @@ interface Message {
override fun toString(): String
operator fun plus(another: Message): MessageChain = this.followedBy(another)
operator fun plus(another: String): MessageChain = this.followedBy(another.toString().toMessage())
operator fun plus(another: String): MessageChain = this.followedBy(another.toMessage())
// `+ ""` will be resolved to `plus(String)` instead of `plus(CharSeq)`
operator fun plus(another: CharSequence): MessageChain = this.followedBy(another.toString().toMessage())
}

View File

@ -17,6 +17,6 @@ package net.mamoe.mirai.event
object Events {
/*
@JvmStatic
fun <E : Subscribable> subscribe(type: Class<E>, handler: suspend (E) -> ListeningStatus) =
fun <E : Event> subscribe(type: Class<E>, handler: suspend (E) -> ListeningStatus) =
runBlocking { type.kotlin.subscribe(handler) }*/
}

View File

@ -12,12 +12,11 @@ package net.mamoe.mirai.event
import kotlinx.coroutines.CompletableJob
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.test.shouldBeEqualTo
import kotlin.system.exitProcess
import kotlin.test.Test
class TestEvent : Subscribable {
class TestEvent : Event {
var triggered = false
}
@ -46,7 +45,7 @@ class EventTests {
}
open class ParentEvent : Subscribable {
open class ParentEvent : Event {
var triggered = false
}

View File

@ -20,7 +20,7 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.alsoLogin
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.events.ReceiveFriendAddRequestEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeGroupMessages
@ -48,8 +48,8 @@ suspend fun main() {
// override config here.
}.alsoLogin()
// 任何可以监听的对象都继承 Subscribable, 因此这个订阅会订阅全部的事件.
GlobalScope.subscribeAlways<Subscribable> {
// 任何可以监听的对象都继承 Event, 因此这个订阅会订阅全部的事件.
GlobalScope.subscribeAlways<Event> {
//bot.logger.verbose("收到了一个事件: $this")
}