Commit de86041d authored by Him188's avatar Him188

Powerful subscribers

parent 0a471e9b
This diff is collapsed.
......@@ -13,6 +13,7 @@ import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import net.mamoe.mirai.utils.BotNetworkConfiguration
import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
import net.mamoe.mirai.utils.log
import kotlin.jvm.JvmOverloads
......@@ -52,7 +53,7 @@ data class BotAccount(
* @see net.mamoe.mirai.contact.Contact
*/
class Bot(val account: BotAccount, val logger: MiraiLogger) {
constructor(id: UInt, password: String) : this(BotAccount(id, password))
constructor(qq: UInt, password: String) : this(BotAccount(qq, password))
constructor(account: BotAccount) : this(account, DefaultLogger("Bot(" + account.id + ")"))
val contacts = ContactSystem()
......@@ -131,8 +132,12 @@ class Bot(val account: BotAccount, val logger: MiraiLogger) {
}
}
suspend inline fun Int.qq(): QQ = getQQ(this.coerceAtLeastOrFail(0).toUInt())
suspend inline fun Long.qq(): QQ = getQQ(this.coerceAtLeastOrFail(0))
suspend inline fun UInt.qq(): QQ = getQQ(this)
suspend inline fun Int.group(): Group = getGroup(this.coerceAtLeastOrFail(0).toUInt())
suspend inline fun Long.group(): Group = getGroup(this.coerceAtLeastOrFail(0))
suspend inline fun UInt.group(): Group = getGroup(GroupId(this))
suspend inline fun GroupId.group(): Group = getGroup(this)
suspend inline fun GroupInternalId.group(): Group = getGroup(this)
......
......@@ -9,14 +9,19 @@ import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import net.mamoe.mirai.network.session
import net.mamoe.mirai.utils.BotNetworkConfiguration
import net.mamoe.mirai.utils.internal.PositiveNumbers
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
/*
* 在 [Bot] 中的方法的捷径
*/
//Contacts
suspend inline fun Bot.getQQ(@PositiveNumbers number: Long): QQ = this.contacts.getQQ(number.coerceAtLeastOrFail(0).toUInt())
suspend inline fun Bot.getQQ(number: UInt): QQ = this.contacts.getQQ(number)
suspend inline fun Bot.getGroup(id: UInt): Group = this.contacts.getGroup(GroupId(id))
suspend inline fun Bot.getGroup(@PositiveNumbers id: Long): Group = this.contacts.getGroup(GroupId(id.coerceAtLeastOrFail(0).toUInt()))
suspend inline fun Bot.getGroup(id: GroupId): Group = this.contacts.getGroup(id)
suspend inline fun Bot.getGroup(internalId: GroupInternalId): Group = this.contacts.getGroup(internalId)
......
......@@ -27,11 +27,13 @@ sealed class Contact(val bot: Bot, val id: UInt) {
abstract suspend fun sendMessage(message: MessageChain)
abstract suspend fun sendXMLMessage(message: String)
}
suspend fun Contact.sendMessage(plain: String) = sendMessage(PlainText(plain))
suspend fun Contact.sendMessage(message: Message) = sendMessage(message.toChain())
//这两个方法写在 Contact 里面更适合. 因为 import 不便
suspend fun sendMessage(plain: String) = sendMessage(PlainText(plain))
suspend fun sendMessage(message: Message) = sendMessage(message.toChain())
}
/**
* 一般的用户可见的 ID.
......
@file:Suppress("EXPERIMENTAL_API_USAGE", "MemberVisibilityCanBePrivate", "unused")
package net.mamoe.mirai.event
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.message.*
import kotlin.jvm.JvmName
/**
* 消息事件时创建的临时容器.
* @see
*/
abstract class SenderAndMessage(
val sender: QQ,
val message: MessageChain
) {
/**
* 给这个消息事件的主体发送消息
* 对于好友消息事件, 这个方法将会给好友 ([sender]) 发送消息
* 对于群消息事件, 这个方法将会给群 ([sender]) 发送消息
*/
abstract suspend fun reply(message: MessageChain)
suspend fun reply(plain: String) = reply(PlainText(plain))
suspend fun reply(message: Message) = reply(message.toChain())
}
class FriendSenderAndMessage(
sender: QQ,
message: MessageChain
) : SenderAndMessage(sender, message) {
override suspend fun reply(message: MessageChain) = sender.sendMessage(message)
}
class GroupSenderAndMessage(
val group: Group,
sender: QQ,
message: MessageChain
) : SenderAndMessage(sender, message) {
override suspend fun reply(message: MessageChain) = group.sendMessage(message)
}
/**
* 订阅来自所有 [Bot] 的所有联系人的消息事件. 联系人可以是任意群或任意好友或临时会话.
*/
@MessageListenerDsl
suspend inline fun subscribeMessages(noinline listeners: suspend MessageSubscribersBuilder<SenderAndMessage>.() -> Unit) {
MessageSubscribersBuilder<SenderAndMessage> { listener ->
subscribeAlways<BotEvent> {
when (it) {
is FriendMessageEvent -> listener(FriendSenderAndMessage(it.sender, it.message))
is GroupMessageEvent -> listener(GroupSenderAndMessage(it.group, it.sender, it.message))
}
}
}.apply { listeners() }
}
/**
* 订阅来自所有 [Bot] 的所有群消息事件
*/
@MessageListenerDsl
suspend inline fun subscribeGroupMessages(noinline listeners: suspend MessageSubscribersBuilder<GroupSenderAndMessage>.() -> Unit) {
MessageSubscribersBuilder<GroupSenderAndMessage> { listener ->
subscribeAlways<GroupMessageEvent> {
listener(GroupSenderAndMessage(it.group, it.sender, it.message))
}
}.apply { listeners() }
}
/**
* 订阅来自所有 [Bot] 的所有好友消息事件
*/
@MessageListenerDsl
suspend inline fun subscribeFriendMessages(noinline listeners: suspend MessageSubscribersBuilder<FriendSenderAndMessage>.() -> Unit) {
MessageSubscribersBuilder<FriendSenderAndMessage> { listener ->
subscribeAlways<FriendMessageEvent> {
listener(FriendSenderAndMessage(it.sender, it.message))
}
}.apply { listeners() }
}
/**
* 订阅来自这个 [Bot] 的所有联系人的消息事件. 联系人可以是任意群或任意好友或临时会话.
*/
@MessageListenerDsl
suspend inline fun Bot.subscribeMessages(noinline listeners: suspend MessageSubscribersBuilder<SenderAndMessage>.() -> Unit) {
MessageSubscribersBuilder<SenderAndMessage> { listener ->
this.subscribeAlways<BotEvent> {
when (it) {
is FriendMessageEvent -> listener(FriendSenderAndMessage(it.sender, it.message))
is GroupMessageEvent -> listener(GroupSenderAndMessage(it.group, it.sender, it.message))
}
}
}.apply { listeners() }
}
/**
* 订阅来自这个 [Bot] 的所有群消息事件
*/
@MessageListenerDsl
suspend inline fun Bot.subscribeGroupMessages(noinline listeners: suspend MessageSubscribersBuilder<GroupSenderAndMessage>.() -> Unit) {
MessageSubscribersBuilder<GroupSenderAndMessage> { listener ->
this.subscribeAlways<GroupMessageEvent> {
listener(GroupSenderAndMessage(it.group, it.sender, it.message))
}
}.apply { listeners() }
}
/**
* 订阅来自这个 [Bot] 的所有好友消息事件.
*/
@MessageListenerDsl
suspend inline fun Bot.subscribeFriendMessages(noinline listeners: suspend MessageSubscribersBuilder<FriendSenderAndMessage>.() -> Unit) {
MessageSubscribersBuilder<FriendSenderAndMessage> { listener ->
this.subscribeAlways<FriendMessageEvent> {
listener(FriendSenderAndMessage(it.sender, it.message))
}
}.apply { listeners() }
}
internal typealias MessageListener<T> = @MessageListenerDsl suspend T.(String) -> Unit
internal typealias MessageReplier<T> = @MessageListenerDsl suspend T.(String) -> String
internal suspend inline operator fun <T : SenderAndMessage> MessageListener<T>.invoke(t: T) = this.invoke(t, t.message.toString())
@JvmName("invoke1") //Avoid Platform declaration clash
internal suspend inline operator fun <T : SenderAndMessage> MessageReplier<T>.invoke(t: T) = this.invoke(t, t.message.toString())
/**
* 消息订阅构造器
*
* @see subscribeFriendMessages
* @sample demo.subscribe.messageDSL
*/
@Suppress("unused")
@MessageListenerDsl
inline class MessageSubscribersBuilder<T : SenderAndMessage>(
val handlerConsumer: suspend (MessageListener<T>) -> Unit
) {
suspend inline fun case(equals: String, trim: Boolean = true, noinline listener: MessageListener<T>) = content({ equals == if (trim) it.trim() else it }, listener)
suspend inline fun contains(value: String, noinline listener: MessageListener<T>) = content({ value in it }, listener)
suspend inline fun replyEndsWith(value: String, noinline replier: MessageReplier<T>) = content({ it.endsWith(value) }) { replier(this) }
suspend inline fun startsWith(start: String, noinline listener: MessageListener<T>) = content({ it.startsWith(start) }, listener)
suspend inline fun endsWith(start: String, noinline listener: MessageListener<T>) = content({ it.endsWith(start) }, listener)
suspend inline fun sentBy(id: UInt, noinline listener: MessageListener<T>) = content({ sender.id == id }, listener)
suspend inline fun sentBy(id: Long, noinline listener: MessageListener<T>) = sentBy(id.toUInt(), listener)
suspend inline fun <reified M : Message> has(noinline listener: MessageListener<T>) = handlerConsumer { if (message.any<M>()) listener(this) }
suspend inline fun content(noinline filter: T.(String) -> Boolean, noinline listener: MessageListener<T>) =
handlerConsumer { if (this.filter(message.toString())) listener(this) }
suspend inline fun replyCase(equals: String, trim: Boolean = true, noinline replier: MessageReplier<T>) = case(equals, trim) { reply(replier(this)) }
suspend inline fun replyContains(value: String, noinline replier: MessageReplier<T>) = content({ value in it }) { replier(this) }
suspend inline fun replyStartsWith(value: String, noinline replier: MessageReplier<T>) = content({ it.startsWith(value) }) { replier(this) }
suspend infix fun String.reply(reply: String) = case(this) { this.reply(reply) }
}
/**
* DSL 标记. 将能让 IDE 阻止一些错误的方法调用.
*/
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.TYPE)
@DslMarker
internal annotation class MessageListenerDsl
\ No newline at end of file
......@@ -72,6 +72,7 @@ suspend fun <E : Event> KClass<E>.subscribeWhileNull(listener: suspend (E) -> An
* 监听一个事件. 可同时进行多种方式的监听
* @see ListenerBuilder
*/
@ListenersBuilderDsl
suspend fun <E : Event> KClass<E>.subscribeAll(listeners: suspend ListenerBuilder<E>.() -> Unit) {
with(ListenerBuilder<E> { this.subscribeInternal(it) }) {
listeners()
......@@ -82,6 +83,7 @@ suspend fun <E : Event> KClass<E>.subscribeAll(listeners: suspend ListenerBuilde
* 监听一个事件. 可同时进行多种方式的监听
* @see ListenerBuilder
*/
@ListenersBuilderDsl
suspend inline fun <reified E : Event> subscribeAll(noinline listeners: suspend ListenerBuilder<E>.() -> Unit) = E::class.subscribeAll(listeners)
/**
......@@ -100,6 +102,7 @@ suspend inline fun <reified E : Event> subscribeAll(noinline listeners: suspend
* }
* ```
*/
@ListenersBuilderDsl
@Suppress("MemberVisibilityCanBePrivate", "unused")
inline class ListenerBuilder<out E : Event>(
private val handlerConsumer: suspend (Handler<in E>) -> Unit
......@@ -125,4 +128,7 @@ inline class ListenerBuilder<out E : Event>(
suspend fun once(block: suspend (E) -> Unit) = handler { block(it); ListeningStatus.STOPPED }
}
@DslMarker
annotation class ListenersBuilderDsl
// endregion
\ No newline at end of file
......@@ -3,6 +3,7 @@
package net.mamoe.mirai.event
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.event.internal.HandlerWithBot
import net.mamoe.mirai.event.internal.subscribeInternal
import kotlin.reflect.KClass
......@@ -16,48 +17,66 @@ import kotlin.reflect.KClass
// region 顶层方法
suspend inline fun <reified E : Event> Bot.subscribe(noinline handler: suspend Bot.(E) -> ListeningStatus) = E::class.subscribe(this, handler)
suspend inline fun <reified E : BotEvent> Bot.subscribe(noinline handler: suspend Bot.(E) -> ListeningStatus) = E::class.subscribe(this, handler)
suspend inline fun <reified E : Event> Bot.subscribeAlways(noinline listener: suspend Bot.(E) -> Unit) = E::class.subscribeAlways(this, listener)
suspend inline fun <reified E : BotEvent> Bot.subscribeAlways(noinline listener: suspend Bot.(E) -> Unit) = E::class.subscribeAlways(this, listener)
suspend inline fun <reified E : Event> Bot.subscribeOnce(noinline listener: suspend Bot.(E) -> Unit) = E::class.subscribeOnce(this, listener)
suspend inline fun <reified E : BotEvent> Bot.subscribeOnce(noinline listener: suspend Bot.(E) -> Unit) = E::class.subscribeOnce(this, listener)
suspend inline fun <reified E : Event, T> Bot.subscribeUntil(valueIfStop: T, noinline listener: suspend Bot.(E) -> T) = E::class.subscribeUntil(this, valueIfStop, listener)
suspend inline fun <reified E : Event> Bot.subscribeUntilFalse(noinline listener: suspend Bot.(E) -> Boolean) = E::class.subscribeUntilFalse(this, listener)
suspend inline fun <reified E : Event> Bot.subscribeUntilTrue(noinline listener: suspend Bot.(E) -> Boolean) = E::class.subscribeUntilTrue(this, listener)
suspend inline fun <reified E : Event> Bot.subscribeUntilNull(noinline listener: suspend Bot.(E) -> Any?) = E::class.subscribeUntilNull(this, listener)
suspend inline fun <reified E : BotEvent, T> Bot.subscribeUntil(valueIfStop: T, noinline listener: suspend Bot.(E) -> T) = E::class.subscribeUntil(this, valueIfStop, listener)
suspend inline fun <reified E : BotEvent> Bot.subscribeUntilFalse(noinline listener: suspend Bot.(E) -> Boolean) = E::class.subscribeUntilFalse(this, listener)
suspend inline fun <reified E : BotEvent> Bot.subscribeUntilTrue(noinline listener: suspend Bot.(E) -> Boolean) = E::class.subscribeUntilTrue(this, listener)
suspend inline fun <reified E : BotEvent> Bot.subscribeUntilNull(noinline listener: suspend Bot.(E) -> Any?) = E::class.subscribeUntilNull(this, listener)
suspend inline fun <reified E : Event, T> Bot.subscribeWhile(valueIfContinue: T, noinline listener: suspend Bot.(E) -> T) = E::class.subscribeWhile(this, valueIfContinue, listener)
suspend inline fun <reified E : Event> Bot.subscribeWhileFalse(noinline listener: suspend Bot.(E) -> Boolean) = E::class.subscribeWhileFalse(this, listener)
suspend inline fun <reified E : Event> Bot.subscribeWhileTrue(noinline listener: suspend Bot.(E) -> Boolean) = E::class.subscribeWhileTrue(this, listener)
suspend inline fun <reified E : Event> Bot.subscribeWhileNull(noinline listener: suspend Bot.(E) -> Any?) = E::class.subscribeWhileNull(this, listener)
suspend inline fun <reified E : BotEvent, T> Bot.subscribeWhile(valueIfContinue: T, noinline listener: suspend Bot.(E) -> T) =
E::class.subscribeWhile(this, valueIfContinue, listener)
suspend inline fun <reified E : BotEvent> Bot.subscribeWhileFalse(noinline listener: suspend Bot.(E) -> Boolean) = E::class.subscribeWhileFalse(this, listener)
suspend inline fun <reified E : BotEvent> Bot.subscribeWhileTrue(noinline listener: suspend Bot.(E) -> Boolean) = E::class.subscribeWhileTrue(this, listener)
suspend inline fun <reified E : BotEvent> Bot.subscribeWhileNull(noinline listener: suspend Bot.(E) -> Any?) = E::class.subscribeWhileNull(this, listener)
// endregion
// region KClass 的扩展方法 (不推荐)
// region KClass 的扩展方法 (仅内部使用)
suspend fun <E : Event> KClass<E>.subscribe(bot: Bot, handler: suspend Bot.(E) -> ListeningStatus) = this.subscribeInternal(HandlerWithBot(bot, handler))
@PublishedApi
internal suspend fun <E : BotEvent> KClass<E>.subscribe(bot: Bot, handler: suspend Bot.(E) -> ListeningStatus) = this.subscribeInternal(HandlerWithBot(bot, handler))
suspend fun <E : Event> KClass<E>.subscribeAlways(bot: Bot, listener: suspend Bot.(E) -> Unit) =
@PublishedApi
internal suspend fun <E : BotEvent> KClass<E>.subscribeAlways(bot: Bot, listener: suspend Bot.(E) -> Unit) =
this.subscribeInternal(HandlerWithBot(bot) { listener(it); ListeningStatus.LISTENING })
suspend fun <E : Event> KClass<E>.subscribeOnce(bot: Bot, listener: suspend Bot.(E) -> Unit) = this.subscribeInternal(HandlerWithBot(bot) { listener(it); ListeningStatus.STOPPED })
@PublishedApi
internal suspend fun <E : BotEvent> KClass<E>.subscribeOnce(bot: Bot, listener: suspend Bot.(E) -> Unit) =
this.subscribeInternal(HandlerWithBot(bot) { listener(it); ListeningStatus.STOPPED })
suspend fun <E : Event, T> KClass<E>.subscribeUntil(bot: Bot, valueIfStop: T, listener: suspend Bot.(E) -> T) =
@PublishedApi
internal suspend fun <E : BotEvent, T> KClass<E>.subscribeUntil(bot: Bot, valueIfStop: T, listener: suspend Bot.(E) -> T) =
subscribeInternal(HandlerWithBot(bot) { if (listener(it) === valueIfStop) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
suspend fun <E : Event> KClass<E>.subscribeUntilFalse(bot: Bot, listener: suspend Bot.(E) -> Boolean) = subscribeUntil(bot, false, listener)
suspend fun <E : Event> KClass<E>.subscribeUntilTrue(bot: Bot, listener: suspend Bot.(E) -> Boolean) = subscribeUntil(bot, true, listener)
suspend fun <E : Event> KClass<E>.subscribeUntilNull(bot: Bot, listener: suspend Bot.(E) -> Any?) = subscribeUntil(bot, null, listener)
@PublishedApi
internal suspend fun <E : BotEvent> KClass<E>.subscribeUntilFalse(bot: Bot, listener: suspend Bot.(E) -> Boolean) = subscribeUntil(bot, false, listener)
@PublishedApi
internal suspend fun <E : BotEvent> KClass<E>.subscribeUntilTrue(bot: Bot, listener: suspend Bot.(E) -> Boolean) = subscribeUntil(bot, true, listener)
@PublishedApi
internal suspend fun <E : BotEvent> KClass<E>.subscribeUntilNull(bot: Bot, listener: suspend Bot.(E) -> Any?) = subscribeUntil(bot, null, listener)
suspend fun <E : Event, T> KClass<E>.subscribeWhile(bot: Bot, valueIfContinue: T, listener: suspend Bot.(E) -> T) =
@PublishedApi
internal suspend fun <E : BotEvent, T> KClass<E>.subscribeWhile(bot: Bot, valueIfContinue: T, listener: suspend Bot.(E) -> T) =
subscribeInternal(HandlerWithBot(bot) { if (listener(it) !== valueIfContinue) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
suspend fun <E : Event> KClass<E>.subscribeWhileFalse(bot: Bot, listener: suspend Bot.(E) -> Boolean) = subscribeWhile(bot, false, listener)
suspend fun <E : Event> KClass<E>.subscribeWhileTrue(bot: Bot, listener: suspend Bot.(E) -> Boolean) = subscribeWhile(bot, true, listener)
suspend fun <E : Event> KClass<E>.subscribeWhileNull(bot: Bot, listener: suspend Bot.(E) -> Any?) = subscribeWhile(bot, null, listener)
@PublishedApi
internal suspend fun <E : BotEvent> KClass<E>.subscribeWhileFalse(bot: Bot, listener: suspend Bot.(E) -> Boolean) = subscribeWhile(bot, false, listener)
@PublishedApi
internal suspend fun <E : BotEvent> KClass<E>.subscribeWhileTrue(bot: Bot, listener: suspend Bot.(E) -> Boolean) = subscribeWhile(bot, true, listener)
@PublishedApi
internal suspend fun <E : BotEvent> KClass<E>.subscribeWhileNull(bot: Bot, listener: suspend Bot.(E) -> Any?) = subscribeWhile(bot, null, listener)
// endregion
\ No newline at end of file
......@@ -2,7 +2,6 @@ package net.mamoe.mirai.event.events
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.message.Message
import net.mamoe.mirai.message.MessageChain
......
......@@ -3,7 +3,6 @@ package net.mamoe.mirai.event.events
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.message.Message
import net.mamoe.mirai.message.MessageChain
import net.mamoe.mirai.network.protocol.tim.packet.event.SenderPermission
......@@ -12,13 +11,14 @@ import net.mamoe.mirai.network.protocol.tim.packet.event.SenderPermission
abstract class GroupEvent(bot: Bot, val group: Group) : BotEvent(bot)
@Suppress("unused")
class GroupMessageEvent(
bot: Bot,
group: Group,
val sender: QQ,
val message: MessageChain,
val senderPermission: SenderPermission,
val senderName: String//若他有群名片就是群名片, 没有就是昵称
bot: Bot,
group: Group,
val sender: QQ,
val message: MessageChain,
val senderPermission: SenderPermission,
val senderName: String//若他有群名片就是群名片, 没有就是昵称
) : GroupEvent(bot, group) {
suspend inline fun reply(message: Message) = group.sendMessage(message)
......
......@@ -7,6 +7,7 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.EventScope
import net.mamoe.mirai.event.ListeningStatus
import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.utils.internal.inlinedRemoveIf
import kotlin.reflect.KClass
......@@ -62,9 +63,22 @@ class Handler<E : Event>(val handler: suspend (E) -> ListeningStatus) : Listener
override suspend fun onEvent(event: E): ListeningStatus = handler.invoke(event)
}
/**
* 带有 bot 筛选的监听器.
* 所有的非 [BotEvent] 的事件都不会被处理
* 所有的 [BotEvent.bot] `!==` `bot` 的事件都不会被处理
*/
class HandlerWithBot<E : Event>(val bot: Bot, val handler: suspend Bot.(E) -> ListeningStatus) : Listener<E>() {
override suspend fun onEvent(event: E): ListeningStatus = with(bot) {
handler(event)
if (event !is BotEvent || event.bot !== this) {
return ListeningStatus.LISTENING
}
return if (bot !== this) {
ListeningStatus.LISTENING
} else {
handler(event)
}
}
}
......
@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE")
package demo1
package demo.subscribe
import kotlinx.coroutines.delay
import kotlinx.coroutines.withTimeoutOrNull
import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.contact.sendMessage
import net.mamoe.mirai.event.*
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.event.subscribeAll
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeUntilFalse
import net.mamoe.mirai.login
import net.mamoe.mirai.message.Image
import net.mamoe.mirai.message.ImageId
import net.mamoe.mirai.message.PlainText
import net.mamoe.mirai.message.firstOrNull
import net.mamoe.mirai.message.*
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingRawPacket
import net.mamoe.mirai.network.protocol.tim.packet.action.uploadImage
import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess
......@@ -42,34 +35,104 @@ private fun readTestAccount(): BotAccount? {
}
}
@Suppress("UNUSED_VARIABLE")
suspend fun main() {
val bot = Bot(
readTestAccount() ?: BotAccount(//填写你的账号
id = 1994701121u,
password = "123456"
)
)
/**
* 使用 dsl 监听消息事件
*
* @see subscribeFriendMessages
* @see subscribeMessages
* @see subscribeGroupMessages
*
* @see MessageSubscribersBuilder
*/
suspend fun Bot.messageDSL() {
//监听所有 bot 的来自所有群和好友的消息
subscribeMessages {
replyCase("你好") { "你好" }
has<Image> {
// this: SenderAndMessage
// message: MessageChain
// sender: QQ
// it: String (MessageChain.toString)
if (this is GroupSenderAndMessage) {
//如果是群消息
// group: Group
this.group.sendMessage("你在一个群里")
}
// 覆盖默认的配置
bot.login {
randomDeviceName = false
}.requireSuccess()
reply("你发送了一个图片, ID为 ${message[Image].id}, 我要复读了")
reply(message)
}
replyContains("123") { "你的消息里面包含 123" }
replyCase("我的qq") { sender.id.toString() }
sentBy(1040400290) {
reply("是你!")
}
contains("复读") {
reply(message)
}
case("上传好友图片") {
val filename = it.toString().substringAfter("上传好友图片")
File("C:\\Users\\Him18\\Desktop\\$filename").sendAsImageTo(1040400290u.qq())
}
subscribeAlways<GroupMessageEvent> {
if (it.message eq "复读" && it.group.internalId.value == 580266363u) {
it.reply(it.message)
case("上传群图片") {
val filename = it.toString().substringAfter("上传好友图片")
File("C:\\Users\\Him18\\Desktop\\$filename").sendAsImageTo(920503456u.group())
}
}
subscribeMessages {
case("你好") {
// this: SenderAndMessage
// message: MessageChain
// sender: QQ
// it: String (来自 MessageChain.toString)
// group: Group (如果是群消息)
reply("你好")
}
}
subscribeFriendMessages {
contains("A") {
// this: FriendSenderAndMessage
// message: MessageChain
// sender: QQ
// it: String (来自 MessageChain.toString)
reply("B")
}
}
subscribeGroupMessages {
// this: FriendSenderAndMessage
// message: MessageChain
// sender: QQ
// it: String (来自 MessageChain.toString)
// group: Group
}
}
/**
* 监听单个事件
*/
@Suppress("UNUSED_VARIABLE")
suspend fun directlySubscribe(bot: Bot) {
// 手动处理消息
// 使用 Bot 的扩展方法监听, 将在处理事件时得到一个 this: Bot.
// 这样可以很方便地调用 Bot 内的一些扩展方法如 UInt.qq():QQ
// 这样可以调用 Bot 内的一些扩展方法如 UInt.qq():QQ
bot.subscribeAlways<FriendMessageEvent> {
// this: Bot
// it: FriendMessageEvent
// 获取第一个纯文本消息, 获取不到会抛出 NoSuchElementException
// val firstText = it.message.first<PlainText>()
val firstText = it.message.firstOrNull<PlainText>()
// 获取第一个图片
......@@ -97,15 +160,6 @@ suspend fun main() {
)
}
"上传好友图片" in it.message -> withTimeoutOrNull(5000) {
val filename = it.message.toString().substringAfter("上传好友图片")
val id = 1040400290u.qq()
.uploadImage(File("C:\\Users\\Him18\\Desktop\\$filename").toExternalImage())
it.reply(id.value)
delay(100)
it.reply(Image(id))
}
"上传群图片" in it.message -> withTimeoutOrNull(5000) {
val filename = it.message.toString().substringAfter("上传群图片")
val image = File(
......@@ -131,8 +185,8 @@ suspend fun main() {
it.message eq "发图片群2" -> 580266363u.group().sendMessage(Image(ImageId("{7AA4B3AA-8C3C-0F45-2D9B-7F302A0ACEAA}.jpg")))
/* it.event eq "发图片" -> sendFriendMessage(it.sender, PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
image.upload(session, it.sender).of()
/* it.event eq "发图片" -> sendFriendMessage(it.sentBy, PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
image.upload(session, it.sentBy).of()
})*/
it.message eq "发图片2" -> it.reply(PlainText("test") + Image(ImageId("{7AA4B3AA-8C3C-0F45-2D9B-7F302A0ACEAA}.jpg")))
else -> {
......@@ -140,7 +194,24 @@ suspend fun main() {
}
}
}
}
@Suppress("UNUSED_VARIABLE")
suspend fun main() {
val bot = Bot(
readTestAccount() ?: BotAccount(//填写你的账号
id = 1994701121u,
password = "123456"
)
)
// 覆盖默认的配置
bot.login {
randomDeviceName = false
}.requireSuccess()
bot.messageDSL()
directlySubscribe(bot)
//DSL 监听
subscribeAll<FriendMessageEvent> {
......
@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE")
package demo1
package demo.gentleman
import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.login
import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess
import java.io.File
......@@ -25,7 +27,7 @@ private fun readTestAccount(): BotAccount? {
@Suppress("UNUSED_VARIABLE")
suspend fun main() {
val bot = Bot(
readTestAccount() ?: BotAccount(//填写你的账号
readTestAccount() ?: BotAccount(
id = 1994701121u,
password = "123456"
)
......@@ -33,5 +35,11 @@ suspend fun main() {
bot.login().requireSuccess()
bot.subscribeAlways<FriendMessageEvent> {
}
bot.network.awaitDisconnection()//等到直到断开连接
}
\ No newline at end of file
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