diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/TIMPCBot.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/TIMPCBot.kt index e33034036..7348f0c4a 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/TIMPCBot.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/TIMPCBot.kt @@ -11,6 +11,9 @@ import net.mamoe.mirai.data.Packet import net.mamoe.mirai.message.data.Image import net.mamoe.mirai.message.data.ImageId0x03 import net.mamoe.mirai.message.data.ImageId0x06 +import net.mamoe.mirai.network.packet.KnownPacketId +import net.mamoe.mirai.network.packet.OutgoingPacket +import net.mamoe.mirai.network.packet.SessionKey import net.mamoe.mirai.qqAccount import net.mamoe.mirai.timpc.internal.RawGroupInfo import net.mamoe.mirai.timpc.network.GroupImpl @@ -18,10 +21,10 @@ import net.mamoe.mirai.timpc.network.MemberImpl import net.mamoe.mirai.timpc.network.QQImpl import net.mamoe.mirai.timpc.network.TIMBotNetworkHandler import net.mamoe.mirai.timpc.network.handler.TemporaryPacketHandler -import net.mamoe.mirai.timpc.network.packet.KnownPacketId -import net.mamoe.mirai.timpc.network.packet.OutgoingPacket -import net.mamoe.mirai.timpc.network.packet.SessionKey import net.mamoe.mirai.timpc.network.packet.action.* +import net.mamoe.mirai.timpc.network.packet.event.EventPacketFactory +import net.mamoe.mirai.timpc.network.packet.event.FriendOnlineStatusChangedPacket +import net.mamoe.mirai.timpc.network.packet.login.* import net.mamoe.mirai.timpc.utils.assertUnreachable import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail @@ -44,9 +47,41 @@ internal abstract class TIMPCBotBase constructor( logger: MiraiLogger?, context: CoroutineContext ) : BotImpl(account, logger ?: DefaultLogger("Bot(" + account.id + ")"), context) { + + @UseExperimental(ExperimentalUnsignedTypes::class) companion object { init { - KnownPacketId.values() /* load id classes */ + KnownPacketId[0x0825u] = TouchPacket + KnownPacketId[0x0828u] = RequestSessionPacket + KnownPacketId[0x0836u] = SubmitPasswordPacket + KnownPacketId[0x00BAu] = CaptchaPacket + KnownPacketId[0x00CEu] = EventPacketFactory + KnownPacketId[0x0017u] = EventPacketFactory + KnownPacketId[0x0081u] = FriendOnlineStatusChangedPacket + KnownPacketId[0x00ECu] = ChangeOnlineStatusPacket + + KnownPacketId[0x0058u] = HeartbeatPacket + KnownPacketId[0x001Du] = RequestSKeyPacket + KnownPacketId[0x005Cu] = RequestAccountInfoPacket + KnownPacketId[0x0002u] = GroupPacket + KnownPacketId[0x00CDu] = SendFriendMessagePacket + KnownPacketId[0x00A7u] = CanAddFriendPacket + KnownPacketId[0x00A8u] = AddFriendPacket + KnownPacketId[0x00AEu] = RequestFriendAdditionKeyPacket + KnownPacketId[0x0388u] = GroupImagePacket + KnownPacketId[0x0352u] = FriendImagePacket + + KnownPacketId[0x0031u] = RequestProfileAvatarPacket + KnownPacketId[0x003Cu] = RequestProfileDetailsPacket + KnownPacketId[0x0126u] = QueryNicknamePacket + + KnownPacketId[0x01BCu] = QueryPreviousNamePacket + + KnownPacketId[0x003Eu] = QueryFriendRemarkPacket + // 031F 查询 "新朋友" 记录 + + // @Suppress("DEPRECATION") + // inline SUBMIT_IMAGE_FILE_NAME(0x01BDu, SubmitImageFilenamePacket), } } @@ -69,7 +104,7 @@ internal abstract class TIMPCBotBase constructor( reinitializeNetworkHandler(configuration, cause) logger.info("Reconnected successfully") return@launch - } catch (e: LoginFailedException){ + } catch (e: LoginFailedException) { delay(configuration.reconnectPeriodMillis) } } diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMBotNetworkHandler.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMBotNetworkHandler.kt index c5d994a1f..de4f5860d 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMBotNetworkHandler.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/TIMBotNetworkHandler.kt @@ -6,19 +6,19 @@ import kotlinx.coroutines.* import kotlinx.io.core.* import kotlinx.io.pool.useInstance import net.mamoe.mirai.Bot +import net.mamoe.mirai.data.LoginResult +import net.mamoe.mirai.data.Packet import net.mamoe.mirai.event.BroadcastControllable import net.mamoe.mirai.event.Cancellable import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.events.BotLoginSucceedEvent import net.mamoe.mirai.network.BotNetworkHandler -import net.mamoe.mirai.data.LoginResult -import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.qqAccount import net.mamoe.mirai.timpc.TIMPCBot import net.mamoe.mirai.timpc.network.handler.DataPacketSocketAdapter import net.mamoe.mirai.timpc.network.handler.TemporaryPacketHandler -import net.mamoe.mirai.timpc.network.packet.* import net.mamoe.mirai.timpc.network.packet.login.* import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.io.* diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacketHelper.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacketHelper.kt new file mode 100644 index 000000000..e61bb9389 --- /dev/null +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacketHelper.kt @@ -0,0 +1,97 @@ +package net.mamoe.mirai.timpc.network.packet + +import kotlinx.io.core.BytePacketBuilder +import kotlinx.serialization.SerializationStrategy +import net.mamoe.mirai.network.packet.* +import net.mamoe.mirai.timpc.network.TIMProtocol +import net.mamoe.mirai.utils.MiraiInternalAPI +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract +import kotlin.jvm.JvmOverloads + + +/** + * 构造一个待发送给服务器的数据包. + */ +@UseExperimental(ExperimentalContracts::class, MiraiInternalAPI::class, ExperimentalUnsignedTypes::class) +@JvmOverloads +inline fun PacketFactory<*, *>.buildOutgoingPacket( + name: String? = null, + id: PacketId = this.id, + sequenceId: UShort = PacketFactory.atomicNextSequenceId(), + headerSizeHint: Int = 0, + block: BytePacketBuilder.() -> Unit +): OutgoingPacket { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + + return buildOutgoingPacket0(name, id, sequenceId, headerSizeHint, TIMProtocol.head, TIMProtocol.ver, TIMProtocol.tail, block) +} + + +/** + * 构造一个待发送给服务器的会话数据包. + */ +@UseExperimental(ExperimentalContracts::class, MiraiInternalAPI::class, ExperimentalUnsignedTypes::class) +@JvmOverloads +inline fun PacketFactory<*, *>.buildSessionPacket( + bot: Long, + sessionKey: SessionKey, + name: String? = null, + id: PacketId = this.id, + sequenceId: UShort = PacketFactory.atomicNextSequenceId(), + headerSizeHint: Int = 0, + version: ByteArray = TIMProtocol.version0x02, // in packet body + block: BytePacketBuilder.() -> Unit +): OutgoingPacket { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return buildSessionPacket0( + bot = bot, + sessionKey = sessionKey, + name = name, + id = id, + sequenceId = sequenceId, + headerSizeHint = headerSizeHint, + version = version, + head = TIMProtocol.head, + ver = TIMProtocol.ver, + tail = TIMProtocol.tail, + block = block + ) +} + +/** + * 构造一个待发送给服务器的会话数据包. + */ +@UseExperimental(ExperimentalContracts::class, MiraiInternalAPI::class, ExperimentalUnsignedTypes::class) +@JvmOverloads +fun PacketFactory<*, *>.buildSessionProtoPacket( + bot: Long, + sessionKey: SessionKey, + name: String? = null, + id: PacketId = this.id, + sequenceId: UShort = PacketFactory.atomicNextSequenceId(), + headerSizeHint: Int = 0, + version: ByteArray = TIMProtocol.version0x04, + head: Any, + serializer: SerializationStrategy, + protoObj: T +): OutgoingPacket = buildSessionProtoPacket0( + bot = bot, + sessionKey = sessionKey, + name = name, + id = id, + sequenceId = sequenceId, + headerSizeHint = headerSizeHint, + version = version, + head = head, + serializer = serializer, + protoObj = protoObj, + packetHead = TIMProtocol.head, + ver = TIMProtocol.ver, + tail = TIMProtocol.tail +) \ No newline at end of file diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketId.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketId.kt deleted file mode 100644 index a40d0be92..000000000 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketId.kt +++ /dev/null @@ -1,100 +0,0 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") - -package net.mamoe.mirai.timpc.network.packet - -import net.mamoe.mirai.timpc.network.packet.action.* -import net.mamoe.mirai.timpc.network.packet.event.EventPacketFactory -import net.mamoe.mirai.timpc.network.packet.event.FriendOnlineStatusChangedPacket -import net.mamoe.mirai.timpc.network.packet.login.* -import net.mamoe.mirai.utils.io.toUHexString - - -/** - * 通过 [value] 匹配一个 [IgnoredPacketId] 或 [KnownPacketId], 无匹配则返回一个 [UnknownPacketId]. - */ -internal fun matchPacketId(value: UShort): PacketId = - IgnoredPacketIds.firstOrNull { it.value == value } ?: KnownPacketId.values().firstOrNull { it.value == value } ?: UnknownPacketId(value) - -/** - * 包 ID. - */ -internal interface PacketId { - val value: UShort - val factory: PacketFactory<*, *> -} - -/** - * 用于代表 `null`. 调用任何属性时都将会得到一个 [error] - */ -@Suppress("unused") -internal object NullPacketId : PacketId { - override val factory: PacketFactory<*, *> get() = error("uninitialized") - override val value: UShort get() = error("uninitialized") - override fun toString(): String = "NullPacketId" -} - -/** - * 未知的 [PacketId] - */ -internal inline class UnknownPacketId(override inline val value: UShort) : PacketId { - override val factory: PacketFactory<*, *> get() = UnknownPacketFactory - override fun toString(): String = "UnknownPacketId(${value.toUHexString()})" -} - -internal object IgnoredPacketIds : List by { - listOf( - ).map { IgnoredPacketId(it.toUShort()) } -}() - -internal inline class IgnoredPacketId constructor(override val value: UShort) : PacketId { - override val factory: PacketFactory<*, *> get() = IgnoredPacketFactory - override fun toString(): String = "IgnoredPacketId(${value.toUHexString()})" -} - -/** - * 已知的 [matchPacketId]. 所有在 Mirai 中实现过的包都会使用这些 Id - */ -@Suppress("unused") -internal enum class KnownPacketId(override val value: UShort, override val factory: PacketFactory<*, *>) : - PacketId { - TOUCH(0x0825u, TouchPacket), - SESSION_KEY(0x0828u, RequestSessionPacket), - LOGIN(0x0836u, SubmitPasswordPacket), - CAPTCHA(0x00BAu, CaptchaPacket), - SERVER_EVENT_1(0x00CEu, EventPacketFactory), - SERVER_EVENT_2(0x0017u, EventPacketFactory), - FRIEND_ONLINE_STATUS_CHANGE(0x0081u, FriendOnlineStatusChangedPacket), - CHANGE_ONLINE_STATUS(0x00ECu, ChangeOnlineStatusPacket), - - HEARTBEAT(0x0058u, HeartbeatPacket), - S_KEY(0x001Du, RequestSKeyPacket), - ACCOUNT_INFO(0x005Cu, RequestAccountInfoPacket), - GROUP_PACKET(0x0002u, GroupPacket), - SEND_FRIEND_MESSAGE(0x00CDu, SendFriendMessagePacket), - CAN_ADD_FRIEND(0x00A7u, CanAddFriendPacket), - ADD_FRIEND(0x00A8u, AddFriendPacket), - REQUEST_FRIEND_ADDITION_KEY(0x00AEu, RequestFriendAdditionKeyPacket), - GROUP_IMAGE_ID(0x0388u, GroupImagePacket), - FRIEND_IMAGE_ID(0x0352u, FriendImagePacket), - - REQUEST_PROFILE_AVATAR(0x0031u, RequestProfileAvatarPacket), - REQUEST_PROFILE_DETAILS(0x003Cu, RequestProfileDetailsPacket), - QUERY_NICKNAME(0x0126u, QueryNicknamePacket), - - QUERY_PREVIOUS_NAME(0x01BCu, QueryPreviousNamePacket), - - QUERY_FRIEND_REMARK(0x003Eu, QueryFriendRemarkPacket) - // 031F 查询 "新朋友" 记录 - - - // @Suppress("DEPRECATION") - // inline SUBMIT_IMAGE_FILE_NAME(0x01BDu, SubmitImageFilenamePacket), - - ; - - init { - factory._id = this - } - - override fun toString(): String = (factory::class.simpleName ?: this.name) + "(${value.toUHexString()})" -} diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/AddContact.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/AddContact.kt index 8b1ee8d9b..55d34a919 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/AddContact.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/AddContact.kt @@ -8,8 +8,9 @@ import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.PreviousNameList +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.utils.io.* diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/FriendImage.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/FriendImage.kt index 2c5ad30fa..3d718c674 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/FriendImage.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/FriendImage.kt @@ -4,14 +4,15 @@ package net.mamoe.mirai.timpc.network.packet.action import kotlinx.io.charsets.Charsets import kotlinx.io.core.* +import net.mamoe.mirai.data.EventPacket +import net.mamoe.mirai.data.ImageLink import net.mamoe.mirai.message.data.ImageId import net.mamoe.mirai.message.data.ImageId0x06 import net.mamoe.mirai.message.data.requireLength import net.mamoe.mirai.network.BotNetworkHandler -import net.mamoe.mirai.data.EventPacket -import net.mamoe.mirai.data.ImageLink +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.io.* diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/FriendList.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/FriendList.kt index 3375a6802..2079b68a4 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/FriendList.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/FriendList.kt @@ -5,8 +5,8 @@ package net.mamoe.mirai.timpc.network.packet.action import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet -import net.mamoe.mirai.timpc.network.packet.PacketId -import net.mamoe.mirai.timpc.network.packet.SessionPacketFactory +import net.mamoe.mirai.network.packet.PacketId +import net.mamoe.mirai.network.packet.SessionPacketFactory // 0001 diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GradeInfo.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GradeInfo.kt index 9ec3f9c13..25bdb947d 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GradeInfo.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GradeInfo.kt @@ -7,8 +7,9 @@ import kotlinx.io.core.writeFully import kotlinx.io.core.writeUByte import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.utils.io.writeQQ /** diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GroupImage.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GroupImage.kt index 244ac85d7..0d4b2b844 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GroupImage.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GroupImage.kt @@ -11,7 +11,8 @@ import net.mamoe.mirai.message.data.requireLength import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.ImageLink -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildSessionProtoPacket import net.mamoe.mirai.timpc.utils.assertUnreachable import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.io.toUHexString diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GroupPacket.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GroupPacket.kt index b2eb5681d..62f369ed2 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GroupPacket.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/GroupPacket.kt @@ -6,17 +6,17 @@ import kotlinx.io.core.* import net.mamoe.mirai.contact.GroupInternalId import net.mamoe.mirai.contact.MemberPermission import net.mamoe.mirai.contact.groupInternalId +import net.mamoe.mirai.data.Packet import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.internal.toPacket import net.mamoe.mirai.network.BotNetworkHandler -import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.internal.RawGroupInfo import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.timpc.utils.unsupportedFlag import net.mamoe.mirai.timpc.utils.unsupportedType import net.mamoe.mirai.utils.io.* -import kotlin.collections.mutableMapOf import kotlin.collections.set diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/Profile.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/Profile.kt index bfed95602..5d0cf04bb 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/Profile.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/Profile.kt @@ -5,10 +5,11 @@ package net.mamoe.mirai.timpc.network.packet.action import io.ktor.util.date.GMTDate import kotlinx.io.core.* import net.mamoe.mirai.data.Gender +import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Profile import net.mamoe.mirai.network.BotNetworkHandler -import net.mamoe.mirai.data.Packet -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.utils.io.* inline class AvatarLink(val value: String) : Packet diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/Remark.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/Remark.kt index 11289ca1c..de6dd7178 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/Remark.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/Remark.kt @@ -6,7 +6,8 @@ import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.FriendNameRemark -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.utils.io.readUShortLVString import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeZero diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/RequestFriendListPacket.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/RequestFriendListPacket.kt index 9d5f47716..0183ba262 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/RequestFriendListPacket.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/RequestFriendListPacket.kt @@ -5,8 +5,9 @@ package net.mamoe.mirai.timpc.network.packet.action import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.utils.io.writeZero class FriendList : Packet diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/SendFriendMessagePacket.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/SendFriendMessagePacket.kt index 0eaaf02bd..98c4220e9 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/SendFriendMessagePacket.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/action/SendFriendMessagePacket.kt @@ -7,8 +7,9 @@ import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.internal.toPacket import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.md5 diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/AndroidOnlineStatusChange.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/AndroidOnlineStatusChange.kt index 5d8f8cbad..73e21fc24 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/AndroidOnlineStatusChange.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/AndroidOnlineStatusChange.kt @@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact import net.mamoe.mirai.Bot import net.mamoe.mirai.data.Packet -import net.mamoe.mirai.timpc.network.packet.PacketVersion +import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.io.readBoolean diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/EventPacketFactory.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/EventPacketFactory.kt index 433f5105a..a5abf9556 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/EventPacketFactory.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/EventPacketFactory.kt @@ -6,9 +6,10 @@ import kotlinx.io.core.* import net.mamoe.mirai.Bot import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMBotNetworkHandler -import net.mamoe.mirai.timpc.network.packet.* import net.mamoe.mirai.qqAccount +import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.utils.io.readIoBuffer /** diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendAddRequestEventPacket.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendAddRequestEventPacket.kt index 36e459843..886abab5a 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendAddRequestEventPacket.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendAddRequestEventPacket.kt @@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact import net.mamoe.mirai.Bot import net.mamoe.mirai.event.events.ReceiveFriendAddRequestEvent -import net.mamoe.mirai.timpc.network.packet.PacketVersion +import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.io.readQQ import net.mamoe.mirai.utils.io.readUShortLVString diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendConversationIniliaze.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendConversationIniliaze.kt index 3b1868871..87b46ff5c 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendConversationIniliaze.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendConversationIniliaze.kt @@ -4,10 +4,9 @@ package net.mamoe.mirai.timpc.network.packet.event import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact -import kotlinx.io.core.readUInt import net.mamoe.mirai.Bot import net.mamoe.mirai.data.EventPacket -import net.mamoe.mirai.timpc.network.packet.PacketVersion +import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.io.readQQ diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendOnlineStatusChanged.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendOnlineStatusChanged.kt index 757e5f920..f4c162898 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendOnlineStatusChanged.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/FriendOnlineStatusChanged.kt @@ -5,12 +5,10 @@ package net.mamoe.mirai.timpc.network.packet.event import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact import kotlinx.io.core.readUByte -import kotlinx.io.core.readUInt import net.mamoe.mirai.event.events.FriendStatusChanged import net.mamoe.mirai.network.BotNetworkHandler -import net.mamoe.mirai.timpc.network.packet.KnownPacketId -import net.mamoe.mirai.timpc.network.packet.PacketId -import net.mamoe.mirai.timpc.network.packet.SessionPacketFactory +import net.mamoe.mirai.network.packet.PacketId +import net.mamoe.mirai.network.packet.SessionPacketFactory import net.mamoe.mirai.utils.OnlineStatus import net.mamoe.mirai.utils.io.readQQ diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/GroupFileUpload.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/GroupFileUpload.kt index 765f31edd..ad45caf15 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/GroupFileUpload.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/GroupFileUpload.kt @@ -5,7 +5,7 @@ package net.mamoe.mirai.timpc.network.packet.event import kotlinx.io.core.ByteReadPacket import net.mamoe.mirai.Bot import net.mamoe.mirai.data.EventPacket -import net.mamoe.mirai.timpc.network.packet.PacketVersion +import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.io.debugPrint diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/MemberPermission.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/MemberPermission.kt index 86b3c105e..7149ddef4 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/MemberPermission.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/MemberPermission.kt @@ -5,11 +5,11 @@ package net.mamoe.mirai.timpc.network.packet.event import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact import net.mamoe.mirai.Bot -import net.mamoe.mirai.data.EventPacket -import net.mamoe.mirai.timpc.network.packet.PacketVersion -import net.mamoe.mirai.utils.io.readQQ -import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.Group +import net.mamoe.mirai.contact.Member +import net.mamoe.mirai.data.EventPacket +import net.mamoe.mirai.network.packet.PacketVersion +import net.mamoe.mirai.utils.io.readQQ data class MemberPermissionChangePacket( diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/MessageEvent.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/MessageEvent.kt index 26c373433..1ba1f2a83 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/MessageEvent.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/event/MessageEvent.kt @@ -7,7 +7,7 @@ import net.mamoe.mirai.contact.MemberPermission import net.mamoe.mirai.message.GroupMessage import net.mamoe.mirai.message.internal.readMessageChain import net.mamoe.mirai.message.FriendMessage -import net.mamoe.mirai.timpc.network.packet.PacketVersion +import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.io.* diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Captcha.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Captcha.kt index 2b7a34946..f0236e8e6 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Captcha.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Captcha.kt @@ -5,11 +5,13 @@ package net.mamoe.mirai.timpc.network.packet.login import kotlinx.io.core.* import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.utils.io.* -internal object CaptchaKey : DecrypterByteArray, DecrypterType { +internal object CaptchaKey : DecrypterByteArray, + DecrypterType { override val value: ByteArray = TIMProtocol.key00BA } diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/ChangeOnlineStatusPacket.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/ChangeOnlineStatusPacket.kt index 14e61071b..1a4ea0f8f 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/ChangeOnlineStatusPacket.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/ChangeOnlineStatusPacket.kt @@ -7,8 +7,9 @@ import kotlinx.io.core.writeFully import kotlinx.io.core.writeUByte import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.utils.OnlineStatus import net.mamoe.mirai.utils.io.writeHex import net.mamoe.mirai.utils.io.writeQQ @@ -16,7 +17,9 @@ import net.mamoe.mirai.utils.io.writeQQ /** * 改变在线状态: "我在线上", "隐身" 等 */ -internal object ChangeOnlineStatusPacket : PacketFactory(NoDecrypter) { +internal object ChangeOnlineStatusPacket : PacketFactory( + NoDecrypter +) { operator fun invoke( bot: Long, sessionKey: SessionKey, diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Heartbeat.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Heartbeat.kt index 7ce4efeaa..3fe10c33b 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Heartbeat.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Heartbeat.kt @@ -7,8 +7,9 @@ import kotlinx.io.core.writeFully import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.utils.io.writeHex import net.mamoe.mirai.utils.io.writeQQ diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/PasswordSubmission.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/PasswordSubmission.kt index 7ccbb92d9..27d0d1fea 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/PasswordSubmission.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/PasswordSubmission.kt @@ -7,12 +7,14 @@ import net.mamoe.mirai.data.Gender import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.LoginResult import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.io.* -internal object ShareKey : DecrypterByteArray, DecrypterType { +internal object ShareKey : DecrypterByteArray, + DecrypterType { override val value: ByteArray = TIMProtocol.shareKey } diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/SKey.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/SKey.kt index f8c3b4c04..9a218da4c 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/SKey.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/SKey.kt @@ -7,8 +7,9 @@ import kotlinx.io.core.discardExact import kotlinx.io.core.writeFully import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.utils.io.* internal inline class SKey( diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Session.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Session.kt index dede09af8..8f9c9c1d8 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Session.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Session.kt @@ -5,8 +5,11 @@ package net.mamoe.mirai.timpc.network.packet.login import kotlinx.io.core.* import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.packet.PacketFactory +import net.mamoe.mirai.network.packet.PacketId +import net.mamoe.mirai.network.packet.SessionKey import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.localIpAddress diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Touch.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Touch.kt index bb87f2003..48407f6a0 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Touch.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/login/Touch.kt @@ -6,13 +6,15 @@ import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact import kotlinx.io.core.readBytes import kotlinx.io.core.writeFully -import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +import net.mamoe.mirai.network.BotNetworkHandler +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.utils.io.* -internal object TouchKey : DecrypterByteArray, DecrypterType { +internal object TouchKey : DecrypterByteArray, + DecrypterType { override val value: ByteArray = TIMProtocol.touchKey } diff --git a/mirai-core-timpc/src/jvmTest/kotlin/PacketDebugger.kt b/mirai-core-timpc/src/jvmTest/kotlin/PacketDebugger.kt index 5dc3027b5..a95de8e3f 100644 --- a/mirai-core-timpc/src/jvmTest/kotlin/PacketDebugger.kt +++ b/mirai-core-timpc/src/jvmTest/kotlin/PacketDebugger.kt @@ -16,13 +16,12 @@ import kotlinx.serialization.internal.ArrayListSerializer import kotlinx.serialization.json.Json import net.mamoe.mirai.Bot import net.mamoe.mirai.network.BotNetworkHandler +import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.TIMPC import net.mamoe.mirai.timpc.network.TIMProtocol -import net.mamoe.mirai.timpc.network.packet.* +import net.mamoe.mirai.timpc.network.packet.event.FriendOnlineStatusChangedPacket import net.mamoe.mirai.timpc.network.packet.event.IgnoredEventPacket -import net.mamoe.mirai.timpc.network.packet.login.CaptchaKey -import net.mamoe.mirai.timpc.network.packet.login.ShareKey -import net.mamoe.mirai.timpc.network.packet.login.TouchKey +import net.mamoe.mirai.timpc.network.packet.login.* import net.mamoe.mirai.utils.DecryptionFailedException import net.mamoe.mirai.utils.decryptBy import net.mamoe.mirai.utils.io.* @@ -181,7 +180,8 @@ internal object PacketDebugger { * 7. 运行完 `mov eax,dword ptr ss:[ebp+10]` * 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `sessionKey` */ - val sessionKey: SessionKey = SessionKey("95 F3 24 8E 7B B6 62 AA 98 C0 EE 45 CE CE 2B 69".hexToBytes()) + val sessionKey: SessionKey = + SessionKey("95 F3 24 8E 7B B6 62 AA 98 C0 EE 45 CE CE 2B 69".hexToBytes()) // TODO: 2019/12/7 无法访问 internal 是 kotlin bug, KT-34849 /** @@ -194,9 +194,9 @@ internal object PacketDebugger { val recorder: Recorder? = Recorder() val IgnoredPacketIdList: List = listOf( - KnownPacketId.FRIEND_ONLINE_STATUS_CHANGE, - KnownPacketId.CHANGE_ONLINE_STATUS, - KnownPacketId.HEARTBEAT + KnownPacketId.get(), + KnownPacketId.get(), + KnownPacketId.get() ) suspend fun dataReceived(data: ByteArray) { @@ -204,10 +204,10 @@ internal object PacketDebugger { //println("raw = " + data.toUHexString()) data.read { discardExact(3) - val id = matchPacketId(readUShort()) + val id = net.mamoe.mirai.network.packet.matchPacketId(readUShort()) val sequenceId = readUShort() val packetQQ = readQQ() - if (id == KnownPacketId.HEARTBEAT || (qq != null && packetQQ != qq)) + if (id == KnownPacketId.get() || (qq != null && packetQQ != qq)) return@read if (IgnoredPacketIdList.contains(id)) { @@ -301,7 +301,7 @@ internal object PacketDebugger { // 3E 03 3F A2 02 00 00 00 01 2E 01 00 00 69 35 discardExact(3)//head - val id = matchPacketId(readUShort()) + val id = net.mamoe.mirai.network.packet.matchPacketId(readUShort()) val sequence = readUShort().toUHexString() if (IgnoredPacketIdList.contains(id)) { return diff --git a/mirai-core-timpc/src/jvmTest/kotlin/packetdebugger/PacketDecoder.kt b/mirai-core-timpc/src/jvmTest/kotlin/packetdebugger/PacketDecoder.kt index ad9f72294..c65e401eb 100644 --- a/mirai-core-timpc/src/jvmTest/kotlin/packetdebugger/PacketDecoder.kt +++ b/mirai-core-timpc/src/jvmTest/kotlin/packetdebugger/PacketDecoder.kt @@ -3,8 +3,8 @@ package packetdebugger import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact import kotlinx.io.core.readUShort -import net.mamoe.mirai.timpc.network.packet.PacketId -import net.mamoe.mirai.timpc.network.packet.matchPacketId +import net.mamoe.mirai.network.packet.PacketId +import net.mamoe.mirai.network.packet.matchPacketId import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt index e28576748..356d01473 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt @@ -19,14 +19,18 @@ import kotlin.coroutines.CoroutineContext */ @MiraiInternalAPI abstract class BotImpl constructor( - override val account: BotAccount, - override val logger: MiraiLogger = DefaultLogger("Bot(" + account.id + ")"), + account: BotAccount, + logger: MiraiLogger?, context: CoroutineContext ) : Bot(), CoroutineScope { private val supervisorJob = SupervisorJob(context[Job]) override val coroutineContext: CoroutineContext = context + supervisorJob + CoroutineExceptionHandler { _, e -> e.logStacktrace("An exception was thrown under a coroutine of Bot") } + @Suppress("CanBePrimaryConstructorProperty") // for logger + override val account: BotAccount = account + override val logger: MiraiLogger = logger ?: DefaultLogger("Bot(" + account.id + ")") + init { @Suppress("LeakingThis") instances.addLast(this) diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/Annotations.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/Annotations.kt similarity index 72% rename from mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/Annotations.kt rename to mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/Annotations.kt index 196ee1155..6b0dba502 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/Annotations.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/Annotations.kt @@ -1,6 +1,6 @@ @file:Suppress("EXPERIMENTAL_API_USAGE", "unused") -package net.mamoe.mirai.timpc.network.packet +package net.mamoe.mirai.network.packet /** * 包的最后一次修改时间, 和分析时使用的 TIM 版本 @@ -8,11 +8,11 @@ package net.mamoe.mirai.timpc.network.packet @MustBeDocumented @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.PROPERTY) @Retention(AnnotationRetention.SOURCE) -internal annotation class PacketVersion(val date: String, val timVersion: String) +annotation class PacketVersion(val date: String, val timVersion: String) /** * 带有这个注解的 [Packet] 将不会被记录在 log 中. */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) -internal annotation class NoLog \ No newline at end of file +annotation class NoLog \ No newline at end of file diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/Decrypters.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/Decrypters.kt similarity index 54% rename from mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/Decrypters.kt rename to mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/Decrypters.kt index a330aaf75..bc8eb89ab 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/Decrypters.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/Decrypters.kt @@ -1,26 +1,23 @@ -package net.mamoe.mirai.timpc.network.packet +package net.mamoe.mirai.network.packet import kotlinx.io.core.BytePacketBuilder import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.IoBuffer -import kotlinx.io.core.writeFully import net.mamoe.mirai.utils.decryptBy -import net.mamoe.mirai.utils.encryptBy import net.mamoe.mirai.utils.io.encryptAndWrite /** * 会话密匙 */ -internal inline class SessionKey(override val value: ByteArray) : DecrypterByteArray { +inline class SessionKey(override val value: ByteArray) : DecrypterByteArray { companion object Type : DecrypterType } /** * [ByteArray] 解密器 */ -@PublishedApi -internal interface DecrypterByteArray : Decrypter { +interface DecrypterByteArray : Decrypter { val value: ByteArray override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value) } @@ -28,7 +25,7 @@ internal interface DecrypterByteArray : Decrypter { /** * [IoBuffer] 解密器 */ -internal interface DecrypterIoBuffer : Decrypter { +interface DecrypterIoBuffer : Decrypter { val value: IoBuffer override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value) } @@ -36,27 +33,28 @@ internal interface DecrypterIoBuffer : Decrypter { /** * 连接在一起的解密器 */ -internal inline class LinkedDecrypter(inline val block: (ByteReadPacket) -> ByteReadPacket) : Decrypter { +inline class LinkedDecrypter(inline val block: (ByteReadPacket) -> ByteReadPacket) : Decrypter { override fun decrypt(input: ByteReadPacket): ByteReadPacket = block(input) } -internal object NoDecrypter : Decrypter, DecrypterType { +object NoDecrypter : Decrypter, + DecrypterType { override fun decrypt(input: ByteReadPacket): ByteReadPacket = input } /** * 解密器 - */ -internal interface Decrypter { + */ +interface Decrypter { fun decrypt(input: ByteReadPacket): ByteReadPacket /** * 连接后将会先用 this 解密, 再用 [another] 解密 */ - operator fun plus(another: Decrypter): Decrypter = LinkedDecrypter { another.decrypt(this.decrypt(it)) } + operator fun plus(another: Decrypter): Decrypter = + LinkedDecrypter { another.decrypt(this.decrypt(it)) } } + +interface DecrypterType -internal interface DecrypterType - -@PublishedApi -internal inline fun BytePacketBuilder.encryptAndWrite(key: DecrypterByteArray, encoder: BytePacketBuilder.() -> Unit) = +inline fun BytePacketBuilder.encryptAndWrite(key: DecrypterByteArray, encoder: BytePacketBuilder.() -> Unit) = this.encryptAndWrite(key.value, encoder) diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/OutgoingPacket.kt similarity index 63% rename from mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacket.kt rename to mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/OutgoingPacket.kt index 409670cb0..24d65cf18 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacket.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/OutgoingPacket.kt @@ -1,13 +1,13 @@ @file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS", "unused", "MemberVisibilityCanBePrivate") -package net.mamoe.mirai.timpc.network.packet +package net.mamoe.mirai.network.packet import kotlinx.io.core.* import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.protobuf.ProtoBuf -import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet -import net.mamoe.mirai.timpc.network.TIMProtocol +import net.mamoe.mirai.network.BotNetworkHandler +import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.writeQQ import kotlin.contracts.ExperimentalContracts @@ -18,11 +18,11 @@ import kotlin.jvm.JvmOverloads /** * 待发送给服务器的数据包. 它代表着一个 [ByteReadPacket], */ -internal class OutgoingPacket( +class OutgoingPacket( name: String?, val packetId: PacketId, val sequenceId: UShort, - internal val delegate: ByteReadPacket + val delegate: ByteReadPacket ) : Packet { val name: String by lazy { name ?: packetId.toString() @@ -35,7 +35,9 @@ internal class OutgoingPacket( * * @param TPacket invariant */ -internal abstract class SessionPacketFactory : PacketFactory(SessionKey) { +abstract class SessionPacketFactory : PacketFactory( + SessionKey +) { /** * 在 [BotNetworkHandler] 下处理这个包. 广播事件等. */ @@ -45,13 +47,16 @@ internal abstract class SessionPacketFactory : PacketFactory.buildOutgoingPacket( +inline fun PacketFactory<*, *>.buildOutgoingPacket0( name: String? = null, id: PacketId = this.id, sequenceId: UShort = PacketFactory.atomicNextSequenceId(), headerSizeHint: Int = 0, + head: ByteArray, + ver: ByteArray, + tail: ByteArray, block: BytePacketBuilder.() -> Unit ): OutgoingPacket { contract { @@ -60,12 +65,12 @@ internal inline fun PacketFactory<*, *>.buildOutgoingPacket( BytePacketBuilder(headerSizeHint).use { with(it) { - writeFully(TIMProtocol.head) - writeFully(TIMProtocol.ver) + writeFully(head) + writeFully(ver) writeUShort(id.value) writeUShort(sequenceId) block(this) - writeFully(TIMProtocol.tail) + writeFully(tail) } return OutgoingPacket(name, id, sequenceId, it.build()) } @@ -75,22 +80,33 @@ internal inline fun PacketFactory<*, *>.buildOutgoingPacket( /** * 构造一个待发送给服务器的会话数据包. */ -@UseExperimental(ExperimentalContracts::class) +@UseExperimental(ExperimentalContracts::class, MiraiInternalAPI::class) @JvmOverloads -internal inline fun PacketFactory<*, *>.buildSessionPacket( +inline fun PacketFactory<*, *>.buildSessionPacket0( bot: Long, sessionKey: SessionKey, name: String? = null, id: PacketId = this.id, sequenceId: UShort = PacketFactory.atomicNextSequenceId(), headerSizeHint: Int = 0, - version: ByteArray = TIMProtocol.version0x02, + version: ByteArray, // in packet body + head: ByteArray, + ver: ByteArray, // in packet head + tail: ByteArray, block: BytePacketBuilder.() -> Unit ): OutgoingPacket { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return buildOutgoingPacket(name, id, sequenceId, headerSizeHint) { + return buildOutgoingPacket0( + name = name, + id = id, + sequenceId = sequenceId, + headerSizeHint = headerSizeHint, + head = head, + ver = ver, + tail = tail + ) { writeQQ(bot) writeFully(version) encryptAndWrite(sessionKey) { @@ -102,22 +118,25 @@ internal inline fun PacketFactory<*, *>.buildSessionPacket( /** * 构造一个待发送给服务器的会话数据包. */ -@UseExperimental(ExperimentalContracts::class) +@UseExperimental(ExperimentalContracts::class, MiraiInternalAPI::class) @JvmOverloads -internal fun PacketFactory<*, *>.buildSessionProtoPacket( +fun PacketFactory<*, *>.buildSessionProtoPacket0( bot: Long, sessionKey: SessionKey, name: String? = null, id: PacketId = this.id, sequenceId: UShort = PacketFactory.atomicNextSequenceId(), headerSizeHint: Int = 0, - version: ByteArray = TIMProtocol.version0x04, + version: ByteArray, head: Any, serializer: SerializationStrategy, - protoObj: T + protoObj: T, + packetHead: ByteArray, + ver: ByteArray, // in packet head + tail: ByteArray ): OutgoingPacket { require(head is ByteArray || head is UByteArray || head is String) { "Illegal head type" } - return buildOutgoingPacket(name, id, sequenceId, headerSizeHint) { + return buildOutgoingPacket0(name, id, sequenceId, headerSizeHint, head = packetHead, ver = ver, tail = tail) { writeQQ(bot) writeFully(version) encryptAndWrite(sessionKey) { @@ -136,17 +155,20 @@ internal fun PacketFactory<*, *>.buildSessionProtoPacket( writeFully(head) writeFully(proto) } - is String -> buildSessionProtoPacket( - bot, - sessionKey, - name, - id, - sequenceId, - headerSizeHint, - version, - head.hexToBytes(), - serializer, - protoObj + is String -> buildSessionProtoPacket0( + bot = bot, + sessionKey = sessionKey, + name = name, + id = id, + sequenceId = sequenceId, + headerSizeHint = headerSizeHint, + version = version, + head = head.hexToBytes(), + serializer = serializer, + protoObj = protoObj, + packetHead = packetHead, + ver = ver, + tail = tail ) } } diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/Packet.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/Packet.kt similarity index 65% rename from mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/Packet.kt rename to mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/Packet.kt index 6ea111429..0eedef402 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/Packet.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/Packet.kt @@ -1,4 +1,4 @@ -package net.mamoe.mirai.timpc.network.packet +package net.mamoe.mirai.network.packet import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.readBytes @@ -8,18 +8,18 @@ import net.mamoe.mirai.utils.io.toUHexString /** * 被忽略的数据包. */ -internal inline class IgnoredPacket(internal val id: PacketId) : Packet +inline class IgnoredPacket(internal val id: PacketId) : Packet /** * 未知的包. */ -internal class UnknownPacket(val id: PacketId, val body: ByteReadPacket) : Packet { +class UnknownPacket(val id: PacketId, val body: ByteReadPacket) : Packet { override fun toString(): String = "UnknownPacket(${id.value.toUHexString()})\nbody=${body.readBytes().toUHexString()}" } /** * 仅用于替换类型应为 [Unit] 的情况 */ -internal object NoPacket : Packet { +object NoPacket : Packet { override fun toString(): String = "NoPacket" } diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketFactory.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/PacketFactory.kt similarity index 89% rename from mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketFactory.kt rename to mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/PacketFactory.kt index 94326783c..d20c98dda 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketFactory.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/packet/PacketFactory.kt @@ -1,6 +1,6 @@ @file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") -package net.mamoe.mirai.timpc.network.packet +package net.mamoe.mirai.network.packet import kotlinx.atomicfu.atomic import kotlinx.io.core.ByteReadPacket @@ -11,6 +11,7 @@ import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.Packet +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 @@ -24,7 +25,7 @@ import net.mamoe.mirai.utils.readProtoMap * @param TPacket 服务器回复包解析结果 * @param TDecrypter 服务器回复包解密器 */ -internal abstract class PacketFactory(val decrypterType: DecrypterType) { +abstract class PacketFactory(val decrypterType: DecrypterType) { @Suppress("PropertyName") internal var _id: PacketId = NullPacketId @@ -64,8 +65,8 @@ internal abstract class PacketFactory +} + +/** + * 用于代表 `null`. 调用任何属性时都将会得到一个 [error] + */ +@Suppress("unused") +object NullPacketId : PacketId { + override val factory: PacketFactory<*, *> get() = error("uninitialized") + override val value: UShort get() = error("uninitialized") + override fun toString(): String = "NullPacketId" +} + +/** + * 未知的 [PacketId] + */ +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 { + listOf( + ).map { IgnoredPacketId(it.toUShort()) } +}() + +inline class IgnoredPacketId constructor(override val value: UShort) : PacketId { + override val factory: PacketFactory<*, *> get() = IgnoredPacketFactory + override fun toString(): String = "IgnoredPacketId(${value.toUHexString()})" +} + +class KnownPacketId(override val value: UShort, override val factory: PacketFactory<*, *>) : PacketId { + companion object : MutableMap by mutableMapOf() { + operator fun set(key: UShort, factory: PacketFactory<*, *>) { + this[key] = KnownPacketId(key, factory) + } + + inline fun > getOrNull(): KnownPacketId? { + val clazz = PF::class + this.forEach { + if (clazz.isInstance(it.value)) { + return it.value + } + } + return null + } + + inline fun > get(): KnownPacketId = getOrNull() ?: throw NoSuchElementException() + } + + override fun toString(): String = (factory::class.simpleName ?: factory::class.simpleName) + "(${value.toUHexString()})" + + init { + factory._id = this + } +} \ No newline at end of file