Commit 47ece90d authored by Him188's avatar Him188

Update docs

parent 490255bc
...@@ -21,14 +21,15 @@ suspend inline fun Bot.getGroup(id: GroupId): Group = this.contacts.getGroup(id) ...@@ -21,14 +21,15 @@ suspend inline fun Bot.getGroup(id: GroupId): Group = this.contacts.getGroup(id)
suspend inline fun Bot.getGroup(internalId: GroupInternalId): Group = this.contacts.getGroup(internalId) suspend inline fun Bot.getGroup(internalId: GroupInternalId): Group = this.contacts.getGroup(internalId)
/** /**
* 取得机器人的群成员列表. 当机器人登录后成员列表就会 * 取得机器人的群成员列表
*/ */
@Suppress("WRONG_MODIFIER_TARGET") inline val Bot.groups: ContactList<Group>
suspend inline val Bot.groups: ContactList<Group>
get() = this.contacts.groups get() = this.contacts.groups
@Suppress("WRONG_MODIFIER_TARGET") /**
suspend inline val Bot.qqs: ContactList<QQ> * 取得机器人的好友列表
*/
inline val Bot.qqs: ContactList<QQ>
get() = this.contacts.qqs get() = this.contacts.qqs
/** /**
...@@ -53,5 +54,7 @@ suspend inline fun Bot.login(noinline configuration: BotNetworkConfiguration.() ...@@ -53,5 +54,7 @@ suspend inline fun Bot.login(noinline configuration: BotNetworkConfiguration.()
*/ */
suspend inline fun Bot.login(): LoginResult = this.network.login(BotNetworkConfiguration.Default) suspend inline fun Bot.login(): LoginResult = this.network.login(BotNetworkConfiguration.Default)
//BotAccount /**
* 取得机器人的 QQ 号
*/
inline val Bot.qqAccount: UInt get() = this.account.id inline val Bot.qqAccount: UInt get() = this.account.id
\ No newline at end of file
...@@ -2,6 +2,7 @@ package net.mamoe.mirai.network ...@@ -2,6 +2,7 @@ package net.mamoe.mirai.network
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.cancelChildren
import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.BotSocketAdapter import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.BotSocketAdapter
import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.LoginHandler import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler.LoginHandler
...@@ -10,10 +11,11 @@ import net.mamoe.mirai.network.protocol.tim.packet.HeartbeatPacket ...@@ -10,10 +11,11 @@ import net.mamoe.mirai.network.protocol.tim.packet.HeartbeatPacket
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
import net.mamoe.mirai.network.protocol.tim.packet.Packet import net.mamoe.mirai.network.protocol.tim.packet.Packet
import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import net.mamoe.mirai.network.protocol.tim.packet.event.ServerEventPacket
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import net.mamoe.mirai.network.protocol.tim.packet.login.RequestSKeyPacket
import net.mamoe.mirai.utils.BotNetworkConfiguration import net.mamoe.mirai.utils.BotNetworkConfiguration
import net.mamoe.mirai.utils.PlatformDatagramChannel import net.mamoe.mirai.utils.PlatformDatagramChannel
import kotlin.coroutines.ContinuationInterceptor
/** /**
* Mirai 的网络处理器, 它承担所有数据包([Packet])的处理任务. * Mirai 的网络处理器, 它承担所有数据包([Packet])的处理任务.
...@@ -36,7 +38,7 @@ import kotlin.coroutines.ContinuationInterceptor ...@@ -36,7 +38,7 @@ import kotlin.coroutines.ContinuationInterceptor
* [BotNetworkHandler] 的协程包含: * [BotNetworkHandler] 的协程包含:
* - UDP 包接收: [PlatformDatagramChannel.read] * - UDP 包接收: [PlatformDatagramChannel.read]
* - 心跳 Job [HeartbeatPacket] * - 心跳 Job [HeartbeatPacket]
* - SKey 刷新 [ReuestSKeyPcket] * - SKey 刷新 [RequestSKeyPacket]
* - 所有数据包处理和发送 * - 所有数据包处理和发送
* *
* [BotNetworkHandler.close] 时将会 [取消][kotlin.coroutines.CoroutineContext.cancelChildren] 所有此作用域下的协程 * [BotNetworkHandler.close] 时将会 [取消][kotlin.coroutines.CoroutineContext.cancelChildren] 所有此作用域下的协程
...@@ -58,6 +60,7 @@ interface BotNetworkHandler<Socket : DataPacketSocketAdapter> : CoroutineScope { ...@@ -58,6 +60,7 @@ interface BotNetworkHandler<Socket : DataPacketSocketAdapter> : CoroutineScope {
/** /**
* 依次尝试登录到可用的服务器. 在任一服务器登录完成后返回登录结果 * 依次尝试登录到可用的服务器. 在任一服务器登录完成后返回登录结果
* 本函数将挂起直到登录成功.
*/ */
suspend fun login(configuration: BotNetworkConfiguration): LoginResult suspend fun login(configuration: BotNetworkConfiguration): LoginResult
...@@ -79,8 +82,11 @@ interface BotNetworkHandler<Socket : DataPacketSocketAdapter> : CoroutineScope { ...@@ -79,8 +82,11 @@ interface BotNetworkHandler<Socket : DataPacketSocketAdapter> : CoroutineScope {
*/ */
suspend fun awaitDisconnection() suspend fun awaitDisconnection()
/**
* 关闭网络接口, 停止所有有关协程和任务
*/
suspend fun close(cause: Throwable? = null) { suspend fun close(cause: Throwable? = null) {
//todo check?? //todo check??
coroutineContext[ContinuationInterceptor]!!.cancelChildren(CancellationException("handler closed", cause)) coroutineContext[Job]!!.cancelChildren(CancellationException("handler closed", cause))
} }
} }
\ No newline at end of file
package net.mamoe.mirai.network.protocol.tim.packet.login package net.mamoe.mirai.network.protocol.tim.packet.login
/**
* 登录结果. 除 [SUCCESS] 外均为失败.
* @see LoginResult.requireSuccess 要求成功
*/
enum class LoginResult { enum class LoginResult {
/** /**
* 登录成功 * 登录成功
...@@ -46,3 +50,18 @@ enum class LoginResult { ...@@ -46,3 +50,18 @@ enum class LoginResult {
*/ */
TIMEOUT, TIMEOUT,
} }
/**
* 如果 [this] 不为 [LoginResult.SUCCESS] 就抛出消息为 [lazyMessage] 的 [IllegalStateException]
*/
fun LoginResult.requireSuccess(lazyMessage: (LoginResult) -> String) {
if (this != LoginResult.SUCCESS) error(lazyMessage(this))
}
/**
* 如果 [this] 不为 [LoginResult.SUCCESS] 就抛出消息为 "Login failed $this" 的 [IllegalStateException]
*/
fun LoginResult.requireSuccess() {
if (this != LoginResult.SUCCESS) error("Login failed: $this")
}
\ No newline at end of file
...@@ -18,11 +18,13 @@ import net.mamoe.mirai.message.PlainText ...@@ -18,11 +18,13 @@ import net.mamoe.mirai.message.PlainText
import net.mamoe.mirai.message.firstOrNull import net.mamoe.mirai.message.firstOrNull
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingRawPacket 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.action.uploadImage
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess
import net.mamoe.mirai.network.session import net.mamoe.mirai.network.session
import net.mamoe.mirai.qqAccount import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.hexToBytes
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.io.toUHexString
import net.mamoe.mirai.utils.toByteArray
import net.mamoe.mirai.utils.toExternalImage
import java.io.File import java.io.File
private fun readTestAccount(): BotAccount? { private fun readTestAccount(): BotAccount? {
...@@ -45,17 +47,13 @@ suspend fun main() { ...@@ -45,17 +47,13 @@ suspend fun main() {
readTestAccount() ?: BotAccount(//填写你的账号 readTestAccount() ?: BotAccount(//填写你的账号
id = 1994701121u, id = 1994701121u,
password = "123456" password = "123456"
), PlatformLogger() )
) )
// 覆盖默认的配置
bot.login { bot.login {
randomDeviceName = false randomDeviceName = false
}.let { }.requireSuccess()
if (it != LoginResult.SUCCESS) {
MiraiLogger.logError("Login failed: " + it.name)
bot.close()
}
}
subscribeAlways<GroupMessageEvent> { subscribeAlways<GroupMessageEvent> {
if (it.message eq "复读" && it.group.internalId.value == 580266363u) { if (it.message eq "复读" && it.group.internalId.value == 580266363u) {
......
...@@ -2,30 +2,10 @@ ...@@ -2,30 +2,10 @@
package demo1 package demo1
import kotlinx.coroutines.delay
import kotlinx.coroutines.withTimeoutOrNull
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotAccount import net.mamoe.mirai.BotAccount
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.login
import net.mamoe.mirai.message.Image import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess
import net.mamoe.mirai.message.ImageId
import net.mamoe.mirai.message.PlainText
import net.mamoe.mirai.message.firstOrNull
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.LoginResult
import net.mamoe.mirai.network.session
import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.hexToBytes
import net.mamoe.mirai.utils.io.toUHexString
import net.mamoe.mirai.utils.toByteArray
import net.mamoe.mirai.utils.toExternalImage
import java.io.File import java.io.File
private fun readTestAccount(): BotAccount? { private fun readTestAccount(): BotAccount? {
...@@ -51,129 +31,7 @@ suspend fun main() { ...@@ -51,129 +31,7 @@ suspend fun main() {
) )
) )
bot.login { bot.login().requireSuccess()
randomDeviceName = false
}.let {
if (it != LoginResult.SUCCESS) {
MiraiLogger.logError("Login failed: " + it.name)
bot.close()
}
}
subscribeAlways<GroupMessageEvent> {
if (it.message eq "复读" && it.group.internalId.value == 580266363u) {
it.reply(it.message)
}
}
// 使用 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 {
it.message eq "你好" -> it.reply("你好!")
"复读" in it.message -> it.sender.sendMessage(it.message)
"发群消息" 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")
.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
)
)
}
"上传好友图片" 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(
"C:\\Users\\Him18\\Desktop\\$filename"
).toExternalImage()
920503456u.group().uploadImage(image)
it.reply(image.groupImageId.value)
delay(100)
920503456u.group().sendMessage(Image(image.groupImageId))
}
"发群图片" in it.message -> {
920503456u.group().sendMessage(Image(ImageId(it.message.toString().substringAfter("发群图片"))))
}
"发好友图片" in it.message -> {
it.reply(Image(ImageId(it.message.toString().substringAfter("发好友图片"))))
}
/*it.event eq "发图片群" -> sendGroupMessage(Group(session.bot, 580266363), PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
image.upload(session, Group(session.bot, 580266363)).of()
})*/
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 -> {
}
}
}
//DSL 监听
subscribeAll<FriendMessageEvent> {
always {
//获取第一个纯文本消息
val firstText = it.message.firstOrNull<PlainText>()
}
}
demo2()
bot.network.awaitDisconnection()//等到直到断开连接 bot.network.awaitDisconnection()//等到直到断开连接
} }
\ No newline at end of file
/**
* 实现功能:
* 对机器人说 "记笔记", 机器人记录之后的所有消息.
* 对机器人说 "停止", 机器人停止
*/
suspend fun demo2() {
subscribeAlways<FriendMessageEvent> { event ->
if (event.message eq "记笔记") {
subscribeUntilFalse<FriendMessageEvent> {
it.reply("你发送了 ${it.message}")
it.message eq "停止"
}
}
}
}
\ 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