Commit 82707d5e authored by Him188's avatar Him188

Update docs

parent 5bf1ecb4
...@@ -160,6 +160,7 @@ inline class MessageSubscribersBuilder<T : SenderAndMessage>( ...@@ -160,6 +160,7 @@ inline class MessageSubscribersBuilder<T : SenderAndMessage>(
suspend inline fun replyStartsWith(value: String, noinline replier: MessageReplier<T>) = content({ it.startsWith(value) }) { 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) } suspend infix fun String.reply(reply: String) = case(this) { this.reply(reply) }
suspend infix fun String.reply(reply: MessageReplier<T>) = case(this) { this.reply(reply(this)) }
} }
......
...@@ -15,7 +15,7 @@ import net.mamoe.mirai.network.protocol.tim.packet.event.ServerEventPacket ...@@ -15,7 +15,7 @@ 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.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.io.PlatformDatagramChannel
/** /**
* Mirai 的网络处理器, 它承担所有数据包([Packet])的处理任务. * Mirai 的网络处理器, 它承担所有数据包([Packet])的处理任务.
......
...@@ -71,6 +71,7 @@ class BotSession( ...@@ -71,6 +71,7 @@ class BotSession(
* } * }
* } * }
* ``` * ```
* @sample net.mamoe.mirai.network.protocol.tim.packet.action.uploadImage
* *
* @param P 期待的包 * @param P 期待的包
* @param handler 处理期待的包 * @param handler 处理期待的包
...@@ -89,9 +90,9 @@ class BotSession( ...@@ -89,9 +90,9 @@ class BotSession(
/** /**
* 发送一个数据包, 并期待接受一个特定的 [ServerPacket][P]. * 发送一个数据包, 并期待接受一个特定的 [ServerPacket][P].
* 您将能从本函数的返回值 [CompletableDeferred] 接收到所期待的 [P]
*/ */
suspend inline fun <reified P : ServerPacket> OutgoingPacket.sendAndExpect(): CompletableDeferred<Unit> = suspend inline fun <reified P : ServerPacket> OutgoingPacket.sendAndExpect(): CompletableDeferred<P> = sendAndExpect<P, P> { it }
sendAndExpect<P, Unit> {}
suspend inline fun OutgoingPacket.send() = socket.sendPacket(this) suspend inline fun OutgoingPacket.send() = socket.sendPacket(this)
} }
...@@ -105,4 +106,4 @@ inline val BotSession.qqAccount: UInt get() = bot.account.id ...@@ -105,4 +106,4 @@ inline val BotSession.qqAccount: UInt get() = bot.account.id
* 取得 [T] 的 [BotSession]. * 取得 [T] 的 [BotSession].
* 实际上是一个捷径. * 实际上是一个捷径.
*/ */
inline val <T : BotNetworkHandler<*>> T.session get() = this[ActionPacketHandler].session val <T : BotNetworkHandler<*>> T.session get() = this[ActionPacketHandler].session
\ No newline at end of file \ No newline at end of file
...@@ -25,8 +25,7 @@ import net.mamoe.mirai.network.session ...@@ -25,8 +25,7 @@ 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.*
import net.mamoe.mirai.utils.internal.inlinedRemoveIf import net.mamoe.mirai.utils.internal.inlinedRemoveIf
import net.mamoe.mirai.utils.io.parseServerPacket import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.io.toUHexString
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
/** /**
...@@ -128,22 +127,24 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) : ...@@ -128,22 +127,24 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
val buffer = IoBuffer.Pool.borrow() val buffer = IoBuffer.Pool.borrow()
try { try {
channel.read(buffer)//JVM: withContext(IO) channel.read(buffer)// JVM: withContext(IO)
} catch (e: ReadPacketInternalException) { } catch (e: ReadPacketInternalException) {
//read failed, continue and reread // read failed, continue and reread
continue continue
} catch (e: Throwable) { } catch (e: Throwable) {
e.log()//other unexpected exceptions caught. e.log()// other unexpected exceptions caught.
continue continue
} finally {
if (!buffer.canRead() || buffer.readRemaining == 0) {//size==0
buffer.release(IoBuffer.Pool)
continue
}// sometimes exceptions are thrown without this `if` clause
} }
if (!buffer.canRead() || buffer.readRemaining == 0) {//size==0
buffer.release(IoBuffer.Pool)
continue
}
launch { launch {
//`.use`: Ensure that the packet is consumed totally so that all the buffers are released // `.use`: Ensure that the packet is consumed **totally**
// so that all the buffers are released
ByteReadPacket(buffer, IoBuffer.Pool).use { ByteReadPacket(buffer, IoBuffer.Pool).use {
distributePacket(it.parseServerPacket(buffer.readRemaining)) distributePacket(it.parseServerPacket(buffer.readRemaining))
} }
...@@ -306,7 +307,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) : ...@@ -306,7 +307,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
field = value field = value
} }
suspend fun onPacketReceived(packet: ServerPacket) { suspend fun onPacketReceived(packet: ServerPacket) {//complex function, but it doesn't matter
when (packet) { when (packet) {
is TouchResponsePacket -> { is TouchResponsePacket -> {
if (packet.serverIP != null) {//redirection if (packet.serverIP != null) {//redirection
......
...@@ -7,7 +7,7 @@ import net.mamoe.mirai.network.BotSession ...@@ -7,7 +7,7 @@ import net.mamoe.mirai.network.BotSession
import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler
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.ServerPacket import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import net.mamoe.mirai.utils.PlatformDatagramChannel import net.mamoe.mirai.utils.io.PlatformDatagramChannel
/** /**
* 网络接口. * 网络接口.
...@@ -19,6 +19,10 @@ import net.mamoe.mirai.utils.PlatformDatagramChannel ...@@ -19,6 +19,10 @@ import net.mamoe.mirai.utils.PlatformDatagramChannel
interface DataPacketSocketAdapter : Closeable { interface DataPacketSocketAdapter : Closeable {
val owner: Bot val owner: Bot
/**
* 连接的服务器的 IPv4 地址
* 在整个过程中都不会变化. 若连接丢失, [DataPacketSocketAdapter] 将会被 [close]
*/
val serverIp: String val serverIp: String
/** /**
......
package net.mamoe.mirai.network.protocol.tim.packet
import kotlin.reflect.KClass
/**
* 标记一个 [OutgoingPacket] 的服务器回复包.
* 在这个包发送时将会记录回复包信息.
* 收到回复包时将解密为指定的包
*
*
* // TODO: 2019/10/27 暂未实现. 计划中
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
annotation class Response(
val responseClass: KClass<out ResponsePacket>
)
\ No newline at end of file
...@@ -17,6 +17,7 @@ import net.mamoe.mirai.utils.io.writeQQ ...@@ -17,6 +17,7 @@ import net.mamoe.mirai.utils.io.writeQQ
* *
* @author Him188moe * @author Him188moe
*/ */
@Response(CanAddFriendPacket.Response::class)
@PacketId(0x00_A7u) @PacketId(0x00_A7u)
class CanAddFriendPacket( class CanAddFriendPacket(
val bot: UInt, val bot: UInt,
......
...@@ -29,30 +29,31 @@ import net.mamoe.mirai.withSession ...@@ -29,30 +29,31 @@ import net.mamoe.mirai.withSession
* @throws OverFileSizeMaxException 如果文件过大, 服务器拒绝接收时 * @throws OverFileSizeMaxException 如果文件过大, 服务器拒绝接收时
*/ */
suspend fun QQ.uploadImage(image: ExternalImage): ImageId = bot.withSession { suspend fun QQ.uploadImage(image: ExternalImage): ImageId = bot.withSession {
FriendImageIdRequestPacket(qqAccount, sessionKey, id, image).sendAndExpect<FriendImageIdRequestPacket.Response, ImageId> { FriendImageIdRequestPacket(qqAccount, sessionKey, id, image)
when (it.state) { .sendAndExpect<FriendImageIdRequestPacket.Response, ImageId> {
REQUIRE_UPLOAD -> { when (it.state) {
require( REQUIRE_UPLOAD -> {
httpPostFriendImage( require(
botAccount = bot.qqAccount, httpPostFriendImage(
uKeyHex = it.uKey!!.toUHexString(""), botAccount = bot.qqAccount,
imageInput = image.input, uKeyHex = it.uKey!!.toUHexString(""),
inputSize = image.inputSize imageInput = image.input,
inputSize = image.inputSize
)
) )
) }
}
ALREADY_EXISTS -> { ALREADY_EXISTS -> {
} }
OVER_FILE_SIZE_MAX -> { OVER_FILE_SIZE_MAX -> {
throw OverFileSizeMaxException() throw OverFileSizeMaxException()
}
} }
}
it.imageId!! it.imageId!!
}.await() }.await()
} }
//fixVer2=00 00 00 01 2E 01 00 00 69 35 //fixVer2=00 00 00 01 2E 01 00 00 69 35
......
package net.mamoe.mirai.utils package net.mamoe.mirai.utils.io
import kotlinx.io.core.Closeable import kotlinx.io.core.Closeable
import kotlinx.io.core.IoBuffer import kotlinx.io.core.IoBuffer
...@@ -8,6 +8,9 @@ import kotlinx.io.errors.IOException ...@@ -8,6 +8,9 @@ import kotlinx.io.errors.IOException
* 多平台适配的 DatagramChannel. * 多平台适配的 DatagramChannel.
*/ */
expect class PlatformDatagramChannel(serverHost: String, serverPort: Short) : Closeable { expect class PlatformDatagramChannel(serverHost: String, serverPort: Short) : Closeable {
// TODO: 2019/10/27 使用 Ktor 的 socket
suspend fun read(buffer: IoBuffer): Int suspend fun read(buffer: IoBuffer): Int
suspend fun send(buffer: IoBuffer): Int suspend fun send(buffer: IoBuffer): Int
......
package net.mamoe.mirai.utils package net.mamoe.mirai.utils.io
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
......
...@@ -4,8 +4,7 @@ package demo.gentleman ...@@ -4,8 +4,7 @@ package demo.gentleman
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.subscribeMessages
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.login import net.mamoe.mirai.login
import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess
import java.io.File import java.io.File
...@@ -27,19 +26,21 @@ private fun readTestAccount(): BotAccount? { ...@@ -27,19 +26,21 @@ private fun readTestAccount(): BotAccount? {
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
suspend fun main() { suspend fun main() {
val bot = Bot( val bot = Bot(
readTestAccount() ?: BotAccount( //readTestAccount() ?: BotAccount(
id = 1994701121u, qq = 1994701121u,
password = "123456" password = "123456"
) // )
) )
val bot2 = Bot(1994701121u, "").apply { login().requireSuccess() }
bot.login().requireSuccess() bot.login().requireSuccess()
bot.subscribeAlways<FriendMessageEvent> { bot.subscribeMessages {
contains("") {
}
} }
bot.network.awaitDisconnection()//等到直到断开连接 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