mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-15 13:00:12 +08:00
Generify packet consumer
This commit is contained in:
parent
849519afc6
commit
c17c736054
@ -13,6 +13,7 @@ import net.mamoe.mirai.qqandroid.QQAndroidBot
|
|||||||
import net.mamoe.mirai.qqandroid.event.PacketReceivedEvent
|
import net.mamoe.mirai.qqandroid.event.PacketReceivedEvent
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.KnownPacketFactories
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.KnownPacketFactories
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
|
||||||
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket.LoginPacketResponse.*
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket.LoginPacketResponse.*
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
|
||||||
@ -20,6 +21,7 @@ import net.mamoe.mirai.utils.*
|
|||||||
import net.mamoe.mirai.utils.io.*
|
import net.mamoe.mirai.utils.io.*
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
@UseExperimental(MiraiInternalAPI::class)
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler() {
|
internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler() {
|
||||||
override val bot: QQAndroidBot by bot.unsafeWeakRef()
|
override val bot: QQAndroidBot by bot.unsafeWeakRef()
|
||||||
@ -145,18 +147,20 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
*/
|
*/
|
||||||
suspend fun parsePacket(input: Input) {
|
suspend fun parsePacket(input: Input) {
|
||||||
try {
|
try {
|
||||||
KnownPacketFactories.parseIncomingPacket(bot, input) { packet: Packet, commandName: String, sequenceId: Int ->
|
KnownPacketFactories.parseIncomingPacket(bot, input) { packetFactory: PacketFactory<Packet>, packet: Packet, commandName: String, sequenceId: Int ->
|
||||||
if (PacketReceivedEvent(packet).broadcast().cancelled) {
|
// highest priority: pass to listeners (attached by sendAndExpect).
|
||||||
return@parseIncomingPacket
|
|
||||||
}
|
|
||||||
|
|
||||||
// pass to listeners (attached by sendAndExpect).
|
|
||||||
packetListeners.forEach { listener ->
|
packetListeners.forEach { listener ->
|
||||||
if (listener.filter(commandName, sequenceId) && packetListeners.remove(listener)) {
|
if (listener.filter(commandName, sequenceId) && packetListeners.remove(listener)) {
|
||||||
listener.complete(packet)
|
listener.complete(packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check top-level cancelling
|
||||||
|
if (PacketReceivedEvent(packet).broadcast().cancelled) {
|
||||||
|
return@parseIncomingPacket
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// broadcast
|
// broadcast
|
||||||
if (packet is Subscribable) {
|
if (packet is Subscribable) {
|
||||||
if (packet is BroadcastControllable) {
|
if (packet is BroadcastControllable) {
|
||||||
@ -168,6 +172,8 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
if (packet is Cancellable && packet.cancelled) return@parseIncomingPacket
|
if (packet is Cancellable && packet.cancelled) return@parseIncomingPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
packetFactory.run { packet.handle(bot) }
|
||||||
|
|
||||||
bot.logger.info(packet)
|
bot.logger.info(packet)
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -7,8 +7,6 @@ import kotlinx.io.core.buildPacket
|
|||||||
import kotlinx.io.core.writeFully
|
import kotlinx.io.core.writeFully
|
||||||
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||||
import net.mamoe.mirai.utils.cryptor.DecrypterByteArray
|
|
||||||
import net.mamoe.mirai.utils.cryptor.encryptAndWrite
|
|
||||||
import net.mamoe.mirai.utils.io.encryptAndWrite
|
import net.mamoe.mirai.utils.io.encryptAndWrite
|
||||||
import net.mamoe.mirai.utils.io.writeHex
|
import net.mamoe.mirai.utils.io.writeHex
|
||||||
import net.mamoe.mirai.utils.io.writeIntLVPacket
|
import net.mamoe.mirai.utils.io.writeIntLVPacket
|
||||||
@ -50,22 +48,13 @@ internal val EMPTY_BYTE_ARRAY = ByteArray(0)
|
|||||||
*
|
*
|
||||||
* byte[] body encrypted by 16 zero
|
* byte[] body encrypted by 16 zero
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* 00 00 02 34 // remaining.length + 4
|
|
||||||
* 00 00 00 0B
|
|
||||||
* 01
|
|
||||||
* 00 01 4E 73 // sequence
|
|
||||||
* 00
|
|
||||||
* 00 00 00 0E
|
|
||||||
* 31 39 39 34 37 30 31 30 32 31
|
|
||||||
* 18 5D 8F 17 7D 67 71 61 FE DB 30 A4 4D 16 DD 0E 8D 84 0A F2 44 BE FB BB 11 BB B4 AC 79 50 50 9F 4C 99 CC 77 0B AA B6 E0 06 0C F7 91 79 99 57 31 3D EF 38 92 2C C8 81 33 79 83 FF C6 2F BA 18 2A 33 F8 D9 4E CD 62 07 D8 08 B7 1A 1E C7 EB AC AB B4 1E C9 9D A9 15 9C 29 29 2A 99 F6 BB D0 43 65 D6 5E 9C 93 A8 8D 17 08 5B 6A 29 92 58 6A 75 C9 B5 45 B3 0E A5 D3 52 8F 9A A4 88 36 A0 14 3A 21 F2 46 C3 91 66 A3 73 67 6A 3E F7 9D 8E 44 52 87 7B 8A C7 1B E2 D3 98 62 E8 25 30 2A 43 5C 5A B2 C6 45 F5 39 EC 85 81 BF 7D 22 4C E8 01 87 92 48 38 06 6B A0 83 70 0B 51 ED CF 7A FF E2 F2 06 3E A7 95 4E E5 29 23 32 1C FE 79 C6 08 C5 7A 39 B9 AF CD 4F 80 3E 5D 74 4D 0B E1 10 33 8D F0 54 8E 0E 22 96 B4 06 7F 29 01 1E CA 30 35 FD 8A 2E 51 04 20 79 7B 08 DC DF F6 64 21 6B C5 95 34 B3 40 D2 E8 CE BB DC 69 89 75 62 A6 0B 4A 49 9D 90 BA 68 2B BD 8A 50 2D 68 6B 56 40 0C 39 F2 08 20 1B EB A4 A5 20 1D 1F 7E FA 4B B8 2E 58 79 2A 16 54 26 6C C8 44 6C 4F 64 2D 5C 0C 47 2E 90 13 A9 D7 33 4A 51 17 6E 3F 3E 48 AE 39 D8 45 05 2C 0C 3C 9F 92 39 DB 62 B3 BB 64 EE 7E 91 C5 84 92 10 96 D9 F1 13 02 94 00 EA DA 87 7C 85 7B 68 BA 8D A1 AB F5 CD 9C EB 4C CD A0 38 78 43 80 DD E5 1D 28 25 1F F0 25 EF 0D 95 91 0F 21 5D 41 06 00 03 48 77 E0 98 09 3E 04 5A B0 93 63 3B AE 8E 49 0C C2 12 BA DD C3 5A ED FF 68 98 22 C4 5E F6 1E 85 57 15 E8 7E 26 22 E3 70 C2 57 F4 CE 2F CB C4 DC 39 4A 9C FE DE 27 18 D3 36 66 88 92 D7 69 D0 04 8E 93 9B AD E9 2E 5A 2C 91 CD 28 DF BE 62 CF 2C 72 8E FD A9 1F 0E 8E 00 9E 54 28 50 25 0C E7 DC 98 85 C9 B3 59 A8 97 F5 2E 7F 44 4C 43 3C C4 65 E5 AB DB 5B 3C 50 2D 53 B3 EA 74 3C 39 F4 0A 52 31 34 30 F5 E6 82 CD 36 D9
|
|
||||||
*/
|
|
||||||
@UseExperimental(MiraiInternalAPI::class)
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
internal inline fun PacketFactory<*>.buildOutgingPacket(
|
internal inline fun PacketFactory<*>.buildOutgoingPacket(
|
||||||
client: QQAndroidClient,
|
client: QQAndroidClient,
|
||||||
|
bodyType: Byte = 1, // 1: PB?
|
||||||
name: String? = this.commandName,
|
name: String? = this.commandName,
|
||||||
commandName: String = this.commandName,
|
commandName: String = this.commandName,
|
||||||
key: ByteArray,
|
key: ByteArray = client.wLoginSigInfo.d2Key,
|
||||||
body: BytePacketBuilder.(sequenceId: Int) -> Unit
|
body: BytePacketBuilder.(sequenceId: Int) -> Unit
|
||||||
): OutgoingPacket {
|
): OutgoingPacket {
|
||||||
val sequenceId: Int = client.nextSsoSequenceId()
|
val sequenceId: Int = client.nextSsoSequenceId()
|
||||||
@ -73,7 +62,7 @@ internal inline fun PacketFactory<*>.buildOutgingPacket(
|
|||||||
return OutgoingPacket(name, commandName, sequenceId, buildPacket {
|
return OutgoingPacket(name, commandName, sequenceId, buildPacket {
|
||||||
writeIntLVPacket(lengthOffset = { it + 4 }) {
|
writeIntLVPacket(lengthOffset = { it + 4 }) {
|
||||||
writeInt(0x0B)
|
writeInt(0x0B)
|
||||||
writeByte(1)
|
writeByte(bodyType)
|
||||||
writeInt(sequenceId)
|
writeInt(sequenceId)
|
||||||
writeByte(0)
|
writeByte(0)
|
||||||
client.uin.toString().let {
|
client.uin.toString().let {
|
||||||
@ -87,6 +76,68 @@ internal inline fun PacketFactory<*>.buildOutgingPacket(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* buildOutgoingPacket 与 writeUniPacket 的 fast-path
|
||||||
|
*/
|
||||||
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
|
internal inline fun PacketFactory<*>.buildOutgoingUniPacket(
|
||||||
|
client: QQAndroidClient,
|
||||||
|
bodyType: Byte = 1, // 1: PB?
|
||||||
|
name: String? = this.commandName,
|
||||||
|
commandName: String = this.commandName,
|
||||||
|
key: ByteArray = client.wLoginSigInfo.d2Key,
|
||||||
|
extraData: ByteReadPacket = BRP_STUB,
|
||||||
|
body: BytePacketBuilder.(sequenceId: Int) -> Unit
|
||||||
|
): OutgoingPacket {
|
||||||
|
val sequenceId: Int = client.nextSsoSequenceId()
|
||||||
|
|
||||||
|
return OutgoingPacket(name, commandName, sequenceId, buildPacket {
|
||||||
|
writeIntLVPacket(lengthOffset = { it + 4 }) {
|
||||||
|
writeInt(0x0B)
|
||||||
|
writeByte(bodyType)
|
||||||
|
writeInt(sequenceId)
|
||||||
|
writeByte(0)
|
||||||
|
client.uin.toString().let {
|
||||||
|
writeInt(it.length + 4)
|
||||||
|
writeStringUtf8(it)
|
||||||
|
}
|
||||||
|
encryptAndWrite(key) {
|
||||||
|
writeUniPacket(commandName, extraData) {
|
||||||
|
body(sequenceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseExperimental(MiraiInternalAPI::class)
|
||||||
|
internal inline fun BytePacketBuilder.writeUniPacket(
|
||||||
|
commandName: String,
|
||||||
|
extraData: ByteReadPacket = BRP_STUB,
|
||||||
|
body: BytePacketBuilder.() -> Unit
|
||||||
|
) {
|
||||||
|
writeIntLVPacket(lengthOffset = { it + 4 }) {
|
||||||
|
commandName.let {
|
||||||
|
writeInt(it.length + 4)
|
||||||
|
writeStringUtf8(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
writeInt(4 + 4)
|
||||||
|
writeInt(45112203) // 02 B0 5B 8B
|
||||||
|
|
||||||
|
if (extraData === BRP_STUB) {
|
||||||
|
writeInt(0x04)
|
||||||
|
} else {
|
||||||
|
writeInt((extraData.remaining + 4).toInt())
|
||||||
|
writePacket(extraData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// body
|
||||||
|
writeIntLVPacket(lengthOffset = { it + 4 }, builder = body)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最外层的包. 结构适用于登录.
|
* 最外层的包. 结构适用于登录.
|
||||||
*
|
*
|
||||||
@ -213,37 +264,6 @@ internal inline fun BytePacketBuilder.writeSsoPacket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Outermost packet, not for login
|
|
||||||
*
|
|
||||||
* **Packet structure**
|
|
||||||
* int remaining.length + 4
|
|
||||||
* int 0x0B
|
|
||||||
* byte 0x01
|
|
||||||
* byte 0
|
|
||||||
* int [uinAccount].length + 4
|
|
||||||
* byte[] uinAccount
|
|
||||||
*
|
|
||||||
* byte[] body encrypted by [sessionKey]
|
|
||||||
*/
|
|
||||||
internal inline fun PacketFactory<*>.buildSessionOutgoingPacket(
|
|
||||||
uinAccount: String,
|
|
||||||
sessionKey: DecrypterByteArray,
|
|
||||||
body: BytePacketBuilder.() -> Unit
|
|
||||||
): ByteReadPacket = buildPacket {
|
|
||||||
writeIntLVPacket(lengthOffset = { it + 4 }) {
|
|
||||||
writeInt(0x00_00_00_0B)
|
|
||||||
writeByte(0x01)
|
|
||||||
|
|
||||||
writeByte(0)
|
|
||||||
|
|
||||||
writeInt(uinAccount.length + 4)
|
|
||||||
writeStringUtf8(uinAccount)
|
|
||||||
|
|
||||||
encryptAndWrite(sessionKey, body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a request packet
|
* Writes a request packet
|
||||||
* This is the innermost packet structure
|
* This is the innermost packet structure
|
||||||
@ -293,6 +313,8 @@ internal fun BytePacketBuilder.writeOicqRequestPacket(
|
|||||||
writeByte(0x03) // tail
|
writeByte(0x03) // tail
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
00 00 01 64
|
00 00 01 64
|
||||||
00 00 00 0A
|
00 00 00 0A
|
||||||
|
@ -3,6 +3,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet
|
|||||||
import kotlinx.io.core.*
|
import kotlinx.io.core.*
|
||||||
import kotlinx.io.pool.useInstance
|
import kotlinx.io.pool.useInstance
|
||||||
import net.mamoe.mirai.data.Packet
|
import net.mamoe.mirai.data.Packet
|
||||||
|
import net.mamoe.mirai.event.Subscribable
|
||||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||||
import net.mamoe.mirai.qqandroid.io.serialization.loadAs
|
import net.mamoe.mirai.qqandroid.io.serialization.loadAs
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
|
||||||
@ -33,9 +34,14 @@ internal abstract class PacketFactory<out TPacket : Packet>(
|
|||||||
val commandName: String
|
val commandName: String
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* **解码**服务器的回复数据包
|
* **解码**服务器的回复数据包. 返回的包若是 [Subscribable], 则会 broadcast.
|
||||||
*/
|
*/
|
||||||
abstract suspend fun ByteReadPacket.decode(bot: QQAndroidBot): TPacket
|
abstract suspend fun ByteReadPacket.decode(bot: QQAndroidBot): TPacket
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可选的处理这个包. 可以在这里面发新的包.
|
||||||
|
*/
|
||||||
|
open suspend fun @UnsafeVariance TPacket.handle(bot: QQAndroidBot) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmName("decode0")
|
@JvmName("decode0")
|
||||||
@ -43,7 +49,7 @@ private suspend inline fun <P : Packet> PacketFactory<P>.decode(bot: QQAndroidBo
|
|||||||
|
|
||||||
internal val DECRYPTER_16_ZERO = ByteArray(16)
|
internal val DECRYPTER_16_ZERO = ByteArray(16)
|
||||||
|
|
||||||
internal typealias PacketConsumer = suspend (packet: Packet, commandName: String, ssoSequenceId: Int) -> Unit
|
internal typealias PacketConsumer<T> = suspend (packetFactory: PacketFactory<T>, packet: T, commandName: String, ssoSequenceId: Int) -> Unit
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal val PacketLogger: MiraiLogger = DefaultLogger("Packet")
|
internal val PacketLogger: MiraiLogger = DefaultLogger("Packet")
|
||||||
@ -66,7 +72,8 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
|
|||||||
* full packet without length
|
* full packet without length
|
||||||
*/
|
*/
|
||||||
// do not inline. Exceptions thrown will not be reported correctly
|
// do not inline. Exceptions thrown will not be reported correctly
|
||||||
suspend fun parseIncomingPacket(bot: QQAndroidBot, rawInput: Input, consumer: PacketConsumer) {
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
suspend fun <T : Packet> parseIncomingPacket(bot: QQAndroidBot, rawInput: Input, consumer: PacketConsumer<T>) {
|
||||||
rawInput.readBytes().let {
|
rawInput.readBytes().let {
|
||||||
PacketLogger.verbose("开始处理包: ${it.toUHexString()}")
|
PacketLogger.verbose("开始处理包: ${it.toUHexString()}")
|
||||||
it.toReadPacket()
|
it.toReadPacket()
|
||||||
@ -124,12 +131,13 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
|
|||||||
1 ->//it.data.parseUniResponse(bot, it.packetFactory, it.sequenceId, consumer)
|
1 ->//it.data.parseUniResponse(bot, it.packetFactory, it.sequenceId, consumer)
|
||||||
{
|
{
|
||||||
consumer(
|
consumer(
|
||||||
|
it.packetFactory as PacketFactory<T>,
|
||||||
it.packetFactory.run { decode(bot, it.data) },
|
it.packetFactory.run { decode(bot, it.data) },
|
||||||
it.packetFactory.commandName,
|
it.packetFactory.commandName,
|
||||||
it.sequenceId
|
it.sequenceId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
2 -> it.data.parseOicqResponse(bot, it.packetFactory, it.sequenceId, consumer)
|
2 -> it.data.parseOicqResponse(bot, it.packetFactory as PacketFactory<T>, it.sequenceId, consumer)
|
||||||
else -> error("unknown flag2: $flag2. Body to be parsed for inner packet=${it.data.readBytes().toUHexString()}")
|
else -> error("unknown flag2: $flag2. Body to be parsed for inner packet=${it.data.readBytes().toUHexString()}")
|
||||||
}
|
}
|
||||||
} ?: inline {
|
} ?: inline {
|
||||||
@ -200,7 +208,12 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
|
|||||||
return IncomingPacket(packetFactory, ssoSequenceId, input)
|
return IncomingPacket(packetFactory, ssoSequenceId, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun ByteReadPacket.parseOicqResponse(bot: QQAndroidBot, packetFactory: PacketFactory<*>, ssoSequenceId: Int, consumer: PacketConsumer) {
|
private suspend fun <T : Packet> ByteReadPacket.parseOicqResponse(
|
||||||
|
bot: QQAndroidBot,
|
||||||
|
packetFactory: PacketFactory<T>,
|
||||||
|
ssoSequenceId: Int,
|
||||||
|
consumer: PacketConsumer<T>
|
||||||
|
) {
|
||||||
val qq: Long
|
val qq: Long
|
||||||
readIoBuffer(readInt() - 4).withUse {
|
readIoBuffer(readInt() - 4).withUse {
|
||||||
check(readByte().toInt() == 2)
|
check(readByte().toInt() == 2)
|
||||||
@ -243,14 +256,19 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
|
|||||||
else -> error("Illegal encryption method. expected 0 or 4, got $encryptionMethod")
|
else -> error("Illegal encryption method. expected 0 or 4, got $encryptionMethod")
|
||||||
}
|
}
|
||||||
|
|
||||||
consumer(packet, packetFactory.commandName, ssoSequenceId)
|
consumer(packetFactory, packet, packetFactory.commandName, ssoSequenceId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun ByteReadPacket.parseUniResponse(bot: QQAndroidBot, packetFactory: PacketFactory<*>, ssoSequenceId: Int, consumer: PacketConsumer) {
|
private suspend fun ByteReadPacket.parseUniResponse(
|
||||||
|
bot: QQAndroidBot,
|
||||||
|
packetFactory: PacketFactory<*>,
|
||||||
|
ssoSequenceId: Int,
|
||||||
|
consumer: PacketConsumer<Packet>
|
||||||
|
) {
|
||||||
val uni = readBytes(readInt() - 4).loadAs(RequestPacket.serializer())
|
val uni = readBytes(readInt() - 4).loadAs(RequestPacket.serializer())
|
||||||
PacketLogger.verbose(uni.toString())
|
PacketLogger.verbose(uni.toString())
|
||||||
/// consumer(packetFactory.decode(bot, uni.sBuffer.toReadPacket()), uni.sServantName + "." + uni.sFuncName, ssoSequenceId)
|
/// consumer(packetFactory.decode(bot, uni.sBuffer.toReadPacket()), uni.sServantName + "." + uni.sFuncName, ssoSequenceId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user