From e47143e872c022a641cfa4f69957a6f974b864f0 Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 6 Dec 2019 23:47:48 +0800 Subject: [PATCH] Make all packets internal --- .../kotlin/net.mamoe.mirai/BotHelper.kt | 11 +++- .../event/events/PacketEvents.kt | 14 ++-- .../network/BotNetworkHandler.kt | 14 ---- .../net.mamoe.mirai/network/BotSession.kt | 39 +++++++---- .../protocol/tim/TIMBotNetworkHandler.kt | 7 +- .../tim/handler/DataPacketSocketAdapter.kt | 10 +-- .../tim/handler/TemporaryPacketHandler.kt | 20 +++--- .../protocol/tim/packet/Annotations.kt | 4 +- .../network/protocol/tim/packet/Decrypters.kt | 14 ++-- .../protocol/tim/packet/OutgoingPacket.kt | 23 +++++-- .../network/protocol/tim/packet/Packet.kt | 6 +- .../protocol/tim/packet/PacketFactory.kt | 24 +++++-- .../network/protocol/tim/packet/PacketId.kt | 14 ++-- .../protocol/tim/packet/action/AddContact.kt | 17 ++--- .../protocol/tim/packet/action/FriendImage.kt | 66 +++++++++++-------- .../protocol/tim/packet/action/GradeInfo.kt | 2 +- .../protocol/tim/packet/action/GroupImage.kt | 20 +++--- .../protocol/tim/packet/action/GroupPacket.kt | 35 ++++++---- .../protocol/tim/packet/action/Profile.kt | 6 +- .../protocol/tim/packet/action/Remark.kt | 2 +- .../packet/action/RequestFriendListPacket.kt | 2 +- .../packet/action/SendFriendMessagePacket.kt | 4 +- .../tim/packet/event/EventPacketFactory.kt | 15 +++-- .../packet/event/FriendOnlineStatusChanged.kt | 2 +- .../protocol/tim/packet/event/Ignored.kt | 6 +- .../protocol/tim/packet/event/MemberJoin.kt | 4 +- .../protocol/tim/packet/event/MemberMute.kt | 2 +- .../protocol/tim/packet/event/Unknown.kt | 4 +- .../protocol/tim/packet/login/Captcha.kt | 6 +- .../packet/login/ChangeOnlineStatusPacket.kt | 4 +- .../protocol/tim/packet/login/Heartbeat.kt | 4 +- .../tim/packet/login/PasswordSubmission.kt | 12 ++-- .../network/protocol/tim/packet/login/SKey.kt | 2 +- .../protocol/tim/packet/login/Session.kt | 4 +- .../protocol/tim/packet/login/Touch.kt | 6 +- .../kotlin/net.mamoe.mirai/utils/TEA.kt | 24 +++---- .../net.mamoe.mirai/utils/io/OutputUtils.kt | 60 ++++++++--------- 37 files changed, 273 insertions(+), 236 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotHelper.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotHelper.kt index 869b69259..acfc697fb 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotHelper.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotHelper.kt @@ -7,6 +7,7 @@ package net.mamoe.mirai import net.mamoe.mirai.contact.* import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotSession +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.login.LoginResult import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess @@ -30,7 +31,9 @@ suspend inline fun Bot.getQQ(@PositiveNumbers number: Long): QQ = this.contacts. 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(@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) @@ -60,7 +63,8 @@ inline fun Bot.withSession(block: BotSession.() -> R): R { * 发送数据包 * @throws IllegalStateException 当 [BotNetworkHandler.socket] 未开启时 */ -suspend inline fun Bot.sendPacket(packet: OutgoingPacket) = this.network.sendPacket(packet) +internal suspend inline fun Bot.sendPacket(packet: OutgoingPacket) = + (this.network as TIMBotNetworkHandler).socket.sendPacket(packet) /** * 使用在默认配置基础上修改的配置进行登录 @@ -109,7 +113,8 @@ suspend inline fun Bot.alsoLogin(message: String): Bot { */ @UseExperimental(ExperimentalContracts::class) @JvmOverloads -suspend inline fun Bot.addFriend(id: UInt, message: String? = null, remark: String? = null): AddFriendResult = contacts.addFriend(id, message, remark) +suspend inline fun Bot.addFriend(id: UInt, message: String? = null, remark: String? = null): AddFriendResult = + contacts.addFriend(id, message, remark) /** * 取得机器人的 QQ 号 diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/PacketEvents.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/PacketEvents.kt index 927201d6e..bdc92a2fa 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/PacketEvents.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/PacketEvents.kt @@ -9,10 +9,8 @@ import net.mamoe.mirai.network.protocol.tim.packet.Packet /** * 数据包相关事件 - * - * @param P 指代数据包的类型. 这个类型是 **invariant(不变的)** */ -sealed class PacketEvent

(bot: Bot, open val packet: P) : BotEvent(bot) +internal sealed class PacketEvent

(bot: Bot, open val packet: P) : BotEvent(bot) /* Client to Server */ @@ -20,21 +18,21 @@ sealed class PacketEvent

(bot: Bot, open val packet: P) : BotEvent(bo /** * 发送给服务器的数据包的相关事件 */ -sealed class OutgoingPacketEvent(bot: Bot, packet: OutgoingPacket) : PacketEvent(bot, packet) +internal sealed class OutgoingPacketEvent(bot: Bot, packet: OutgoingPacket) : PacketEvent(bot, packet) /** * 包已发送, 此时包数据已完全发送至服务器, 且包已被关闭. * * 不可被取消 */ -class PacketSentEvent(bot: Bot, packet: OutgoingPacket) : OutgoingPacketEvent(bot, packet) +internal class PacketSentEvent(bot: Bot, packet: OutgoingPacket) : OutgoingPacketEvent(bot, packet) /** * 包发送前, 此时包数据已经编码完成. * * 可被取消 */ -class BeforePacketSendEvent(bot: Bot, packet: OutgoingPacket) : OutgoingPacketEvent(bot, packet), Cancellable +internal class BeforePacketSendEvent(bot: Bot, packet: OutgoingPacket) : OutgoingPacketEvent(bot, packet), Cancellable /* Server to Client */ @@ -42,9 +40,9 @@ class BeforePacketSendEvent(bot: Bot, packet: OutgoingPacket) : OutgoingPacketEv /** * 来自服务器的数据包的相关事件 */ -sealed class ServerPacketEvent

(bot: Bot, packet: P) : PacketEvent

(bot, packet) +internal sealed class ServerPacketEvent

(bot: Bot, packet: P) : PacketEvent

(bot, packet) /** * 服务器数据包接收事件. 此时包已经解密完成. */ -class ServerPacketReceivedEvent

(bot: Bot, packet: P) : ServerPacketEvent

(bot, packet), Cancellable \ No newline at end of file +internal class ServerPacketReceivedEvent

(bot: Bot, packet: P) : ServerPacketEvent

(bot, packet), Cancellable \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt index d679b0c9d..ae602d238 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotNetworkHandler.kt @@ -47,20 +47,6 @@ interface BotNetworkHandler : CoroutineScope { */ suspend fun login(): LoginResult - /** - * 添加一个临时包处理器, 并发送相应的包 - * - * @see [BotSession.sendAndExpectAsync] 发送并期待一个包 - * @see [TemporaryPacketHandler] 临时包处理器 - */ - @MiraiInternalAPI - suspend fun addHandler(temporaryPacketHandler: TemporaryPacketHandler<*, *>) - - /** - * 发送数据包 - */ - suspend fun sendPacket(packet: OutgoingPacket) - /** * 等待直到与服务器断开连接. 若未连接则立即返回 */ diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt index 6ee04100d..999049c07 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/BotSession.kt @@ -46,7 +46,7 @@ internal inline fun TIMBotNetworkHandler.BotSession( * @author Him188moe */ @UseExperimental(MiraiInternalAPI::class) -expect class BotSession( +expect class BotSession internal constructor( bot: Bot, sessionKey: SessionKey, socket: DataPacketSocketAdapter, @@ -58,9 +58,9 @@ expect class BotSession( */ @MiraiInternalAPI // cannot be internal because of `public BotSession` -abstract class BotSessionBase( +abstract class BotSessionBase internal constructor( val bot: Bot, - val sessionKey: SessionKey, + internal val sessionKey: SessionKey, val socket: DataPacketSocketAdapter, val NetworkScope: CoroutineScope ) { @@ -110,33 +110,36 @@ abstract class BotSessionBase( * * @see Bot.withSession 转换 receiver, 即 `this` 的指向, 为 [BotSession] */ - suspend inline fun OutgoingPacket.sendAndExpectAsync( + internal suspend inline fun OutgoingPacket.sendAndExpectAsync( checkSequence: Boolean = true, noinline handler: suspend (P) -> R ): Deferred { val deferred: CompletableDeferred = CompletableDeferred(coroutineContext[Job]) - bot.network.addHandler(TemporaryPacketHandler(P::class, deferred, this@BotSessionBase as BotSession, checkSequence, coroutineContext + deferred).also { + (bot.network as TIMBotNetworkHandler).addHandler(TemporaryPacketHandler( + P::class, deferred, this@BotSessionBase as BotSession, checkSequence, coroutineContext + deferred + ).also { it.toSend(this) it.onExpect(handler) }) return deferred } - suspend inline fun OutgoingPacket.sendAndExpectAsync(checkSequence: Boolean = true): Deferred

= + internal suspend inline fun OutgoingPacket.sendAndExpectAsync(checkSequence: Boolean = true): Deferred

= sendAndExpectAsync(checkSequence) { it } - suspend inline fun OutgoingPacket.sendAndExpect( + internal suspend inline fun OutgoingPacket.sendAndExpect( checkSequence: Boolean = true, timeout: TimeSpan = 5.seconds, crossinline mapper: (P) -> R ): R = withTimeout(timeout.millisecondsLong) { sendAndExpectAsync(checkSequence) { mapper(it) }.await() } - suspend inline fun OutgoingPacket.sendAndExpect( + internal suspend inline fun OutgoingPacket.sendAndExpect( checkSequence: Boolean = true, timeout: TimeSpan = 5.seconds ): P = withTimeout(timeout.millisecondsLong) { sendAndExpectAsync(checkSequence) { it }.await() } - suspend inline fun OutgoingPacket.send() = socket.sendPacket(this) + internal suspend inline fun OutgoingPacket.send() = + (socket as TIMBotNetworkHandler.BotSocketAdapter).sendPacket(this) suspend inline fun Int.qq(): QQ = bot.getQQ(this.coerceAtLeastOrFail(0).toUInt()) @@ -150,8 +153,16 @@ abstract class BotSessionBase( suspend inline fun GroupInternalId.group(): Group = bot.getGroup(this) suspend fun Image.getLink(): ImageLink = when (this.id) { - is ImageId0x06 -> FriendImagePacket.RequestImageLink(bot.qqAccount, bot.sessionKey, id).sendAndExpect() - is ImageId0x03 -> GroupImagePacket.RequestImageLink(bot.qqAccount, bot.sessionKey, id).sendAndExpect().requireSuccess() + is ImageId0x06 -> FriendImagePacket.RequestImageLink( + bot.qqAccount, + bot.sessionKey, + id + ).sendAndExpect() + is ImageId0x03 -> GroupImagePacket.RequestImageLink( + bot.qqAccount, + bot.sessionKey, + id + ).sendAndExpect().requireSuccess() else -> assertUnreachable() } @@ -167,7 +178,7 @@ inline val BotSession.qqAccount: UInt get() = bot.account.id // 为了与群和 * 取得 [BotNetworkHandler] 的 sessionKey. * 实际上是一个捷径. */ -inline val BotNetworkHandler<*>.sessionKey: SessionKey get() = this.session.sessionKey +internal inline val BotNetworkHandler<*>.sessionKey: SessionKey get() = this.session.sessionKey /** * 取得 [Bot] 的 [BotSession]. @@ -179,14 +190,14 @@ inline val Bot.session: BotSession get() = this.network.session * 取得 [Bot] 的 `sessionKey`. * 实际上是一个捷径. */ -inline val Bot.sessionKey: SessionKey get() = this.session.sessionKey +internal inline val Bot.sessionKey: SessionKey get() = this.session.sessionKey /** * 发送数据包 * @throws IllegalStateException 当 [BotNetworkHandler.socket] 未开启时 */ -suspend inline fun BotSession.sendPacket(packet: OutgoingPacket) = this.bot.sendPacket(packet) +internal suspend inline fun BotSession.sendPacket(packet: OutgoingPacket) = this.bot.sendPacket(packet) suspend inline fun BotSession.getQQ(@PositiveNumbers number: Long): QQ = this.bot.getQQ(number) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt index 8c2559624..2cfe51102 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt @@ -59,8 +59,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou private var heartbeatJob: Job? = null - @UseExperimental(MiraiInternalAPI::class) - override suspend fun addHandler(temporaryPacketHandler: TemporaryPacketHandler<*, *>) { + suspend fun addHandler(temporaryPacketHandler: TemporaryPacketHandler<*, *>) { handlersLock.withLock { temporaryPacketHandlers.add(temporaryPacketHandler) } @@ -116,8 +115,6 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou this.socket.close() } - override suspend fun sendPacket(packet: OutgoingPacket) = socket.sendPacket(packet) - internal inner class BotSocketAdapter(override val serverIp: String) : DataPacketSocketAdapter { @@ -255,7 +252,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou loginHandler?.onPacketReceived(packet) } - override suspend fun sendPacket(packet: OutgoingPacket): Unit = withContext(coroutineContext + CoroutineName("sendPacket")) { + internal suspend fun sendPacket(packet: OutgoingPacket): Unit = withContext(coroutineContext + CoroutineName("sendPacket")) { check(channel.isOpen) { "channel is not open" } if (BeforePacketSendEvent(bot, packet).broadcast().cancelled) { diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/DataPacketSocketAdapter.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/DataPacketSocketAdapter.kt index 9cd1b48e1..04f1b049f 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/DataPacketSocketAdapter.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/DataPacketSocketAdapter.kt @@ -8,6 +8,7 @@ import net.mamoe.mirai.event.events.ServerPacketReceivedEvent import net.mamoe.mirai.network.BotSession import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket +import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.io.PlatformDatagramChannel /** @@ -36,14 +37,5 @@ interface DataPacketSocketAdapter : Closeable { */ val isOpen: Boolean - /** - * 发送一个数据包(非异步). - * - * 可通过 hook 事件 [ServerPacketReceivedEvent] 来获取服务器返回. - * - * @see [BotSession.sendAndExpectAsync] kotlin DSL - */ - suspend fun sendPacket(packet: OutgoingPacket) - override fun close() } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt index 021e0f7c8..b8512e040 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.withContext import net.mamoe.mirai.network.BotSession import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket import net.mamoe.mirai.network.protocol.tim.packet.Packet +import net.mamoe.mirai.network.sendPacket import kotlin.coroutines.CoroutineContext import kotlin.reflect.KClass @@ -23,7 +24,7 @@ import kotlin.reflect.KClass * * @see BotSession.sendAndExpectAsync */ -class TemporaryPacketHandler

( +internal class TemporaryPacketHandler

( private val expectationClass: KClass

, private val deferred: CompletableDeferred, private val fromSession: BotSession, @@ -40,24 +41,26 @@ class TemporaryPacketHandler

( lateinit var session: BotSession//无需覆盖 - fun toSend(packet: OutgoingPacket) { + @Suppress("NOTHING_TO_INLINE") + inline fun toSend(packet: OutgoingPacket) { this.toSend = packet } - fun onExpect(handler: suspend (P) -> R) { + @Suppress("NOTHING_TO_INLINE") + inline fun onExpect(noinline handler: suspend (P) -> R) { this.handler = handler } - internal suspend fun send(session: BotSession) { - require(::handler.isInitialized) { "handler is not initialized" } + internal suspend inline fun send(session: BotSession) { this.session = session - session.socket.sendPacket(toSend) + session.sendPacket(toSend) } - internal fun filter(session: BotSession, packet: Packet, sequenceId: UShort): Boolean = + @Suppress("NOTHING_TO_INLINE") + internal inline fun filter(session: BotSession, packet: Packet, sequenceId: UShort): Boolean = expectationClass.isInstance(packet) && session === this.fromSession && if (checkSequence) sequenceId == toSend.sequenceId else true - internal suspend fun doReceiveWithoutExceptions(packet: Packet) { + internal suspend inline fun doReceiveWithoutExceptions(packet: Packet) { @Suppress("UNCHECKED_CAST") val ret = try { withContext(callerContext) { @@ -68,6 +71,5 @@ class TemporaryPacketHandler

( return } deferred.complete(ret) - return } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Annotations.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Annotations.kt index a2ffcce3f..8760ae58f 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Annotations.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Annotations.kt @@ -9,11 +9,11 @@ package net.mamoe.mirai.network.protocol.tim.packet @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.CLASS) -annotation class AnnotatedId( // 注解无法在 JS 平台使用, 但现在暂不需要考虑 JS +internal annotation class AnnotatedId( // 注解无法在 JS 平台使用, 但现在暂不需要考虑 JS val id: KnownPacketId ) -inline val AnnotatedId.value: UShort get() = id.value +internal inline val AnnotatedId.value: UShort get() = id.value /** * 包的最后一次修改时间, 和分析时使用的 TIM 版本 diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Decrypters.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Decrypters.kt index f8b1bdee6..61bed0632 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Decrypters.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Decrypters.kt @@ -8,14 +8,14 @@ import net.mamoe.mirai.utils.decryptBy /** * 会话密匙 */ -inline class SessionKey(override val value: ByteArray) : DecrypterByteArray { +internal inline class SessionKey(override val value: ByteArray) : DecrypterByteArray { companion object Type : DecrypterType } /** * [ByteArray] 解密器 */ -interface DecrypterByteArray : Decrypter { +internal interface DecrypterByteArray : Decrypter { val value: ByteArray override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value) } @@ -23,7 +23,7 @@ interface DecrypterByteArray : Decrypter { /** * [IoBuffer] 解密器 */ -interface DecrypterIoBuffer : Decrypter { +internal interface DecrypterIoBuffer : Decrypter { val value: IoBuffer override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value) } @@ -31,18 +31,18 @@ interface DecrypterIoBuffer : Decrypter { /** * 连接在一起的解密器 */ -inline class LinkedDecrypter(inline val block: (ByteReadPacket) -> ByteReadPacket) : Decrypter { +internal inline class LinkedDecrypter(inline val block: (ByteReadPacket) -> ByteReadPacket) : Decrypter { override fun decrypt(input: ByteReadPacket): ByteReadPacket = block(input) } -object NoDecrypter : Decrypter, DecrypterType { +internal object NoDecrypter : Decrypter, DecrypterType { override fun decrypt(input: ByteReadPacket): ByteReadPacket = input } /** * 解密器 */ -interface Decrypter { +internal interface Decrypter { fun decrypt(input: ByteReadPacket): ByteReadPacket /** * 连接后将会先用 this 解密, 再用 [another] 解密 @@ -50,4 +50,4 @@ interface Decrypter { operator fun plus(another: Decrypter): Decrypter = LinkedDecrypter { another.decrypt(this.decrypt(it)) } } -interface DecrypterType \ No newline at end of file +internal interface DecrypterType \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt index f1946d016..0fed254bb 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt @@ -18,7 +18,7 @@ import kotlin.jvm.JvmOverloads /** * 待发送给服务器的数据包. 它代表着一个 [ByteReadPacket], */ -class OutgoingPacket( +internal class OutgoingPacket( name: String?, val packetId: PacketId, val sequenceId: UShort, @@ -35,7 +35,7 @@ class OutgoingPacket( * * @param TPacket invariant */ -abstract class SessionPacketFactory : PacketFactory(SessionKey) { +internal abstract class SessionPacketFactory : PacketFactory(SessionKey) { /** * 在 [BotNetworkHandler] 下处理这个包. 广播事件等. */ @@ -49,7 +49,7 @@ abstract class SessionPacketFactory : PacketFactory.buildOutgoingPacket( +internal inline fun PacketFactory<*, *>.buildOutgoingPacket( name: String? = null, id: PacketId = this.id, sequenceId: UShort = PacketFactory.atomicNextSequenceId(), @@ -81,7 +81,7 @@ inline fun PacketFactory<*, *>.buildOutgoingPacket( */ @UseExperimental(ExperimentalContracts::class) @JvmOverloads -inline fun PacketFactory<*, *>.buildSessionPacket( +internal inline fun PacketFactory<*, *>.buildSessionPacket( bot: UInt, sessionKey: SessionKey, name: String? = null, @@ -110,7 +110,7 @@ inline fun PacketFactory<*, *>.buildSessionPacket( */ @UseExperimental(ExperimentalContracts::class) @JvmOverloads -fun PacketFactory<*, *>.buildSessionProtoPacket( +internal fun PacketFactory<*, *>.buildSessionProtoPacket( bot: UInt, sessionKey: SessionKey, name: String? = null, @@ -142,7 +142,18 @@ fun PacketFactory<*, *>.buildSessionProtoPacket( writeFully(head) writeFully(proto) } - is String -> buildSessionProtoPacket(bot, sessionKey, name, id, sequenceId, headerSizeHint, version, head.hexToBytes(), serializer, protoObj) + is String -> buildSessionProtoPacket( + bot, + sessionKey, + name, + id, + sequenceId, + headerSizeHint, + version, + head.hexToBytes(), + serializer, + protoObj + ) } } } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Packet.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Packet.kt index 38a4ff3e2..8a4731752 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Packet.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/Packet.kt @@ -12,18 +12,18 @@ interface Packet /** * 被忽略的数据包. */ -inline class IgnoredPacket(val id: PacketId) : Packet +internal inline class IgnoredPacket(internal val id: PacketId) : Packet /** * 未知的包. */ -class UnknownPacket(val id: PacketId, val body: ByteReadPacket) : Packet { +internal class UnknownPacket(val id: PacketId, val body: ByteReadPacket) : Packet { override fun toString(): String = "UnknownPacket(${id.value.toUHexString()})\nbody=${body.readBytes().toUHexString()}" } /** * 仅用于替换类型应为 [Unit] 的情况 */ -object NoPacket : Packet { +internal object NoPacket : Packet { override fun toString(): String = "NoPacket" } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketFactory.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketFactory.kt index d79ee4f22..398213572 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketFactory.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketFactory.kt @@ -10,6 +10,7 @@ import kotlinx.io.pool.useInstance import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.network.BotNetworkHandler +import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.io.ByteArrayPool import net.mamoe.mirai.utils.io.debugPrint import net.mamoe.mirai.utils.io.read @@ -23,7 +24,7 @@ import net.mamoe.mirai.utils.readProtoMap * @param TPacket 服务器回复包解析结果 * @param TDecrypter 服务器回复包解密器 */ -abstract class PacketFactory(val decrypterType: DecrypterType) { +internal abstract class PacketFactory(val decrypterType: DecrypterType) { /** * 2 Ubyte. @@ -46,7 +47,10 @@ abstract class PacketFactory(val d abstract suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): TPacket @Suppress("DEPRECATION") - fun ByteReadPacket.decodeProtoPacket(deserializer: DeserializationStrategy, debuggingTag: String? = null): T { + fun ByteReadPacket.decodeProtoPacket( + deserializer: DeserializationStrategy, + debuggingTag: String? = null + ): T { val headLength = readInt() val protoLength = readInt() if (debuggingTag != null) { @@ -72,7 +76,7 @@ abstract class PacketFactory(val d } } -object UnknownPacketFactory : SessionPacketFactory() { +internal object UnknownPacketFactory : SessionPacketFactory() { override suspend fun BotNetworkHandler<*>.handlePacket(packet: UnknownPacket) { ByteArrayPool.useInstance { packet.body.readAvailable(it) @@ -81,11 +85,19 @@ object UnknownPacketFactory : SessionPacketFactory() { packet.body.close() } - override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): UnknownPacket { + override suspend fun ByteReadPacket.decode( + id: PacketId, + sequenceId: UShort, + handler: BotNetworkHandler<*> + ): UnknownPacket { return UnknownPacket(id, this) } } -object IgnoredPacketFactory : SessionPacketFactory() { - override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): IgnoredPacket = IgnoredPacket(id) +internal object IgnoredPacketFactory : SessionPacketFactory() { + override suspend fun ByteReadPacket.decode( + id: PacketId, + sequenceId: UShort, + handler: BotNetworkHandler<*> + ): IgnoredPacket = IgnoredPacket(id) } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketId.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketId.kt index 496e8bc3e..db4ddd7b0 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketId.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketId.kt @@ -12,13 +12,13 @@ import net.mamoe.mirai.utils.io.toUHexString /** * 通过 [value] 匹配一个 [IgnoredPacketId] 或 [KnownPacketId], 无匹配则返回一个 [UnknownPacketId]. */ -fun matchPacketId(value: UShort): PacketId = +internal fun matchPacketId(value: UShort): PacketId = IgnoredPacketIds.firstOrNull { it.value == value } ?: KnownPacketId.values().firstOrNull { it.value == value } ?: UnknownPacketId(value) /** * 包 ID. */ -interface PacketId { +internal interface PacketId { val value: UShort val factory: PacketFactory<*, *> } @@ -27,7 +27,7 @@ interface PacketId { * 用于代表 `null`. 调用任何属性时都将会得到一个 [error] */ @Suppress("unused") -object NullPacketId : PacketId { +internal object NullPacketId : PacketId { override val factory: PacketFactory<*, *> get() = error("uninitialized") override val value: UShort get() = error("uninitialized") override fun toString(): String = "NullPacketId" @@ -36,17 +36,17 @@ object NullPacketId : PacketId { /** * 未知的 [PacketId] */ -inline class UnknownPacketId(override inline val value: UShort) : PacketId { +internal inline class UnknownPacketId(override inline val value: UShort) : PacketId { override val factory: PacketFactory<*, *> get() = UnknownPacketFactory override fun toString(): String = "UnknownPacketId(${value.toUHexString()})" } -object IgnoredPacketIds : List by { +internal object IgnoredPacketIds : List by { listOf( ).map { IgnoredPacketId(it.toUShort()) } }() -inline class IgnoredPacketId constructor(override val value: UShort) : PacketId { +internal inline class IgnoredPacketId constructor(override val value: UShort) : PacketId { override val factory: PacketFactory<*, *> get() = IgnoredPacketFactory override fun toString(): String = "IgnoredPacketId(${value.toUHexString()})" } @@ -55,7 +55,7 @@ inline class IgnoredPacketId constructor(override val value: UShort) : PacketId * 已知的 [matchPacketId]. 所有在 Mirai 中实现过的包都会使用这些 Id */ @Suppress("unused") -enum class KnownPacketId(override inline val value: UShort, override inline val factory: PacketFactory<*, *>) : +internal enum class KnownPacketId(override inline val value: UShort, override inline val factory: PacketFactory<*, *>) : PacketId { inline TOUCH(0x0825u, TouchPacket), inline SESSION_KEY(0x0828u, RequestSessionPacket), diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/AddContact.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/AddContact.kt index 82cb97aec..02114cf40 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/AddContact.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/AddContact.kt @@ -21,7 +21,7 @@ import net.mamoe.mirai.withSession */ @AnnotatedId(KnownPacketId.QUERY_PREVIOUS_NAME) @PacketVersion(date = "2019.11.11", timVersion = "2.3.2 (21173)") -object QueryPreviousNamePacket : SessionPacketFactory() { +internal object QueryPreviousNamePacket : SessionPacketFactory() { operator fun invoke( bot: UInt, sessionKey: SessionKey, @@ -79,7 +79,7 @@ class PreviousNameList( */ @AnnotatedId(KnownPacketId.CAN_ADD_FRIEND) @PacketVersion(date = "2019.11.11", timVersion = "2.3.2 (21173)") -object CanAddFriendPacket : SessionPacketFactory() { +internal object CanAddFriendPacket : SessionPacketFactory() { operator fun invoke( bot: UInt, qq: UInt, @@ -112,7 +112,7 @@ object CanAddFriendPacket : SessionPacketFactory() { } -sealed class CanAddFriendResponse : EventPacket { +internal sealed class CanAddFriendResponse : EventPacket { abstract val qq: QQ /** @@ -157,7 +157,7 @@ inline class FriendAdditionKey(val value: IoBuffer) */ @AnnotatedId(KnownPacketId.REQUEST_FRIEND_ADDITION_KEY) @PacketVersion(date = "2019.11.11", timVersion = "2.3.2 (21173)") -object RequestFriendAdditionKeyPacket : SessionPacketFactory() { +internal object RequestFriendAdditionKeyPacket : SessionPacketFactory() { operator fun invoke( bot: UInt, qq: UInt, @@ -183,8 +183,9 @@ object RequestFriendAdditionKeyPacket : SessionPacketFactory() { +internal object AddFriendPacket : SessionPacketFactory() { @PacketVersion(date = "2019.11.11", timVersion = "2.3.2 (21173)") + @Suppress("FunctionName") fun RequestAdd( bot: UInt, qq: UInt, @@ -198,7 +199,7 @@ object AddFriendPacket : SessionPacketFactory() { */ remark: String?, //// TODO: 2019/11/15 无备注的情况 key: FriendAdditionKey - ): OutgoingPacket = buildSessionPacket(bot, sessionKey) { + ): OutgoingPacket = buildSessionPacket(bot, sessionKey, name = "AddFriendPacket.RequestAdd") { //02 5D 12 93 30 // 00 @@ -264,7 +265,7 @@ object AddFriendPacket : SessionPacketFactory() { * 备注. 不设置则需要为 `null` TODO 需要确认是否还需发送一个设置备注包. 因为测试时若有备注则会多发一个包并且包里面有所设置的备注 */ remark: String? - ): OutgoingPacket = buildSessionPacket(bot, sessionKey, version = TIMProtocol.version0x02) { + ): OutgoingPacket = buildSessionPacket(bot, sessionKey, version = TIMProtocol.version0x02, name = "AddFriendPacket.Approve") { writeByte(0x03) writeQQ(qq) writeZero(1) @@ -282,7 +283,7 @@ object AddFriendPacket : SessionPacketFactory() { writeHex("00 05 00 00 00 00 01") } - object Response : Packet { + internal object Response : Packet { override fun toString(): String = "AddFriendPacket.Response" } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/FriendImage.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/FriendImage.kt index 54214eb30..59dadf377 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/FriendImage.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/FriendImage.kt @@ -29,31 +29,30 @@ import net.mamoe.mirai.withSession * @throws OverFileSizeMaxException 如果文件过大, 服务器拒绝接收时 */ suspend fun QQ.uploadImage(image: ExternalImage): ImageId = bot.withSession { - FriendImagePacket.RequestImageId(qqAccount, sessionKey, id, image) - .sendAndExpectAsync { - return@sendAndExpectAsync when (it) { - is FriendImageUKey -> { - Http.postImage( - htcmd = "0x6ff0070", - uin = bot.qqAccount, - groupId = null, - uKeyHex = it.uKey.toUHexString(""), - imageInput = image.input, - inputSize = image.inputSize - ) - it.imageId - } - is FriendImageAlreadyExists -> it.imageId - is FriendImageOverFileSizeMax -> throw OverFileSizeMaxException() - else -> error("This shouldn't happen") + FriendImagePacket.RequestImageId(qqAccount, sessionKey, id, image).sendAndExpect().let { + when (it) { + is FriendImageUKey -> { + Http.postImage( + htcmd = "0x6ff0070", + uin = bot.qqAccount, + groupId = null, + uKeyHex = it.uKey.toUHexString(""), + imageInput = image.input, + inputSize = image.inputSize + ) + it.imageId } - }.await() + is FriendImageAlreadyExists -> it.imageId + is FriendImageOverFileSizeMax -> throw OverFileSizeMaxException() + else -> error("This shouldn't happen") + } + } } // region FriendImageResponse -interface FriendImageResponse : EventPacket +internal interface FriendImageResponse : EventPacket /** * 图片数据地址. @@ -66,7 +65,7 @@ data class FriendImageLink(override inline val original: String) : FriendImageRe /** * 访问 HTTP API 时使用的 uKey */ -class FriendImageUKey(inline val imageId: ImageId, inline val uKey: ByteArray) : FriendImageResponse { +internal class FriendImageUKey(inline val imageId: ImageId, inline val uKey: ByteArray) : FriendImageResponse { override fun toString(): String = "FriendImageUKey(imageId=${imageId.value}, uKey=${uKey.toUHexString()})" } @@ -74,14 +73,14 @@ class FriendImageUKey(inline val imageId: ImageId, inline val uKey: ByteArray) : * 图片 ID 已存在 * 发送消息时使用的 id */ -inline class FriendImageAlreadyExists(inline val imageId: ImageId) : FriendImageResponse { +internal inline class FriendImageAlreadyExists(inline val imageId: ImageId) : FriendImageResponse { override fun toString(): String = "FriendImageAlreadyExists(imageId=${imageId.value})" } /** * 超过文件大小上限 */ -object FriendImageOverFileSizeMax : FriendImageResponse { +internal object FriendImageOverFileSizeMax : FriendImageResponse { override fun toString(): String = "FriendImageOverFileSizeMax" } @@ -95,14 +94,19 @@ object FriendImageOverFileSizeMax : FriendImageResponse { */ @AnnotatedId(KnownPacketId.FRIEND_IMAGE_ID) @PacketVersion(date = "2019.11.16", timVersion = "2.3.2 (21173)") -object FriendImagePacket : SessionPacketFactory() { +internal object FriendImagePacket : SessionPacketFactory() { @Suppress("FunctionName") fun RequestImageId( bot: UInt, sessionKey: SessionKey, target: UInt, image: ExternalImage - ): OutgoingPacket = buildSessionPacket(bot, sessionKey, version = TIMProtocol.version0x04) { + ): OutgoingPacket = buildSessionPacket( + bot, + sessionKey, + version = TIMProtocol.version0x04, + name = "FriendImagePacket.RequestPacketId" + ) { writeHex("00 00 00 07 00 00") @@ -186,7 +190,12 @@ object FriendImagePacket : SessionPacketFactory() { // TODO: 2019/11/22 should be ProtoBuf - return buildSessionPacket(bot, sessionKey, version = TIMProtocol.version0x04) { + return buildSessionPacket( + bot, + sessionKey, + version = TIMProtocol.version0x04, + name = "FriendImagePacket.RequestImageLink" + ) { writeHex("00 00 00 07 00 00") writeUShort(0x004Bu) @@ -206,7 +215,11 @@ object FriendImagePacket : SessionPacketFactory() { } } - override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): FriendImageResponse { + override suspend fun ByteReadPacket.decode( + id: PacketId, + sequenceId: UShort, + handler: BotNetworkHandler<*> + ): FriendImageResponse { // 上传图片, 成功获取ID //00 00 00 08 00 00 @@ -304,7 +317,6 @@ object FriendImagePacket : SessionPacketFactory() { // 3A 00 80 01 00 - //00 00 00 08 00 00 // [02 29] // 12 [06] 98 01 02 A0 01 00 diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt index 107f538df..61ec3289b 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt @@ -17,7 +17,7 @@ import net.mamoe.mirai.utils.io.writeQQ * @author Him188moe */ @AnnotatedId(KnownPacketId.ACCOUNT_INFO) -object RequestAccountInfoPacket : SessionPacketFactory() { +internal object RequestAccountInfoPacket : SessionPacketFactory() { operator fun invoke( qq: UInt, sessionKey: SessionKey diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt index eb66eac9e..f4170e16d 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt @@ -21,7 +21,6 @@ import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.Http import net.mamoe.mirai.utils.assertUnreachable import net.mamoe.mirai.utils.io.toUHexString -import kotlin.coroutines.coroutineContext /** @@ -58,13 +57,13 @@ suspend fun Group.uploadImage(image: ExternalImage): ImageId = withSession { return image.groupImageId } -interface GroupImageResponse : EventPacket +internal interface GroupImageResponse : EventPacket // endregion @Suppress("unused") @Serializable -class ImageDownloadInfo( +class GroupImageLink( @SerialId(3) val errorCode: Int = 0, // 0 for success @SerialId(4) val errorMessage: String? = null, // 感动中国 @@ -84,13 +83,14 @@ class ImageDownloadInfo( override fun toString(): String = "ImageDownloadInfo(${_original?.let { original } ?: errorMessage ?: "unknown"})" } -fun ImageDownloadInfo.requireSuccess(): ImageDownloadInfo { +@Suppress("NOTHING_TO_INLINE") +internal inline fun GroupImageLink.requireSuccess(): GroupImageLink { require(this.errorCode == 0) { this.errorMessage ?: "null" } return this } @Serializable -class ImageUploadInfo( +internal class ImageUploadInfo( @SerialId(8) val uKey: ByteArray? = null ) : GroupImageResponse { override fun toString(): String = "ImageUploadInfo(uKey=${uKey?.toUHexString()})" @@ -101,7 +101,7 @@ class ImageUploadInfo( */ @AnnotatedId(KnownPacketId.GROUP_IMAGE_ID) @PacketVersion(date = "2019.11.22", timVersion = "2.3.2 (21173)") -object GroupImagePacket : SessionPacketFactory() { +internal object GroupImagePacket : SessionPacketFactory() { private val constValue3 = byteArrayOf( 0x28, 0x00, 0x5A, 0x00, 0x53, 0x00, 0x41, 0x00, 0x58, 0x00, 0x40, 0x00, 0x57, @@ -115,7 +115,7 @@ object GroupImagePacket : SessionPacketFactory() { @SerialId(3) var body: Body ) { @Serializable - class Body( + internal class Body( @SerialId(1) val group: Int, @SerialId(2) val bot: Int, @SerialId(3) val const1: Byte = 0, @@ -142,7 +142,7 @@ object GroupImagePacket : SessionPacketFactory() { @SerialId(4) var body: Body ) { @Serializable - class Body( + internal class Body( @SerialId(1) val group: Int, @SerialId(2) val bot: Int, @SerialId(3) val uniqueId: Int, @@ -226,13 +226,13 @@ object GroupImagePacket : SessionPacketFactory() { @Serializable data class GroupImageResponseProto( @SerialId(3) val imageUploadInfoPacket: ImageUploadInfo? = null, - @SerialId(4) val imageDownloadInfo: ImageDownloadInfo? = null + @SerialId(4) val groupImageLink: GroupImageLink? = null ) val proto = decodeProtoPacket(GroupImageResponseProto.serializer()) return when { proto.imageUploadInfoPacket != null -> proto.imageUploadInfoPacket - proto.imageDownloadInfo != null -> proto.imageDownloadInfo + proto.groupImageLink != null -> proto.groupImageLink else -> assertUnreachable() } } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupPacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupPacket.kt index e465d86df..e52d07c82 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupPacket.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupPacket.kt @@ -4,7 +4,7 @@ package net.mamoe.mirai.network.protocol.tim.packet.action import kotlinx.io.core.* import net.mamoe.mirai.contact.* -import net.mamoe.mirai.contact.internal.MemberImpl +import net.mamoe.mirai.contact.internal.Member import net.mamoe.mirai.message.MessageChain import net.mamoe.mirai.message.internal.toPacket import net.mamoe.mirai.network.BotNetworkHandler @@ -32,10 +32,11 @@ class GroupInfo( val announcement: String get() = _announcement val members: ContactList get() = _members - override fun toString(): String = "GroupInfo(id=${group.id}, owner=$owner, name=$name, announcement=$announcement, members=${members.idContentString}" + override fun toString(): String = + "GroupInfo(id=${group.id}, owner=$owner, name=$name, announcement=$announcement, members=${members.idContentString}" } -data class RawGroupInfo( +internal data class RawGroupInfo( val group: UInt, val owner: UInt, val name: String, @@ -49,10 +50,12 @@ data class RawGroupInfo( suspend inline fun parseBy(group: Group): GroupInfo = group.bot.withSession { return GroupInfo( group, - MemberImpl(this@RawGroupInfo.owner.qq(), group, MemberPermission.OWNER), + this@RawGroupInfo.owner.qq().let { Member(it, group, MemberPermission.OWNER, it.coroutineContext) }, this@RawGroupInfo.name, this@RawGroupInfo.announcement, - ContactList(this@RawGroupInfo.members.mapValuesTo(MutableContactList()) { MemberImpl(it.key.qq(), group, it.value) }) + ContactList(this@RawGroupInfo.members.mapValuesTo(MutableContactList()) { entry: Map.Entry -> + entry.key.qq().let { Member(it,group, entry.value, it.coroutineContext) } + }) ) } } @@ -69,14 +72,14 @@ inline class QuitGroupResponse(private val _group: GroupInternalId?) : Packet, G @Suppress("FunctionName") @AnnotatedId(KnownPacketId.GROUP_PACKET) -object GroupPacket : SessionPacketFactory() { +internal object GroupPacket : SessionPacketFactory() { @PacketVersion(date = "2019.10.19", timVersion = "2.3.2 (21173)") fun Message( bot: UInt, groupInternalId: GroupInternalId, sessionKey: SessionKey, message: MessageChain - ): OutgoingPacket = buildSessionPacket(bot, sessionKey, name = "GroupMessage") { + ): OutgoingPacket = buildSessionPacket(bot, sessionKey, name = "GroupPacket.GroupMessage") { writeUByte(0x2Au) writeGroup(groupInternalId) @@ -102,7 +105,7 @@ object GroupPacket : SessionPacketFactory() { bot: UInt, sessionKey: SessionKey, group: GroupInternalId - ): OutgoingPacket = buildSessionPacket(bot, sessionKey) { + ): OutgoingPacket = buildSessionPacket(bot, sessionKey, name = "GroupPacket.QuitGroup") { writeUByte(0x09u) writeGroup(group) } @@ -115,7 +118,7 @@ object GroupPacket : SessionPacketFactory() { bot: UInt, groupInternalId: GroupInternalId, sessionKey: SessionKey - ): OutgoingPacket = buildSessionPacket(bot, sessionKey, name = "QueryGroupInfo", headerSizeHint = 9) { + ): OutgoingPacket = buildSessionPacket(bot, sessionKey, name = "GroupPacket.QueryGroupInfo", headerSizeHint = 9) { writeUByte(0x72u) writeGroup(groupInternalId) writeZero(4) @@ -134,7 +137,7 @@ object GroupPacket : SessionPacketFactory() { * 0 为取消 */ timeSeconds: UInt - ): OutgoingPacket = buildSessionPacket(bot, sessionKey, name = "MuteMember") { + ): OutgoingPacket = buildSessionPacket(bot, sessionKey, name = "GroupPacket.Mute") { writeUByte(0x7Eu) writeGroup(groupInternalId) writeByte(0x20) @@ -144,21 +147,25 @@ object GroupPacket : SessionPacketFactory() { writeUInt(timeSeconds) } - interface GroupPacketResponse : Packet + internal interface GroupPacketResponse : Packet @NoLog - object MessageResponse : Packet, GroupPacketResponse { + internal object MessageResponse : Packet, GroupPacketResponse { override fun toString(): String = "GroupPacket.MessageResponse" } @NoLog - object MuteResponse : Packet, GroupPacketResponse { + internal object MuteResponse : Packet, GroupPacketResponse { override fun toString(): String = "GroupPacket.MuteResponse" } @PacketVersion(date = "2019.11.27", timVersion = "2.3.2 (21173)") @UseExperimental(ExperimentalStdlibApi::class) - override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): GroupPacketResponse { + override suspend fun ByteReadPacket.decode( + id: PacketId, + sequenceId: UShort, + handler: BotNetworkHandler<*> + ): GroupPacketResponse { return when (readUByte().toUInt()) { 0x2Au -> MessageResponse 0x7Eu -> MuteResponse // 成功: 7E 00 22 96 29 7B; diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/Profile.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/Profile.kt index ea03337f8..47bdb62f1 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/Profile.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/Profile.kt @@ -15,7 +15,7 @@ import net.mamoe.mirai.utils.io.* * 请求获取头像 */ @AnnotatedId(KnownPacketId.REQUEST_PROFILE_AVATAR) -object RequestProfileAvatarPacket : SessionPacketFactory() { +internal object RequestProfileAvatarPacket : SessionPacketFactory() { //00 01 00 17 D4 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 29 4E 22 4E 25 4E 26 4E 27 4E 29 4E 2A 4E 2B 4E 2D 4E 2E 4E 2F 4E 30 4E 31 4E 33 4E 35 4E 36 4E 37 4E 38 4E 3F 4E 40 4E 41 4E 42 4E 43 4E 45 4E 49 4E 4B 4E 4F 4E 54 4E 5B 52 0B 52 0F 5D C2 5D C8 65 97 69 9D 69 A9 9D A5 A4 91 A4 93 A4 94 A4 9C A4 B5 operator fun invoke( bot: UInt, @@ -39,7 +39,7 @@ object RequestProfileAvatarPacket : SessionPacketFactory() { * @see Profile */ @AnnotatedId(KnownPacketId.REQUEST_PROFILE_DETAILS) -object RequestProfileDetailsPacket : SessionPacketFactory() { +internal object RequestProfileDetailsPacket : SessionPacketFactory() { //00 01 3E F8 FB E3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 29 4E 22 4E 25 4E 26 4E 27 4E 29 4E 2A 4E 2B 4E 2D 4E 2E 4E 2F 4E 30 4E 31 4E 33 4E 35 4E 36 4E 37 4E 38 4E 3F 4E 40 4E 41 4E 42 4E 43 4E 45 4E 49 4E 4B 4E 4F 4E 54 4E 5B 52 0B 52 0F 5D C2 5D C8 65 97 69 9D 69 A9 9D A5 A4 91 A4 93 A4 94 A4 9C A4 B5 //00 01 B1 89 BE 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 29 4E 22 4E 25 4E 26 4E 27 4E 29 4E 2A 4E 2B 4E 2D 4E 2E 4E 2F 4E 30 4E 31 4E 33 4E 35 4E 36 4E 37 4E 38 4E 3F 4E 40 4E 41 4E 42 4E 43 4E 45 4E 49 4E 4B 4E 4F 4E 54 4E 5B 52 0B 52 0F 5D C2 5D C8 65 97 69 9D 69 A9 9D A5 A4 91 A4 93 A4 94 A4 9C A4 B5 //00 01 87 73 86 9D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 29 4E 22 4E 25 4E 26 4E 27 4E 29 4E 2A 4E 2B 4E 2D 4E 2E 4E 2F 4E 30 4E 31 4E 33 4E 35 4E 36 4E 37 4E 38 4E 3F 4E 40 4E 41 4E 42 4E 43 4E 45 4E 49 4E 4B 4E 4F 4E 54 4E 5B 52 0B 52 0F 5D C2 5D C8 65 97 69 9D 69 A9 9D A5 A4 91 A4 93 A4 94 A4 9C A4 B5 @@ -91,7 +91,7 @@ object RequestProfileDetailsPacket : SessionPacketFactory() { +internal object QueryFriendRemarkPacket : SessionPacketFactory() { /** * 查询好友的备注 */ diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/RequestFriendListPacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/RequestFriendListPacket.kt index b3afd8689..1629b55c8 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/RequestFriendListPacket.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/RequestFriendListPacket.kt @@ -11,7 +11,7 @@ import net.mamoe.mirai.utils.io.writeZero class FriendList : Packet @PacketVersion(date = "2019.11.24", timVersion = "2.3.2 (21173)") -object RequestFriendListPacket : SessionPacketFactory() { +internal object RequestFriendListPacket : SessionPacketFactory() { operator fun invoke( bot: UInt, sessionKey: SessionKey diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/SendFriendMessagePacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/SendFriendMessagePacket.kt index 45290cc94..b009c84ce 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/SendFriendMessagePacket.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/SendFriendMessagePacket.kt @@ -13,7 +13,7 @@ import net.mamoe.mirai.utils.md5 @AnnotatedId(KnownPacketId.SEND_FRIEND_MESSAGE) @PacketVersion(date = "2019.10.19", timVersion = "2.3.2 (21173)") -object SendFriendMessagePacket : SessionPacketFactory() { +internal object SendFriendMessagePacket : SessionPacketFactory() { operator fun invoke( botQQ: UInt, targetQQ: UInt, @@ -65,7 +65,7 @@ object SendFriendMessagePacket : SessionPacketFactory = +internal fun matchEventPacketFactory(value: UShort): EventParserAndHandler<*> = KnownEventParserAndHandler.firstOrNull { it.id == value } ?: IgnoredEventIds.firstOrNull { it.id == value } ?: UnknownEventParserAndHandler(value) /** @@ -37,14 +38,14 @@ fun matchEventPacketFactory(value: UShort): EventParserAndHandler<*> = */ @NoLog @Suppress("FunctionName") -object EventPacketFactory : PacketFactory(SessionKey) { +internal object EventPacketFactory : PacketFactory(SessionKey) { override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): Packet { val eventIdentity = EventPacketIdentity( from = readUInt(), to = readUInt(), uniqueId = readIoBuffer(8) ) - handler.sendPacket(EventPacketFactory(id, sequenceId, handler.bot.qqAccount, handler.sessionKey, eventIdentity)) + (handler as TIMBotNetworkHandler).socket.sendPacket(EventPacketFactory(id, sequenceId, handler.bot.qqAccount, handler.sessionKey, eventIdentity)) discardExact(2) // 1F 40 return with(matchEventPacketFactory(readUShort())) { parse(handler.bot, eventIdentity) }.also { @@ -75,7 +76,7 @@ object EventPacketFactory : PacketFactory(SessionKey) { } } -interface EventParserAndHandler { +internal interface EventParserAndHandler { val id: UShort suspend fun ByteReadPacket.parse(bot: Bot, identity: EventPacketIdentity): TPacket @@ -86,7 +87,7 @@ interface EventParserAndHandler { suspend fun BotNetworkHandler<*>.handlePacket(packet: TPacket) {} } -abstract class KnownEventParserAndHandler(override val id: UShort) : EventParserAndHandler { +internal abstract class KnownEventParserAndHandler(override val id: UShort) : EventParserAndHandler { companion object FactoryList : MutableList> by mutableListOf( AndroidDeviceOnlineStatusChangedEventFactory, FriendConversationInitializedEventParserAndHandler, diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/FriendOnlineStatusChanged.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/FriendOnlineStatusChanged.kt index 4de8a085c..b60fac6dc 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/FriendOnlineStatusChanged.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/FriendOnlineStatusChanged.kt @@ -24,7 +24,7 @@ data class FriendStatusChanged( * 好友在线状态改变 */ @AnnotatedId(KnownPacketId.FRIEND_ONLINE_STATUS_CHANGE) -object FriendOnlineStatusChangedPacket : SessionPacketFactory() { +internal object FriendOnlineStatusChangedPacket : SessionPacketFactory() { override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): FriendStatusChanged { val qq = readUInt() diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Ignored.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Ignored.kt index 286f7fa5d..e6036f76a 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Ignored.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Ignored.kt @@ -6,17 +6,17 @@ import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.Bot import net.mamoe.mirai.utils.io.toUHexString -inline class IgnoredEventPacket(val id: UShort) : EventPacket { +internal inline class IgnoredEventPacket(val id: UShort) : EventPacket { override fun toString(): String = "IgnoredEventPacket(id=0x${id.toUHexString("")})" } -object IgnoredEventIds : List by { +internal object IgnoredEventIds : List by { listOf( //0x0021u, // 与群成员加入有关 0x0210u // 新朋友等字符串通知 ).map { IgnoredEventParserAndHandler(it.toUShort()) } }() -inline class IgnoredEventParserAndHandler(override val id: UShort) : EventParserAndHandler { +internal inline class IgnoredEventParserAndHandler(override val id: UShort) : EventParserAndHandler { override suspend fun ByteReadPacket.parse(bot: Bot, identity: EventPacketIdentity): IgnoredEventPacket = IgnoredEventPacket(id) } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt index 53d551898..76476a406 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt @@ -8,6 +8,7 @@ import net.mamoe.mirai.Bot import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.MemberPermission +import net.mamoe.mirai.contact.internal.Member import net.mamoe.mirai.contact.internal.MemberImpl import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.event.broadcast @@ -74,7 +75,8 @@ internal object MemberJoinPacketHandler : KnownEventParserAndHandler { +internal class UnknownEventParserAndHandler(override val id: UShort) : EventParserAndHandler { override suspend fun ByteReadPacket.parse(bot: Bot, identity: EventPacketIdentity): UnknownEventPacket { // MiraiLogger.debug("UnknownEventPacket(${id.toUHexString()}) = ${readBytes().toUHexString()}") diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Captcha.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Captcha.kt index 872e6ed53..75c7bdefb 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Captcha.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Captcha.kt @@ -8,12 +8,12 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.packet.* import net.mamoe.mirai.utils.io.* -object CaptchaKey : DecrypterByteArray, DecrypterType { +internal object CaptchaKey : DecrypterByteArray, DecrypterType { override val value: ByteArray = TIMProtocol.key00BA } @AnnotatedId(KnownPacketId.CAPTCHA) -object CaptchaPacket : PacketFactory(CaptchaKey) { +internal object CaptchaPacket : PacketFactory(CaptchaKey) { /** * 请求验证码传输 */ @@ -97,7 +97,7 @@ object CaptchaPacket : PacketFactory( } } - sealed class CaptchaResponse : Packet { + internal sealed class CaptchaResponse : Packet { lateinit var token00BA: ByteArray//56 bytes class Correct : CaptchaResponse() { diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/ChangeOnlineStatusPacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/ChangeOnlineStatusPacket.kt index a553546c6..abbc4f8e4 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/ChangeOnlineStatusPacket.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/ChangeOnlineStatusPacket.kt @@ -17,7 +17,7 @@ import net.mamoe.mirai.utils.io.writeQQ * 改变在线状态: "我在线上", "隐身" 等 */ @AnnotatedId(KnownPacketId.CHANGE_ONLINE_STATUS) -object ChangeOnlineStatusPacket : PacketFactory(NoDecrypter) { +internal object ChangeOnlineStatusPacket : PacketFactory(NoDecrypter) { operator fun invoke( bot: UInt, sessionKey: SessionKey, @@ -32,7 +32,7 @@ object ChangeOnlineStatusPacket : PacketFactory() { +internal object HeartbeatPacket : SessionPacketFactory() { operator fun invoke( bot: UInt, sessionKey: SessionKey @@ -32,4 +32,4 @@ object HeartbeatPacket : SessionPacketFactory() { @NoLog @AnnotatedId(KnownPacketId.HEARTBEAT) -object HeartbeatPacketResponse : Packet, Subscribable \ No newline at end of file +internal object HeartbeatPacketResponse : Packet, Subscribable \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/PasswordSubmission.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/PasswordSubmission.kt index 048176cf8..41131469d 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/PasswordSubmission.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/PasswordSubmission.kt @@ -13,15 +13,15 @@ import net.mamoe.mirai.utils.encryptBy import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.writeCRC32 -object ShareKey : DecrypterByteArray, DecrypterType { +internal object ShareKey : DecrypterByteArray, DecrypterType { override val value: ByteArray = TIMProtocol.shareKey } -inline class PrivateKey(override val value: ByteArray) : DecrypterByteArray { +internal inline class PrivateKey(override val value: ByteArray) : DecrypterByteArray { companion object Type : DecrypterType } -inline class SubmitPasswordResponseDecrypter(private val privateKey: PrivateKey) : Decrypter { +internal inline class SubmitPasswordResponseDecrypter(private val privateKey: PrivateKey) : Decrypter { override fun decrypt(input: ByteReadPacket): ByteReadPacket { var decrypted = ShareKey.decrypt(input) (decrypted.remaining).let { @@ -45,7 +45,7 @@ inline class SubmitPasswordResponseDecrypter(private val privateKey: PrivateKey) * 提交密码 */ @AnnotatedId(KnownPacketId.LOGIN) -object SubmitPasswordPacket : PacketFactory(SubmitPasswordResponseDecrypter) { +internal object SubmitPasswordPacket : PacketFactory(SubmitPasswordResponseDecrypter) { operator fun invoke( bot: UInt, password: String, @@ -76,7 +76,7 @@ object SubmitPasswordPacket : PacketFactory(SessionResponseDecryptionKey) { +internal object RequestSessionPacket : PacketFactory(SessionResponseDecryptionKey) { operator fun invoke( bot: UInt, serverIp: String, @@ -59,7 +59,7 @@ object RequestSessionPacket : PacketFactory { +internal object TouchKey : DecrypterByteArray, DecrypterType { override val value: ByteArray = TIMProtocol.touchKey } @@ -21,7 +21,7 @@ object TouchKey : DecrypterByteArray, DecrypterType { * @author Him188moe */ @AnnotatedId(KnownPacketId.TOUCH) -object TouchPacket : PacketFactory(TouchKey) { +internal object TouchPacket : PacketFactory(TouchKey) { operator fun invoke( bot: UInt, serverIp: String, @@ -45,7 +45,7 @@ object TouchPacket : PacketFactory(TouchKey } } - sealed class TouchResponse : Packet { + internal sealed class TouchResponse : Packet { class OK( var loginTime: Int, val loginIP: String, diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/TEA.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/TEA.kt index 790fe3282..822ce3d0e 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/TEA.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/TEA.kt @@ -17,7 +17,7 @@ import kotlin.random.Random /** * 解密错误 */ -class DecryptionFailedException : Exception() +internal class DecryptionFailedException : Exception() // region encrypt @@ -28,9 +28,9 @@ class DecryptionFailedException : Exception() * @param key 长度至少为 16 * @throws DecryptionFailedException 解密错误时 */ -fun ByteArray.encryptBy(key: ByteArray, length: Int = this.size): ByteArray = TEA.encrypt(this, key, sourceLength = length) +internal fun ByteArray.encryptBy(key: ByteArray, length: Int = this.size): ByteArray = TEA.encrypt(this, key, sourceLength = length) -fun ByteArray.encryptBy(key: DecrypterByteArray, length: Int = this.size): ByteArray = TEA.encrypt(this, key.value, sourceLength = length) +internal fun ByteArray.encryptBy(key: DecrypterByteArray, length: Int = this.size): ByteArray = TEA.encrypt(this, key.value, sourceLength = length) /** * 在 [ByteArrayPool] 缓存 [this], 然后使用 [key] 加密. @@ -39,7 +39,7 @@ fun ByteArray.encryptBy(key: DecrypterByteArray, length: Int = this.size): ByteA * @consumer 由于缓存需要被回收, 需在方法内执行解密后明文的消耗过程 * @throws DecryptionFailedException 解密错误时 */ -inline fun ByteReadPacket.encryptBy(key: ByteArray, offset: Int = 0, length: Int = remaining.toInt() - offset, consumer: (ByteArray) -> Unit) { +internal inline fun ByteReadPacket.encryptBy(key: ByteArray, offset: Int = 0, length: Int = remaining.toInt() - offset, consumer: (ByteArray) -> Unit) { ByteArrayPool.useInstance { this.readFully(it, offset, length) consumer(it.encryptBy(key, length = length)) @@ -57,7 +57,7 @@ inline fun ByteReadPacket.encryptBy(key: ByteArray, offset: Int = 0, length: Int * @param key 固定长度 16 * @throws DecryptionFailedException 解密错误时 */ -fun ByteArray.decryptBy(key: ByteArray, length: Int = this.size): ByteArray = +internal fun ByteArray.decryptBy(key: ByteArray, length: Int = this.size): ByteArray = TEA.decrypt(checkDataLengthAndReturnSelf(length), key, sourceLength = length) /** @@ -68,7 +68,7 @@ fun ByteArray.decryptBy(key: ByteArray, length: Int = this.size): ByteArray = * @param key 长度至少为 16 * @throws DecryptionFailedException 解密错误时 */ -fun ByteArray.decryptBy(key: IoBuffer, length: Int = this.size): ByteArray { +internal fun ByteArray.decryptBy(key: IoBuffer, length: Int = this.size): ByteArray { checkDataLengthAndReturnSelf(length) return ByteArrayPool.useInstance { keyBuffer -> key.readFully(keyBuffer, 0, key.readRemaining) @@ -82,7 +82,7 @@ fun ByteArray.decryptBy(key: IoBuffer, length: Int = this.size): ByteArray { * @param key 长度至少为 16 * @throws DecryptionFailedException 解密错误时 */ -fun IoBuffer.decryptBy(key: ByteArray, offset: Int = 0, length: Int = readRemaining - offset): ByteArray { +internal fun IoBuffer.decryptBy(key: ByteArray, offset: Int = 0, length: Int = readRemaining - offset): ByteArray { return ByteArrayPool.useInstance { this.readFully(it, offset, length) it.checkDataLengthAndReturnSelf(length) @@ -94,20 +94,20 @@ fun IoBuffer.decryptBy(key: ByteArray, offset: Int = 0, length: Int = readRemain // region ByteReadPacket extension -fun ByteReadPacket.decryptBy(key: ByteArray): ByteReadPacket = decryptAsByteArray(key) { data -> ByteReadPacket(data, 0) } +internal fun ByteReadPacket.decryptBy(key: ByteArray): ByteReadPacket = decryptAsByteArray(key) { data -> ByteReadPacket(data, 0) } -fun ByteReadPacket.decryptBy(key: IoBuffer): ByteReadPacket = decryptAsByteArray(key) { data -> ByteReadPacket(data, 0) } +internal fun ByteReadPacket.decryptBy(key: IoBuffer): ByteReadPacket = decryptAsByteArray(key) { data -> ByteReadPacket(data, 0) } -fun ByteReadPacket.decryptBy(key: Decrypter): ByteReadPacket = key.decrypt(this) +internal fun ByteReadPacket.decryptBy(key: Decrypter): ByteReadPacket = key.decrypt(this) -inline fun ByteReadPacket.decryptAsByteArray(key: ByteArray, consumer: (ByteArray) -> R): R = +internal inline fun ByteReadPacket.decryptAsByteArray(key: ByteArray, consumer: (ByteArray) -> R): R = ByteArrayPool.useInstance { val length = remaining.toInt() readFully(it, 0, length) consumer(it.decryptBy(key, length)) }.also { close() } -inline fun ByteReadPacket.decryptAsByteArray(key: IoBuffer, consumer: (ByteArray) -> R): R = +internal inline fun ByteReadPacket.decryptAsByteArray(key: IoBuffer, consumer: (ByteArray) -> R): R = ByteArrayPool.useInstance { val length = remaining.toInt() readFully(it, 0, length) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt index c44d2ec1e..f09596553 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt @@ -16,46 +16,46 @@ import net.mamoe.mirai.utils.internal.coerceAtMostOrFail import kotlin.random.Random import kotlin.random.nextInt -fun BytePacketBuilder.writeZero(count: Int) { +internal fun BytePacketBuilder.writeZero(count: Int) { require(count != 0) { "Trying to write zero with count 0, you made a mistake?" } require(count > 0) { "writeZero: count must > 0" } repeat(count) { this.writeByte(0) } } -fun BytePacketBuilder.writeRandom(length: Int) = repeat(length) { this.writeByte(Random.Default.nextInt(255).toByte()) } +internal fun BytePacketBuilder.writeRandom(length: Int) = repeat(length) { this.writeByte(Random.Default.nextInt(255).toByte()) } -fun BytePacketBuilder.writeQQ(qq: Long) = this.writeUInt(qq.toUInt()) -fun BytePacketBuilder.writeQQ(qq: UInt) = this.writeUInt(qq) -fun BytePacketBuilder.writeGroup(groupId: GroupId) = this.writeUInt(groupId.value) -fun BytePacketBuilder.writeGroup(groupInternalId: GroupInternalId) = this.writeUInt(groupInternalId.value) -fun BytePacketBuilder.writeFully(value: DecrypterByteArray) = this.writeFully(value.value) +internal fun BytePacketBuilder.writeQQ(qq: Long) = this.writeUInt(qq.toUInt()) +internal fun BytePacketBuilder.writeQQ(qq: UInt) = this.writeUInt(qq) +internal fun BytePacketBuilder.writeGroup(groupId: GroupId) = this.writeUInt(groupId.value) +internal fun BytePacketBuilder.writeGroup(groupInternalId: GroupInternalId) = this.writeUInt(groupInternalId.value) +internal fun BytePacketBuilder.writeFully(value: DecrypterByteArray) = this.writeFully(value.value) -fun BytePacketBuilder.writeShortLVByteArray(byteArray: ByteArray) { +internal fun BytePacketBuilder.writeShortLVByteArray(byteArray: ByteArray) { this.writeShort(byteArray.size.toShort()) this.writeFully(byteArray) } -fun BytePacketBuilder.writeShortLVPacket(tag: UByte? = null, lengthOffset: ((Long) -> Long)? = null, builder: BytePacketBuilder.() -> Unit) = +internal fun BytePacketBuilder.writeShortLVPacket(tag: UByte? = null, lengthOffset: ((Long) -> Long)? = null, builder: BytePacketBuilder.() -> Unit) = BytePacketBuilder().apply(builder).build().use { if (tag != null) writeUByte(tag) writeUShort((lengthOffset?.invoke(it.remaining) ?: it.remaining).coerceAtMostOrFail(0xFFFFL).toUShort()) writePacket(it) } -fun BytePacketBuilder.writeUVarIntLVPacket(tag: UByte? = null, lengthOffset: ((Long) -> Long)? = null, builder: BytePacketBuilder.() -> Unit) = +internal fun BytePacketBuilder.writeUVarIntLVPacket(tag: UByte? = null, lengthOffset: ((Long) -> Long)? = null, builder: BytePacketBuilder.() -> Unit) = BytePacketBuilder().apply(builder).build().use { if (tag != null) writeUByte(tag) writeUVarInt((lengthOffset?.invoke(it.remaining) ?: it.remaining).coerceAtMostOrFail(0xFFFFL)) writePacket(it) } -fun BytePacketBuilder.writeShortLVString(str: String) = writeShortLVByteArray(str.toByteArray()) +internal fun BytePacketBuilder.writeShortLVString(str: String) = writeShortLVByteArray(str.toByteArray()) -fun BytePacketBuilder.writeIP(ip: String) = writeFully(ip.trim().split(".").map { it.toUByte() }.toUByteArray()) +internal fun BytePacketBuilder.writeIP(ip: String) = writeFully(ip.trim().split(".").map { it.toUByte() }.toUByteArray()) -fun BytePacketBuilder.writeTime() = this.writeInt(currentTime.toInt()) +internal fun BytePacketBuilder.writeTime() = this.writeInt(currentTime.toInt()) -fun BytePacketBuilder.writeHex(uHex: String) { +internal fun BytePacketBuilder.writeHex(uHex: String) { uHex.split(" ").forEach { if (it.isNotBlank()) { writeUByte(it.toUByte(16)) @@ -63,49 +63,49 @@ fun BytePacketBuilder.writeHex(uHex: String) { } } -fun BytePacketBuilder.writeProto(serializer: SerializationStrategy, obj: T) = writeFully(ProtoBuf.dump(serializer, obj)) +internal fun BytePacketBuilder.writeProto(serializer: SerializationStrategy, obj: T) = writeFully(ProtoBuf.dump(serializer, obj)) -fun BytePacketBuilder.writeTLV(tag: UByte, values: UByteArray) { +internal fun BytePacketBuilder.writeTLV(tag: UByte, values: UByteArray) { writeUByte(tag) writeUVarInt(values.size.toUInt()) writeFully(values) } -fun BytePacketBuilder.writeTLV(tag: UByte, values: ByteArray) { +internal fun BytePacketBuilder.writeTLV(tag: UByte, values: ByteArray) { writeUByte(tag) writeUVarInt(values.size.toUInt()) writeFully(values) } -fun BytePacketBuilder.writeTHex(tag: UByte, uHex: String) { +internal fun BytePacketBuilder.writeTHex(tag: UByte, uHex: String) { this.writeUByte(tag) this.writeFully(uHex.hexToUBytes()) } -fun BytePacketBuilder.writeTV(tagValue: UShort) = writeUShort(tagValue) +internal fun BytePacketBuilder.writeTV(tagValue: UShort) = writeUShort(tagValue) -fun BytePacketBuilder.writeTV(tag: UByte, value: UByte) { +internal fun BytePacketBuilder.writeTV(tag: UByte, value: UByte) { writeUByte(tag) writeUByte(value) } -fun BytePacketBuilder.writeTUbyte(tag: UByte, value: UByte) { +internal fun BytePacketBuilder.writeTUbyte(tag: UByte, value: UByte) { this.writeUByte(tag) this.writeUByte(value) } -fun BytePacketBuilder.writeTUVarint(tag: UByte, value: UInt) { +internal fun BytePacketBuilder.writeTUVarint(tag: UByte, value: UInt) { this.writeUByte(tag) this.writeUVarInt(value) } -fun BytePacketBuilder.writeTByteArray(tag: UByte, value: ByteArray) { +internal fun BytePacketBuilder.writeTByteArray(tag: UByte, value: ByteArray) { this.writeUByte(tag) this.writeFully(value) } -fun BytePacketBuilder.writeTByteArray(tag: UByte, value: UByteArray) { +internal fun BytePacketBuilder.writeTByteArray(tag: UByte, value: UByteArray) { this.writeUByte(tag) this.writeFully(value) } @@ -113,19 +113,19 @@ fun BytePacketBuilder.writeTByteArray(tag: UByte, value: UByteArray) { /** * 会使用 [ByteArrayPool] 缓存 */ -inline fun BytePacketBuilder.encryptAndWrite(key: ByteArray, encoder: BytePacketBuilder.() -> Unit) = +internal inline fun BytePacketBuilder.encryptAndWrite(key: ByteArray, encoder: BytePacketBuilder.() -> Unit) = BytePacketBuilder().apply(encoder).build().encryptBy(key) { decrypted -> writeFully(decrypted) } -inline fun BytePacketBuilder.encryptAndWrite(key: IoBuffer, encoder: BytePacketBuilder.() -> Unit) = ByteArrayPool.useInstance { +internal inline fun BytePacketBuilder.encryptAndWrite(key: IoBuffer, encoder: BytePacketBuilder.() -> Unit) = ByteArrayPool.useInstance { key.readFully(it, 0, key.readRemaining) encryptAndWrite(it, encoder) } -inline fun BytePacketBuilder.encryptAndWrite(key: DecrypterByteArray, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(key.value, encoder) +internal inline fun BytePacketBuilder.encryptAndWrite(key: DecrypterByteArray, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(key.value, encoder) -inline fun BytePacketBuilder.encryptAndWrite(keyHex: String, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(keyHex.hexToBytes(), encoder) +internal inline fun BytePacketBuilder.encryptAndWrite(keyHex: String, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(keyHex.hexToBytes(), encoder) -fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, loginIP: String, privateKey: PrivateKey) { +internal fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, loginIP: String, privateKey: PrivateKey) { val firstMD5 = md5(password) val secondMD5 = md5(firstMD5 + byteArrayOf(0, 0, 0, 0) + qq.toUInt().toByteArray()) @@ -149,7 +149,7 @@ fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, l } @Tested -fun BytePacketBuilder.writeDeviceName(random: Boolean) { +internal fun BytePacketBuilder.writeDeviceName(random: Boolean) { val deviceName: String = if (random) { "DESKTOP-" + String(ByteArray(7) { (if (Random.nextBoolean()) Random.nextInt('A'.toInt()..'Z'.toInt())