Commit 0334d33d authored by Him188's avatar Him188

Extensions of subscribers for Bot

parent cb320dd9
......@@ -21,60 +21,38 @@ enum class ListeningStatus {
// region 顶层方法
suspend inline fun <reified E : Event> subscribe(noinline handler: suspend (E) -> ListeningStatus) =
E::class.subscribe(handler)
suspend inline fun <reified E : Event> subscribe(noinline handler: suspend (E) -> ListeningStatus) = E::class.subscribe(handler)
suspend inline fun <reified E : Event> subscribeAlways(noinline listener: suspend (E) -> Unit) =
E::class.subscribeAlways(listener)
suspend inline fun <reified E : Event> subscribeAlways(noinline listener: suspend (E) -> Unit) = E::class.subscribeAlways(listener)
suspend inline fun <reified E : Event> subscribeOnce(noinline listener: suspend (E) -> Unit) =
E::class.subscribeOnce(listener)
suspend inline fun <reified E : Event> subscribeOnce(noinline listener: suspend (E) -> Unit) = E::class.subscribeOnce(listener)
suspend inline fun <reified E : Event, T> subscribeUntil(valueIfStop: T, noinline listener: suspend (E) -> T) =
E::class.subscribeUntil(valueIfStop, listener)
suspend inline fun <reified E : Event, T> subscribeUntil(valueIfStop: T, noinline listener: suspend (E) -> T) = E::class.subscribeUntil(valueIfStop, listener)
suspend inline fun <reified E : Event> subscribeUntilFalse(noinline listener: suspend (E) -> Boolean) = E::class.subscribeUntilFalse(listener)
suspend inline fun <reified E : Event> subscribeUntilTrue(noinline listener: suspend (E) -> Boolean) = E::class.subscribeUntilTrue(listener)
suspend inline fun <reified E : Event> subscribeUntilNull(noinline listener: suspend (E) -> Any?) = E::class.subscribeUntilNull(listener)
suspend inline fun <reified E : Event> subscribeUntilFalse(noinline listener: suspend (E) -> Boolean) =
E::class.subscribeUntilFalse(listener)
suspend inline fun <reified E : Event> subscribeUntilTrue(noinline listener: suspend (E) -> Boolean) =
E::class.subscribeUntilTrue(listener)
suspend inline fun <reified E : Event> subscribeUntilNull(noinline listener: suspend (E) -> Any?) =
E::class.subscribeUntilNull(listener)
suspend inline fun <reified E : Event, T> subscribeWhile(valueIfContinue: T, noinline listener: suspend (E) -> T) =
E::class.subscribeWhile(valueIfContinue, listener)
suspend inline fun <reified E : Event> subscribeWhileFalse(noinline listener: suspend (E) -> Boolean) =
E::class.subscribeWhileFalse(listener)
suspend inline fun <reified E : Event> subscribeWhileTrue(noinline listener: suspend (E) -> Boolean) =
E::class.subscribeWhileTrue(listener)
suspend inline fun <reified E : Event> subscribeWhileNull(noinline listener: suspend (E) -> Any?) =
E::class.subscribeWhileNull(listener)
suspend inline fun <reified E : Event, T> subscribeWhile(valueIfContinue: T, noinline listener: suspend (E) -> T) = E::class.subscribeWhile(valueIfContinue, listener)
suspend inline fun <reified E : Event> subscribeWhileFalse(noinline listener: suspend (E) -> Boolean) = E::class.subscribeWhileFalse(listener)
suspend inline fun <reified E : Event> subscribeWhileTrue(noinline listener: suspend (E) -> Boolean) = E::class.subscribeWhileTrue(listener)
suspend inline fun <reified E : Event> subscribeWhileNull(noinline listener: suspend (E) -> Any?) = E::class.subscribeWhileNull(listener)
// endregion
// region KClass 的扩展方法 (不推荐)
suspend fun <E : Event> KClass<E>.subscribe(handler: suspend (E) -> ListeningStatus) =
this.subscribeInternal(Handler(handler))
suspend fun <E : Event> KClass<E>.subscribe(handler: suspend (E) -> ListeningStatus) = this.subscribeInternal(Handler(handler))
suspend fun <E : Event> KClass<E>.subscribeAlways(listener: suspend (E) -> Unit) =
this.subscribeInternal(Handler { listener(it); ListeningStatus.LISTENING })
suspend fun <E : Event> KClass<E>.subscribeAlways(listener: suspend (E) -> Unit) = this.subscribeInternal(Handler { listener(it); ListeningStatus.LISTENING })
suspend fun <E : Event> KClass<E>.subscribeOnce(listener: suspend (E) -> Unit) =
this.subscribeInternal(Handler { listener(it); ListeningStatus.STOPPED })
suspend fun <E : Event> KClass<E>.subscribeOnce(listener: suspend (E) -> Unit) = this.subscribeInternal(Handler { listener(it); ListeningStatus.STOPPED })
suspend fun <E : Event, T> KClass<E>.subscribeUntil(valueIfStop: T, listener: suspend (E) -> T) =
subscribeInternal(Handler { if (listener(it) === valueIfStop) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
suspend fun <E : Event> KClass<E>.subscribeUntilFalse(listener: suspend (E) -> Boolean) =
subscribeUntil(false, listener)
suspend fun <E : Event> KClass<E>.subscribeUntilFalse(listener: suspend (E) -> Boolean) = subscribeUntil(false, listener)
suspend fun <E : Event> KClass<E>.subscribeUntilTrue(listener: suspend (E) -> Boolean) = subscribeUntil(true, listener)
suspend fun <E : Event> KClass<E>.subscribeUntilNull(listener: suspend (E) -> Any?) = subscribeUntil(null, listener)
......@@ -82,9 +60,7 @@ suspend fun <E : Event> KClass<E>.subscribeUntilNull(listener: suspend (E) -> An
suspend fun <E : Event, T> KClass<E>.subscribeWhile(valueIfContinue: T, listener: suspend (E) -> T) =
subscribeInternal(Handler { if (listener(it) !== valueIfContinue) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
suspend fun <E : Event> KClass<E>.subscribeWhileFalse(listener: suspend (E) -> Boolean) =
subscribeWhile(false, listener)
suspend fun <E : Event> KClass<E>.subscribeWhileFalse(listener: suspend (E) -> Boolean) = subscribeWhile(false, listener)
suspend fun <E : Event> KClass<E>.subscribeWhileTrue(listener: suspend (E) -> Boolean) = subscribeWhile(true, listener)
suspend fun <E : Event> KClass<E>.subscribeWhileNull(listener: suspend (E) -> Any?) = subscribeWhile(null, listener)
......@@ -106,8 +82,7 @@ suspend fun <E : Event> KClass<E>.subscribeAll(listeners: suspend ListenerBuilde
* 监听一个事件. 可同时进行多种方式的监听
* @see ListenerBuilder
*/
suspend inline fun <reified E : Event> subscribeAll(noinline listeners: suspend ListenerBuilder<E>.() -> Unit) =
E::class.subscribeAll(listeners)
suspend inline fun <reified E : Event> subscribeAll(noinline listeners: suspend ListenerBuilder<E>.() -> Unit) = E::class.subscribeAll(listeners)
/**
* 监听构建器. 可同时进行多种方式的监听
......@@ -135,17 +110,13 @@ inline class ListenerBuilder<out E : Event>(
suspend fun always(listener: suspend (E) -> Unit) = handler { listener(it); ListeningStatus.LISTENING }
suspend fun <T> until(until: T, listener: suspend (E) -> T) =
handler { if (listener(it) === until) ListeningStatus.STOPPED else ListeningStatus.LISTENING }
suspend fun <T> until(until: T, listener: suspend (E) -> T) = handler { if (listener(it) === until) ListeningStatus.STOPPED else ListeningStatus.LISTENING }
suspend fun untilFalse(listener: suspend (E) -> Boolean) = until(false, listener)
suspend fun untilTrue(listener: suspend (E) -> Boolean) = until(true, listener)
suspend fun untilNull(listener: suspend (E) -> Any?) = until(null, listener)
suspend fun <T> `while`(until: T, listener: suspend (E) -> T) =
handler { if (listener(it) !== until) ListeningStatus.STOPPED else ListeningStatus.LISTENING }
suspend fun <T> `while`(until: T, listener: suspend (E) -> T) = handler { if (listener(it) !== until) ListeningStatus.STOPPED else ListeningStatus.LISTENING }
suspend fun whileFalse(listener: suspend (E) -> Boolean) = `while`(false, listener)
suspend fun whileTrue(listener: suspend (E) -> Boolean) = `while`(true, listener)
suspend fun whileNull(listener: suspend (E) -> Any?) = `while`(null, listener)
......
@file:Suppress("unused")
package net.mamoe.mirai.event
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.internal.HandlerWithBot
import net.mamoe.mirai.event.internal.subscribeInternal
import kotlin.reflect.KClass
/**
* 该文件为所有的含 Bot 的事件的订阅方法
*
* 与不含 bot 的相比, 在监听时将会有 `this: Bot`
* 在 demo 中找到实例可很快了解区别.
*/
// 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 : Event> 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 : 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 : 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)
// endregion
// region KClass 的扩展方法 (不推荐)
suspend fun <E : Event> 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) =
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 })
suspend fun <E : Event, 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)
suspend fun <E : Event, 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)
// endregion
\ No newline at end of file
......@@ -3,6 +3,7 @@ package net.mamoe.mirai.event.internal
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.EventScope
import net.mamoe.mirai.event.ListeningStatus
......@@ -49,18 +50,24 @@ internal suspend fun <E : Event> KClass<E>.subscribeInternal(listener: Listener<
*
* @author Him188moe
*/
internal interface Listener<in E : Event> {
suspend fun onEvent(event: E): ListeningStatus
sealed class Listener<in E : Event> {
abstract suspend fun onEvent(event: E): ListeningStatus
}
/**
* Lambda 监听器.
* 不推荐直接使用该类
*/
class Handler<E : Event>(val handler: suspend (E) -> ListeningStatus) : Listener<E> {
class Handler<E : Event>(val handler: suspend (E) -> ListeningStatus) : Listener<E>() {
override suspend fun onEvent(event: E): ListeningStatus = handler.invoke(event)
}
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)
}
}
/**
* 这个事件类的监听器 list
*/
......@@ -105,7 +112,6 @@ internal object EventListenerManger {
@Suppress("UNCHECKED_CAST")
internal suspend fun <E : Event> E.broadcastInternal(): E {
//FIXME 若一个 listener 阻塞, 则这个事件全部阻塞.
suspend fun callListeners(listeners: EventListeners<in E>) = listeners.mainMutex.withLock {
listeners.inlinedRemoveIf { it.onEvent(this) == ListeningStatus.STOPPED }
}
......
......@@ -91,6 +91,6 @@ class BotSession(
suspend fun BotSession.distributePacket(packet: ServerPacket) = this.socket.distributePacket(packet)
val BotSession.isOpen: Boolean get() = socket.isOpen
val BotSession.qqAccount: UInt get() = bot.account.account
val BotSession.qqAccount: UInt get() = bot.account.id
val <T : BotNetworkHandler<*>> T.session get() = this[ActionPacketHandler].session
\ No newline at end of file
......@@ -4,7 +4,7 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.io.core.*
import net.mamoe.mirai.*
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.ListeningStatus
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BeforePacketSendEvent
......@@ -22,6 +22,7 @@ import net.mamoe.mirai.network.protocol.tim.packet.UnknownServerPacket
import net.mamoe.mirai.network.protocol.tim.packet.event.ServerEventPacket
import net.mamoe.mirai.network.protocol.tim.packet.login.*
import net.mamoe.mirai.network.session
import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.parseServerPacket
import net.mamoe.mirai.utils.io.toUHexString
......@@ -184,7 +185,9 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
packet.decode()
} catch (e: Exception) {
e.log()
bot.printPacketDebugging(packet)
bot.logger.logDebug("Packet=$packet")
bot.logger.logDebug("Packet size=" + packet.input.readBytes().size)
bot.logger.logDebug("Packet data=" + packet.input.readBytes().toUHexString())
packet.close()
throw e
}
......@@ -192,7 +195,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
packet.use {
val name = packet::class.simpleName
if (name != null && !name.endsWith("Encrypted") && !name.endsWith("Raw")) {
bot.logCyan("Packet received: $packet")
bot.logger.logCyan("Packet received: $packet")
}
handlersLock.withLock {
......@@ -258,7 +261,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
}
}
bot.logGreen("Packet sent: $packet")
bot.logger.logGreen("Packet sent: $packet")
PacketSentEvent(bot, packet).broadcast()
......@@ -374,7 +377,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
is ServerCaptchaTransmissionPacket -> {
//packet is ServerCaptchaWrongPacket
if (this.captchaSectionId == 0) {
bot.logError("验证码错误, 请重新输入")
bot.logger.logPurple("验证码错误, 请重新输入")
this.captchaSectionId = 1
this.captchaCache = null
}
......@@ -460,7 +463,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
sessionKey
).sendAndExpect<HeartbeatPacket.Response>().join()
} == null) {
bot.logPurple("Heartbeat timed out")
bot.logger.logPurple("Heartbeat timed out")
bot.reinitializeNetworkHandler(configuration, HeartbeatTimeoutException())
return@launch
}
......
package net.mamoe.mirai.network.protocol.tim.handler
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.GroupId
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.getGroupByNumber
import net.mamoe.mirai.getGroup
import net.mamoe.mirai.getQQ
import net.mamoe.mirai.message.MessageChain
import net.mamoe.mirai.network.BotSession
......@@ -41,11 +42,11 @@ class EventPacketHandler(session: BotSession) : PacketHandler(session) {
}
is ServerGroupMessageEventPacket -> {
if (packet.qq == bot.account.account) return
if (packet.qq == bot.account.id) return
GroupMessageEvent(
bot,
group = bot.getGroupByNumber(packet.groupNumber),
group = bot.getGroup(GroupId(packet.groupNumber)),
sender = bot.getQQ(packet.qq),
message = packet.message,
senderName = packet.senderName,
......@@ -68,10 +69,10 @@ class EventPacketHandler(session: BotSession) : PacketHandler(session) {
}
suspend fun sendFriendMessage(qq: QQ, message: MessageChain) {
session.socket.sendPacket(SendFriendMessagePacket(session.bot.account.account, qq.number, session.sessionKey, message))
session.socket.sendPacket(SendFriendMessagePacket(session.bot.account.id, qq.id, session.sessionKey, message))
}
suspend fun sendGroupMessage(group: Group, message: MessageChain) {
session.socket.sendPacket(SendGroupMessagePacket(session.bot.account.account, group.groupId, session.sessionKey, message))
session.socket.sendPacket(SendGroupMessagePacket(session.bot.account.id, group.internalId, session.sessionKey, message))
}
}
\ No newline at end of file
@file:Suppress("EXPERIMENTAL_API_USAGE")
package net.mamoe.mirai.utils
import net.mamoe.mirai.contact.Contact
class ContactList<C : Contact> : MutableMap<UInt, C> by mutableMapOf()
\ No newline at end of file
@file:Suppress("EXPERIMENTAL_API_USAGE")
package net.mamoe.mirai.contact
import net.mamoe.mirai.Bot
import net.mamoe.mirai.message.MessageChain
import net.mamoe.mirai.network.protocol.tim.handler.EventPacketHandler
import net.mamoe.mirai.utils.ContactList
/**
* 联系人.
*
* A contact is a [QQ] or a [Group] for one particular [Bot] instance only.
*
* @param bot the Owner [Bot]
* @param number the id number of this contact
* @author Him188moe
*/
@Suppress("unused")
actual sealed class Contact actual constructor(bot: Bot, number: UInt) : PlatformContactBase(bot, number) {
abstract override suspend fun sendMessage(message: MessageChain)
abstract override suspend fun sendXMLMessage(message: String)
//
// /**
// * 阻塞发送一个消息. 仅应在 Java 使用
// */
// fun blockingSendMessage(chain: MessageChain) = runBlocking { sendMessage(chain) }
//
// /**
// * 阻塞发送一个消息. 仅应在 Java 使用
// */
// fun blockingSendMessage(message: Message) = runBlocking { sendMessage(message) }
//
// /**
// * 阻塞发送一个消息. 仅应在 Java 使用
// */
// fun blockingSendMessage(plain: String) = runBlocking { sendMessage(plain) }
//
// /**
// * 异步发送一个消息. 仅应在 Java 使用
// */
// fun asyncSendMessage(chain: MessageChain) = bot.network.launch { sendMessage(chain) }
//
// /**
// * 异步发送一个消息. 仅应在 Java 使用
// */
// fun asyncSendMessage(message: Message) = bot.network.launch { sendMessage(message) }
//
// /**
// * 异步发送一个消息. 仅应在 Java 使用
// */
// fun asyncSendMessage(plain: String) = bot.network.launch { sendMessage(plain) }
}
/**
* 群.
*
* Group ID 与 Group Number 并不是同一个值.
* - Group Number([Group.number]) 是通常使用的群号码.(在 QQ 客户端中可见)
* - Group ID([Group.groupId]) 是与服务器通讯时使用的 id.(在 QQ 客户端中不可见)
*
* Java 获取 groupNumber: `group.getNumber()`
* Java 获取所属 bot: `group.getBot()`
* Java 获取群成员列表: `group.getMembers()`
* Java 获取 groupId: `group.getGroupId()`
*
* Java 调用 [groupNumberToId] : `Group.groupNumberToId(number)`
* @author Him188moe
*/
actual class Group actual constructor(bot: Bot, number: UInt) : Contact(bot, number) {
actual val groupId = groupNumberToId(number)
actual val members: ContactList<QQ>
//todo members
get() = throw UnsupportedOperationException("Not yet supported")
actual override suspend fun sendMessage(message: MessageChain) {
bot.network[EventPacketHandler].sendGroupMessage(this, message)
}
actual override suspend fun sendXMLMessage(message: String) {
}
actual companion object
}
/**
* QQ 账号.
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Bot].
*
* Java 获取 qq 号: `qq.getNumber()`
* Java 获取所属 bot: `qq.getBot()`
*
* A QQ instance helps you to receive event from or sendPacket event to.
* Notice that, one QQ instance belong to one [Bot], that is, QQ instances from different [Bot] are NOT the same.
*
* @author Him188moe
*/
actual class QQ actual constructor(bot: Bot, number: UInt) : Contact(bot, number) {
actual override suspend fun sendMessage(message: MessageChain) {
bot.network[EventPacketHandler].sendFriendMessage(this, message)
}
actual override suspend fun sendXMLMessage(message: String) {
TODO()
}
}
\ No newline at end of file
......@@ -2,11 +2,11 @@
package demo1
import kotlinx.coroutines.*
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.withTimeoutOrNull
import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.event.subscribeAll
......@@ -24,7 +24,6 @@ import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.toUHexString
import java.io.File
import javax.imageio.ImageIO
private fun readTestAccount(): BotAccount? {
val file = File("testAccount.txt")
......@@ -42,10 +41,12 @@ private fun readTestAccount(): BotAccount? {
@Suppress("UNUSED_VARIABLE")
suspend fun main() = coroutineScope {
val bot = Bot(readTestAccount() ?: BotAccount(//填写你的账号
account = 1994701121u,
val bot = Bot(
readTestAccount() ?: BotAccount(//填写你的账号
id = 1994701121u,
password = "123456"
), PlatformLogger())
), PlatformLogger()
)
bot.login {
randomDeviceName = false
......@@ -57,18 +58,22 @@ suspend fun main() = coroutineScope {
}
subscribeAlways<GroupMessageEvent> {
if (it.message eq "复读" && it.group.groupId == 580266363u) {
if (it.message eq "复读" && it.group.internalId == 580266363u) {
it.reply(it.message)
}
}
//提供泛型以监听事件
subscribeAlways<FriendMessageEvent> {
//获取第一个纯文本消息, 获取不到会抛出 NoSuchElementException
//val firstText = it.message.first<PlainText>()
// 使用 Bot 的扩展方法监听, 将在处理事件时得到一个 this: Bot.
// 这样可以很方便地调用 Bot 内的一些扩展方法如 UInt.qq():QQ
bot.subscribeAlways<FriendMessageEvent> {
// this: Bot
// it: FriendMessageEvent
// 获取第一个纯文本消息, 获取不到会抛出 NoSuchElementException
// val firstText = it.message.first<PlainText>()
val firstText = it.message.firstOrNull<PlainText>()
//获取第一个图片
// 获取第一个图片
val firstImage = it.message.firstOrNull<Image>()
when {
......@@ -76,32 +81,43 @@ suspend fun main() = coroutineScope {
"复读" in it.message -> it.sender.sendMessage(it.message)
"发群消息" in it.message -> Group(bot, 580266363u).sendMessage(it.message.toString().substringAfter("发群消息"))
"发群消息" in it.message -> 580266363u.group().sendMessage(it.message.toString().substringAfter("发群消息"))
"直接发送包" in it.message -> {
val d = ("01 " + 1994701021u.toByteArray().toUHexString() + " 3E 03 3F A2 00 00 02 BB 00 0A 00 01 00 01 00 5E 4F 53 52 6F 6F 74 3A 43 3A 5C 55 73 65 72 73 5C 48 69 6D 31 38 5C 44 6F 63 75 6D 65 6E 74 73 5C 54 65 6E 63 65 6E 74 20 46 69 6C 65 73 5C 31 30 34 30 34 30 30 32 39 30 5C 49 6D 61 67 65 5C 43 32 43 5C 7B 47 47 42 7E 49 31 5A 4D 43 28 25 49 4D 5A 5F 47 55 51 36 35 5D 51 2E 6A 70 67 00 00 04 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 35 02")
val d =
("01 " + 1994701021u.toByteArray().toUHexString() + " 3E 03 3F A2 00 00 02 BB 00 0A 00 01 00 01 00 5E 4F 53 52 6F 6F 74 3A 43 3A 5C 55 73 65 72 73 5C 48 69 6D 31 38 5C 44 6F 63 75 6D 65 6E 74 73 5C 54 65 6E 63 65 6E 74 20 46 69 6C 65 73 5C 31 30 34 30 34 30 30 32 39 30 5C 49 6D 61 67 65 5C 43 32 43 5C 7B 47 47 42 7E 49 31 5A 4D 43 28 25 49 4D 5A 5F 47 55 51 36 35 5D 51 2E 6A 70 67 00 00 04 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 35 02")
.hexToBytes()
it.bot.network.socket.sendPacket(OutgoingRawPacket(0x01_BDu, it.bot.qqAccount, "00 00 00 01 2E 01 00 00 69 35".hexToBytes(), it.bot.network.session.sessionKey, d))
it.bot.network.socket.sendPacket(
OutgoingRawPacket(
0x01_BDu,
it.bot.qqAccount,
"00 00 00 01 2E 01 00 00 69 35".hexToBytes(),
it.bot.network.session.sessionKey,
d
)
)
}
"上传好友图片" in it.message -> withTimeoutOrNull(5000) {
val id = QQ(bot, 1040400290u)
.uploadImage(withContext(Dispatchers.IO) { ImageIO.read(File("C:\\Users\\Him18\\Desktop\\${it.message.toString().substringAfter("上传好友图片")}").inputStream()) }.toMiraiImage("gif"))
val id = 1040400290u.qq()
.uploadImage(File("C:\\Users\\Him18\\Desktop\\${it.message.toString().substringAfter("上传好友图片")}").toMiraiImage())
it.reply(id.value)
delay(1000)
it.reply(Image(id))
}
"上传群图片" in it.message -> withTimeoutOrNull(5000) {
val image = withContext(Dispatchers.IO) { ImageIO.read(File("C:\\Users\\Him18\\Desktop\\${it.message.toString().substringAfter("上传群图片")}").inputStream()) }.toMiraiImage("gif")
Group(bot, 580266363u).uploadImage(image)
val image = File(
"C:\\Users\\Him18\\Desktop\\${it.message.toString().substringAfter("上传群图片")}"
).toMiraiImage()
580266363u.group().uploadImage(image)
it.reply(image.groupImageId.value)
delay(1000)
Group(bot, 580266363u).sendMessage(Image(image.groupImageId))
580266363u.group().sendMessage(Image(image.groupImageId))
}
"发群图片" in it.message -> {
Group(bot, 580266363u).sendMessage(Image(ImageId(it.message.toString().substringAfter("发群图片"))))
580266363u.group().sendMessage(Image(ImageId(it.message.toString().substringAfter("发群图片"))))
}
"发好友图片" in it.message -> {
......@@ -112,12 +128,15 @@ suspend fun main() = coroutineScope {
image.upload(session, Group(session.bot, 580266363)).of()
})*/
it.message eq "发图片群2" -> Group(bot, 580266363u).sendMessage(Image(ImageId("{7AA4B3AA-8C3C-0F45-2D9B-7F302A0ACEAA}.jpg")))
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.message eq "发图片2" -> it.reply(PlainText("test") + Image(ImageId("{7AA4B3AA-8C3C-0F45-2D9B-7F302A0ACEAA}.jpg")))
else -> {
}
}
}
......
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