Commit c8eac6af authored by Him188's avatar Him188

Move packet stuffs to mirai-core

parent 19d5c910
...@@ -11,6 +11,9 @@ import net.mamoe.mirai.data.Packet ...@@ -11,6 +11,9 @@ import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.message.data.Image import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.ImageId0x03 import net.mamoe.mirai.message.data.ImageId0x03
import net.mamoe.mirai.message.data.ImageId0x06 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.qqAccount
import net.mamoe.mirai.timpc.internal.RawGroupInfo import net.mamoe.mirai.timpc.internal.RawGroupInfo
import net.mamoe.mirai.timpc.network.GroupImpl import net.mamoe.mirai.timpc.network.GroupImpl
...@@ -18,10 +21,10 @@ import net.mamoe.mirai.timpc.network.MemberImpl ...@@ -18,10 +21,10 @@ import net.mamoe.mirai.timpc.network.MemberImpl
import net.mamoe.mirai.timpc.network.QQImpl import net.mamoe.mirai.timpc.network.QQImpl
import net.mamoe.mirai.timpc.network.TIMBotNetworkHandler import net.mamoe.mirai.timpc.network.TIMBotNetworkHandler
import net.mamoe.mirai.timpc.network.handler.TemporaryPacketHandler 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.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.timpc.utils.assertUnreachable
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
...@@ -44,9 +47,41 @@ internal abstract class TIMPCBotBase constructor( ...@@ -44,9 +47,41 @@ internal abstract class TIMPCBotBase constructor(
logger: MiraiLogger?, logger: MiraiLogger?,
context: CoroutineContext context: CoroutineContext
) : BotImpl<TIMBotNetworkHandler>(account, logger ?: DefaultLogger("Bot(" + account.id + ")"), context) { ) : BotImpl<TIMBotNetworkHandler>(account, logger ?: DefaultLogger("Bot(" + account.id + ")"), context) {
@UseExperimental(ExperimentalUnsignedTypes::class)
companion object { companion object {
init { 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( ...@@ -69,7 +104,7 @@ internal abstract class TIMPCBotBase constructor(
reinitializeNetworkHandler(configuration, cause) reinitializeNetworkHandler(configuration, cause)
logger.info("Reconnected successfully") logger.info("Reconnected successfully")
return@launch return@launch
} catch (e: LoginFailedException){ } catch (e: LoginFailedException) {
delay(configuration.reconnectPeriodMillis) delay(configuration.reconnectPeriodMillis)
} }
} }
......
...@@ -6,19 +6,19 @@ import kotlinx.coroutines.* ...@@ -6,19 +6,19 @@ import kotlinx.coroutines.*
import kotlinx.io.core.* import kotlinx.io.core.*
import kotlinx.io.pool.useInstance import kotlinx.io.pool.useInstance
import net.mamoe.mirai.Bot 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.BroadcastControllable
import net.mamoe.mirai.event.Cancellable import net.mamoe.mirai.event.Cancellable
import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BotLoginSucceedEvent import net.mamoe.mirai.event.events.BotLoginSucceedEvent
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.LoginResult import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqAccount import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.timpc.TIMPCBot import net.mamoe.mirai.timpc.TIMPCBot
import net.mamoe.mirai.timpc.network.handler.DataPacketSocketAdapter import net.mamoe.mirai.timpc.network.handler.DataPacketSocketAdapter
import net.mamoe.mirai.timpc.network.handler.TemporaryPacketHandler 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.timpc.network.packet.login.*
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
......
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 <T> 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<T>,
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
...@@ -8,8 +8,9 @@ import net.mamoe.mirai.network.BotNetworkHandler ...@@ -8,8 +8,9 @@ import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.EventPacket
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.data.PreviousNameList 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.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.io.*
......
...@@ -4,14 +4,15 @@ package net.mamoe.mirai.timpc.network.packet.action ...@@ -4,14 +4,15 @@ package net.mamoe.mirai.timpc.network.packet.action
import kotlinx.io.charsets.Charsets import kotlinx.io.charsets.Charsets
import kotlinx.io.core.* 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.ImageId
import net.mamoe.mirai.message.data.ImageId0x06 import net.mamoe.mirai.message.data.ImageId0x06
import net.mamoe.mirai.message.data.requireLength import net.mamoe.mirai.message.data.requireLength
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.data.ImageLink
import net.mamoe.mirai.timpc.network.TIMProtocol 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.ExternalImage
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
......
...@@ -5,8 +5,8 @@ package net.mamoe.mirai.timpc.network.packet.action ...@@ -5,8 +5,8 @@ package net.mamoe.mirai.timpc.network.packet.action
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.timpc.network.packet.PacketId import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.timpc.network.packet.SessionPacketFactory import net.mamoe.mirai.network.packet.SessionPacketFactory
// 0001 // 0001
......
...@@ -7,8 +7,9 @@ import kotlinx.io.core.writeFully ...@@ -7,8 +7,9 @@ import kotlinx.io.core.writeFully
import kotlinx.io.core.writeUByte import kotlinx.io.core.writeUByte
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.* import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
/** /**
......
...@@ -11,7 +11,8 @@ import net.mamoe.mirai.message.data.requireLength ...@@ -11,7 +11,8 @@ import net.mamoe.mirai.message.data.requireLength
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.EventPacket
import net.mamoe.mirai.data.ImageLink 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.timpc.utils.assertUnreachable
import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.io.toUHexString
......
...@@ -6,17 +6,17 @@ import kotlinx.io.core.* ...@@ -6,17 +6,17 @@ import kotlinx.io.core.*
import net.mamoe.mirai.contact.GroupInternalId import net.mamoe.mirai.contact.GroupInternalId
import net.mamoe.mirai.contact.MemberPermission import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.contact.groupInternalId import net.mamoe.mirai.contact.groupInternalId
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.internal.toPacket import net.mamoe.mirai.message.internal.toPacket
import net.mamoe.mirai.network.BotNetworkHandler 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.internal.RawGroupInfo
import net.mamoe.mirai.timpc.network.TIMProtocol 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.unsupportedFlag
import net.mamoe.mirai.timpc.utils.unsupportedType import net.mamoe.mirai.timpc.utils.unsupportedType
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
import kotlin.collections.mutableMapOf
import kotlin.collections.set import kotlin.collections.set
......
...@@ -5,10 +5,11 @@ package net.mamoe.mirai.timpc.network.packet.action ...@@ -5,10 +5,11 @@ package net.mamoe.mirai.timpc.network.packet.action
import io.ktor.util.date.GMTDate import io.ktor.util.date.GMTDate
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.data.Gender import net.mamoe.mirai.data.Gender
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.data.Profile import net.mamoe.mirai.data.Profile
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.network.packet.*
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.io.*
inline class AvatarLink(val value: String) : Packet inline class AvatarLink(val value: String) : Packet
......
...@@ -6,7 +6,8 @@ import kotlinx.io.core.ByteReadPacket ...@@ -6,7 +6,8 @@ import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.FriendNameRemark 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.readUShortLVString
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
import net.mamoe.mirai.utils.io.writeZero import net.mamoe.mirai.utils.io.writeZero
......
...@@ -5,8 +5,9 @@ package net.mamoe.mirai.timpc.network.packet.action ...@@ -5,8 +5,9 @@ package net.mamoe.mirai.timpc.network.packet.action
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.* import net.mamoe.mirai.timpc.network.packet.buildSessionPacket
import net.mamoe.mirai.utils.io.writeZero import net.mamoe.mirai.utils.io.writeZero
class FriendList : Packet class FriendList : Packet
......
...@@ -7,8 +7,9 @@ import net.mamoe.mirai.message.data.MessageChain ...@@ -7,8 +7,9 @@ import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.internal.toPacket import net.mamoe.mirai.message.internal.toPacket
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.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.io.*
import net.mamoe.mirai.utils.md5 import net.mamoe.mirai.utils.md5
......
...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket ...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.data.Packet 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 import net.mamoe.mirai.utils.io.readBoolean
......
...@@ -6,9 +6,10 @@ import kotlinx.io.core.* ...@@ -6,9 +6,10 @@ import kotlinx.io.core.*
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.TIMBotNetworkHandler
import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.qqAccount import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket
import net.mamoe.mirai.utils.io.readIoBuffer import net.mamoe.mirai.utils.io.readIoBuffer
/** /**
......
...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket ...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.ReceiveFriendAddRequestEvent 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.readQQ
import net.mamoe.mirai.utils.io.readUShortLVString import net.mamoe.mirai.utils.io.readUShortLVString
......
...@@ -4,10 +4,9 @@ package net.mamoe.mirai.timpc.network.packet.event ...@@ -4,10 +4,9 @@ package net.mamoe.mirai.timpc.network.packet.event
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readUInt
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.data.EventPacket 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 import net.mamoe.mirai.utils.io.readQQ
......
...@@ -5,12 +5,10 @@ package net.mamoe.mirai.timpc.network.packet.event ...@@ -5,12 +5,10 @@ package net.mamoe.mirai.timpc.network.packet.event
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readUByte import kotlinx.io.core.readUByte
import kotlinx.io.core.readUInt
import net.mamoe.mirai.event.events.FriendStatusChanged import net.mamoe.mirai.event.events.FriendStatusChanged
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.timpc.network.packet.KnownPacketId import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.timpc.network.packet.PacketId import net.mamoe.mirai.network.packet.SessionPacketFactory
import net.mamoe.mirai.timpc.network.packet.SessionPacketFactory
import net.mamoe.mirai.utils.OnlineStatus import net.mamoe.mirai.utils.OnlineStatus
import net.mamoe.mirai.utils.io.readQQ import net.mamoe.mirai.utils.io.readQQ
......
...@@ -5,7 +5,7 @@ package net.mamoe.mirai.timpc.network.packet.event ...@@ -5,7 +5,7 @@ package net.mamoe.mirai.timpc.network.packet.event
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.data.EventPacket 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 import net.mamoe.mirai.utils.io.debugPrint
......
...@@ -5,11 +5,11 @@ package net.mamoe.mirai.timpc.network.packet.event ...@@ -5,11 +5,11 @@ package net.mamoe.mirai.timpc.network.packet.event
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.data.EventPacket 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 import net.mamoe.mirai.utils.io.readQQ
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.Group
data class MemberPermissionChangePacket( data class MemberPermissionChangePacket(
......
...@@ -7,7 +7,7 @@ import net.mamoe.mirai.contact.MemberPermission ...@@ -7,7 +7,7 @@ import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.message.GroupMessage import net.mamoe.mirai.message.GroupMessage
import net.mamoe.mirai.message.internal.readMessageChain import net.mamoe.mirai.message.internal.readMessageChain
import net.mamoe.mirai.message.FriendMessage 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.MiraiLogger
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
......
...@@ -5,11 +5,13 @@ package net.mamoe.mirai.timpc.network.packet.login ...@@ -5,11 +5,13 @@ package net.mamoe.mirai.timpc.network.packet.login
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.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.io.*
internal object CaptchaKey : DecrypterByteArray, DecrypterType<CaptchaKey> { internal object CaptchaKey : DecrypterByteArray,
DecrypterType<CaptchaKey> {
override val value: ByteArray = TIMProtocol.key00BA override val value: ByteArray = TIMProtocol.key00BA
} }
......
...@@ -7,8 +7,9 @@ import kotlinx.io.core.writeFully ...@@ -7,8 +7,9 @@ import kotlinx.io.core.writeFully
import kotlinx.io.core.writeUByte import kotlinx.io.core.writeUByte
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.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.OnlineStatus
import net.mamoe.mirai.utils.io.writeHex import net.mamoe.mirai.utils.io.writeHex
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
...@@ -16,7 +17,9 @@ import net.mamoe.mirai.utils.io.writeQQ ...@@ -16,7 +17,9 @@ import net.mamoe.mirai.utils.io.writeQQ
/** /**
* 改变在线状态: "我在线上", "隐身" 等 * 改变在线状态: "我在线上", "隐身" 等
*/ */
internal object ChangeOnlineStatusPacket : PacketFactory<ChangeOnlineStatusPacket.ChangeOnlineStatusResponse, NoDecrypter>(NoDecrypter) { internal object ChangeOnlineStatusPacket : PacketFactory<ChangeOnlineStatusPacket.ChangeOnlineStatusResponse, NoDecrypter>(
NoDecrypter
) {
operator fun invoke( operator fun invoke(
bot: Long, bot: Long,
sessionKey: SessionKey, sessionKey: SessionKey,
......
...@@ -7,8 +7,9 @@ import kotlinx.io.core.writeFully ...@@ -7,8 +7,9 @@ import kotlinx.io.core.writeFully
import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.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.writeHex
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
......
...@@ -7,12 +7,14 @@ import net.mamoe.mirai.data.Gender ...@@ -7,12 +7,14 @@ import net.mamoe.mirai.data.Gender
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.LoginResult import net.mamoe.mirai.data.LoginResult
import net.mamoe.mirai.data.Packet 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.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.*
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
internal object ShareKey : DecrypterByteArray, DecrypterType<ShareKey> { internal object ShareKey : DecrypterByteArray,
DecrypterType<ShareKey> {
override val value: ByteArray = TIMProtocol.shareKey override val value: ByteArray = TIMProtocol.shareKey
} }
......
...@@ -7,8 +7,9 @@ import kotlinx.io.core.discardExact ...@@ -7,8 +7,9 @@ import kotlinx.io.core.discardExact
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.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.io.*
internal inline class SKey( internal inline class SKey(
......
...@@ -5,8 +5,11 @@ package net.mamoe.mirai.timpc.network.packet.login ...@@ -5,8 +5,11 @@ package net.mamoe.mirai.timpc.network.packet.login
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.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.io.*
import net.mamoe.mirai.utils.localIpAddress import net.mamoe.mirai.utils.localIpAddress
......
...@@ -6,13 +6,15 @@ import kotlinx.io.core.ByteReadPacket ...@@ -6,13 +6,15 @@ import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readBytes import kotlinx.io.core.readBytes
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.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.io.*
internal object TouchKey : DecrypterByteArray, DecrypterType<TouchKey> { internal object TouchKey : DecrypterByteArray,
DecrypterType<TouchKey> {
override val value: ByteArray = TIMProtocol.touchKey override val value: ByteArray = TIMProtocol.touchKey
} }
......
...@@ -16,13 +16,12 @@ import kotlinx.serialization.internal.ArrayListSerializer ...@@ -16,13 +16,12 @@ import kotlinx.serialization.internal.ArrayListSerializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.TIMPC import net.mamoe.mirai.timpc.TIMPC
import net.mamoe.mirai.timpc.network.TIMProtocol 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.event.IgnoredEventPacket
import net.mamoe.mirai.timpc.network.packet.login.CaptchaKey import net.mamoe.mirai.timpc.network.packet.login.*
import net.mamoe.mirai.timpc.network.packet.login.ShareKey
import net.mamoe.mirai.timpc.network.packet.login.TouchKey
import net.mamoe.mirai.utils.DecryptionFailedException import net.mamoe.mirai.utils.DecryptionFailedException
import net.mamoe.mirai.utils.decryptBy import net.mamoe.mirai.utils.decryptBy
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
...@@ -181,7 +180,8 @@ internal object PacketDebugger { ...@@ -181,7 +180,8 @@ internal object PacketDebugger {
* 7. 运行完 `mov eax,dword ptr ss:[ebp+10]` * 7. 运行完 `mov eax,dword ptr ss:[ebp+10]`
* 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `sessionKey` * 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 // TODO: 2019/12/7 无法访问 internal 是 kotlin bug, KT-34849
/** /**
...@@ -194,9 +194,9 @@ internal object PacketDebugger { ...@@ -194,9 +194,9 @@ internal object PacketDebugger {
val recorder: Recorder? = Recorder() val recorder: Recorder? = Recorder()
val IgnoredPacketIdList: List<PacketId> = listOf( val IgnoredPacketIdList: List<PacketId> = listOf(
KnownPacketId.FRIEND_ONLINE_STATUS_CHANGE, KnownPacketId.get<FriendOnlineStatusChangedPacket>(),
KnownPacketId.CHANGE_ONLINE_STATUS, KnownPacketId.get<ChangeOnlineStatusPacket>(),
KnownPacketId.HEARTBEAT KnownPacketId.get<HeartbeatPacket>()
) )
suspend fun dataReceived(data: ByteArray) { suspend fun dataReceived(data: ByteArray) {
...@@ -204,10 +204,10 @@ internal object PacketDebugger { ...@@ -204,10 +204,10 @@ internal object PacketDebugger {
//println("raw = " + data.toUHexString()) //println("raw = " + data.toUHexString())
data.read { data.read {
discardExact(3) discardExact(3)
val id = matchPacketId(readUShort()) val id = net.mamoe.mirai.network.packet.matchPacketId(readUShort())
val sequenceId = readUShort() val sequenceId = readUShort()
val packetQQ = readQQ() val packetQQ = readQQ()
if (id == KnownPacketId.HEARTBEAT || (qq != null && packetQQ != qq)) if (id == KnownPacketId.get<HeartbeatPacket>() || (qq != null && packetQQ != qq))
return@read return@read
if (IgnoredPacketIdList.contains(id)) { if (IgnoredPacketIdList.contains(id)) {
...@@ -301,7 +301,7 @@ internal object PacketDebugger { ...@@ -301,7 +301,7 @@ internal object PacketDebugger {
// 3E 03 3F A2 02 00 00 00 01 2E 01 00 00 69 35 // 3E 03 3F A2 02 00 00 00 01 2E 01 00 00 69 35
discardExact(3)//head discardExact(3)//head
val id = matchPacketId(readUShort()) val id = net.mamoe.mirai.network.packet.matchPacketId(readUShort())
val sequence = readUShort().toUHexString() val sequence = readUShort().toUHexString()
if (IgnoredPacketIdList.contains(id)) { if (IgnoredPacketIdList.contains(id)) {
return return
......
...@@ -3,8 +3,8 @@ package packetdebugger ...@@ -3,8 +3,8 @@ package packetdebugger
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readUShort import kotlinx.io.core.readUShort
import net.mamoe.mirai.timpc.network.packet.PacketId import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.timpc.network.packet.matchPacketId import net.mamoe.mirai.network.packet.matchPacketId
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
......
...@@ -19,14 +19,18 @@ import kotlin.coroutines.CoroutineContext ...@@ -19,14 +19,18 @@ import kotlin.coroutines.CoroutineContext
*/ */
@MiraiInternalAPI @MiraiInternalAPI
abstract class BotImpl<N : BotNetworkHandler> constructor( abstract class BotImpl<N : BotNetworkHandler> constructor(
override val account: BotAccount, account: BotAccount,
override val logger: MiraiLogger = DefaultLogger("Bot(" + account.id + ")"), logger: MiraiLogger?,
context: CoroutineContext context: CoroutineContext
) : Bot(), CoroutineScope { ) : Bot(), CoroutineScope {
private val supervisorJob = SupervisorJob(context[Job]) private val supervisorJob = SupervisorJob(context[Job])
override val coroutineContext: CoroutineContext = override val coroutineContext: CoroutineContext =
context + supervisorJob + CoroutineExceptionHandler { _, e -> e.logStacktrace("An exception was thrown under a coroutine of Bot") } 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 { init {
@Suppress("LeakingThis") @Suppress("LeakingThis")
instances.addLast(this) instances.addLast(this)
......
@file:Suppress("EXPERIMENTAL_API_USAGE", "unused") @file:Suppress("EXPERIMENTAL_API_USAGE", "unused")
package net.mamoe.mirai.timpc.network.packet package net.mamoe.mirai.network.packet
/** /**
* 包的最后一次修改时间, 和分析时使用的 TIM 版本 * 包的最后一次修改时间, 和分析时使用的 TIM 版本
...@@ -8,11 +8,11 @@ package net.mamoe.mirai.timpc.network.packet ...@@ -8,11 +8,11 @@ package net.mamoe.mirai.timpc.network.packet
@MustBeDocumented @MustBeDocumented
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.PROPERTY) @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
internal annotation class PacketVersion(val date: String, val timVersion: String) annotation class PacketVersion(val date: String, val timVersion: String)
/** /**
* 带有这个注解的 [Packet] 将不会被记录在 log 中. * 带有这个注解的 [Packet] 将不会被记录在 log 中.
*/ */
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
internal annotation class NoLog annotation class NoLog
\ No newline at end of file \ No newline at end of file
package net.mamoe.mirai.timpc.network.packet package net.mamoe.mirai.network.packet
import kotlinx.io.core.BytePacketBuilder import kotlinx.io.core.BytePacketBuilder
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.IoBuffer import kotlinx.io.core.IoBuffer
import kotlinx.io.core.writeFully
import net.mamoe.mirai.utils.decryptBy import net.mamoe.mirai.utils.decryptBy
import net.mamoe.mirai.utils.encryptBy
import net.mamoe.mirai.utils.io.encryptAndWrite 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<SessionKey> companion object Type : DecrypterType<SessionKey>
} }
/** /**
* [ByteArray] 解密器 * [ByteArray] 解密器
*/ */
@PublishedApi interface DecrypterByteArray : Decrypter {
internal interface DecrypterByteArray : Decrypter {
val value: ByteArray val value: ByteArray
override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value) override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value)
} }
...@@ -28,7 +25,7 @@ internal interface DecrypterByteArray : Decrypter { ...@@ -28,7 +25,7 @@ internal interface DecrypterByteArray : Decrypter {
/** /**
* [IoBuffer] 解密器 * [IoBuffer] 解密器
*/ */
internal interface DecrypterIoBuffer : Decrypter { interface DecrypterIoBuffer : Decrypter {
val value: IoBuffer val value: IoBuffer
override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value) override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value)
} }
...@@ -36,27 +33,28 @@ internal interface DecrypterIoBuffer : Decrypter { ...@@ -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) override fun decrypt(input: ByteReadPacket): ByteReadPacket = block(input)
} }
internal object NoDecrypter : Decrypter, DecrypterType<NoDecrypter> { object NoDecrypter : Decrypter,
DecrypterType<NoDecrypter> {
override fun decrypt(input: ByteReadPacket): ByteReadPacket = input override fun decrypt(input: ByteReadPacket): ByteReadPacket = input
} }
/** /**
* 解密器 * 解密器
*/ */
internal interface Decrypter { interface Decrypter {
fun decrypt(input: ByteReadPacket): ByteReadPacket fun decrypt(input: ByteReadPacket): ByteReadPacket
/** /**
* 连接后将会先用 this 解密, 再用 [another] 解密 * 连接后将会先用 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<D : Decrypter>
internal interface DecrypterType<D : Decrypter> inline fun BytePacketBuilder.encryptAndWrite(key: DecrypterByteArray, encoder: BytePacketBuilder.() -> Unit) =
@PublishedApi
internal inline fun BytePacketBuilder.encryptAndWrite(key: DecrypterByteArray, encoder: BytePacketBuilder.() -> Unit) =
this.encryptAndWrite(key.value, encoder) this.encryptAndWrite(key.value, encoder)
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS", "unused", "MemberVisibilityCanBePrivate") @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.io.core.*
import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.hexToBytes
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
...@@ -18,11 +18,11 @@ import kotlin.jvm.JvmOverloads ...@@ -18,11 +18,11 @@ import kotlin.jvm.JvmOverloads
/** /**
* 待发送给服务器的数据包. 它代表着一个 [ByteReadPacket], * 待发送给服务器的数据包. 它代表着一个 [ByteReadPacket],
*/ */
internal class OutgoingPacket( class OutgoingPacket(
name: String?, name: String?,
val packetId: PacketId, val packetId: PacketId,
val sequenceId: UShort, val sequenceId: UShort,
internal val delegate: ByteReadPacket val delegate: ByteReadPacket
) : Packet { ) : Packet {
val name: String by lazy { val name: String by lazy {
name ?: packetId.toString() name ?: packetId.toString()
...@@ -35,7 +35,9 @@ internal class OutgoingPacket( ...@@ -35,7 +35,9 @@ internal class OutgoingPacket(
* *
* @param TPacket invariant * @param TPacket invariant
*/ */
internal abstract class SessionPacketFactory<TPacket : Packet> : PacketFactory<TPacket, SessionKey>(SessionKey) { abstract class SessionPacketFactory<TPacket : Packet> : PacketFactory<TPacket, SessionKey>(
SessionKey
) {
/** /**
* 在 [BotNetworkHandler] 下处理这个包. 广播事件等. * 在 [BotNetworkHandler] 下处理这个包. 广播事件等.
*/ */
...@@ -45,13 +47,16 @@ internal abstract class SessionPacketFactory<TPacket : Packet> : PacketFactory<T ...@@ -45,13 +47,16 @@ internal abstract class SessionPacketFactory<TPacket : Packet> : PacketFactory<T
/** /**
* 构造一个待发送给服务器的数据包. * 构造一个待发送给服务器的数据包.
*/ */
@UseExperimental(ExperimentalContracts::class) @UseExperimental(ExperimentalContracts::class, MiraiInternalAPI::class)
@JvmOverloads @JvmOverloads
internal inline fun PacketFactory<*, *>.buildOutgoingPacket( inline fun PacketFactory<*, *>.buildOutgoingPacket0(
name: String? = null, name: String? = null,
id: PacketId = this.id, id: PacketId = this.id,
sequenceId: UShort = PacketFactory.atomicNextSequenceId(), sequenceId: UShort = PacketFactory.atomicNextSequenceId(),
headerSizeHint: Int = 0, headerSizeHint: Int = 0,
head: ByteArray,
ver: ByteArray,
tail: ByteArray,
block: BytePacketBuilder.() -> Unit block: BytePacketBuilder.() -> Unit
): OutgoingPacket { ): OutgoingPacket {
contract { contract {
...@@ -60,12 +65,12 @@ internal inline fun PacketFactory<*, *>.buildOutgoingPacket( ...@@ -60,12 +65,12 @@ internal inline fun PacketFactory<*, *>.buildOutgoingPacket(
BytePacketBuilder(headerSizeHint).use { BytePacketBuilder(headerSizeHint).use {
with(it) { with(it) {
writeFully(TIMProtocol.head) writeFully(head)
writeFully(TIMProtocol.ver) writeFully(ver)
writeUShort(id.value) writeUShort(id.value)
writeUShort(sequenceId) writeUShort(sequenceId)
block(this) block(this)
writeFully(TIMProtocol.tail) writeFully(tail)
} }
return OutgoingPacket(name, id, sequenceId, it.build()) return OutgoingPacket(name, id, sequenceId, it.build())
} }
...@@ -75,22 +80,33 @@ internal inline fun PacketFactory<*, *>.buildOutgoingPacket( ...@@ -75,22 +80,33 @@ internal inline fun PacketFactory<*, *>.buildOutgoingPacket(
/** /**
* 构造一个待发送给服务器的会话数据包. * 构造一个待发送给服务器的会话数据包.
*/ */
@UseExperimental(ExperimentalContracts::class) @UseExperimental(ExperimentalContracts::class, MiraiInternalAPI::class)
@JvmOverloads @JvmOverloads
internal inline fun PacketFactory<*, *>.buildSessionPacket( inline fun PacketFactory<*, *>.buildSessionPacket0(
bot: Long, bot: Long,
sessionKey: SessionKey, sessionKey: SessionKey,
name: String? = null, name: String? = null,
id: PacketId = this.id, id: PacketId = this.id,
sequenceId: UShort = PacketFactory.atomicNextSequenceId(), sequenceId: UShort = PacketFactory.atomicNextSequenceId(),
headerSizeHint: Int = 0, headerSizeHint: Int = 0,
version: ByteArray = TIMProtocol.version0x02, version: ByteArray, // in packet body
head: ByteArray,
ver: ByteArray, // in packet head
tail: ByteArray,
block: BytePacketBuilder.() -> Unit block: BytePacketBuilder.() -> Unit
): OutgoingPacket { ): OutgoingPacket {
contract { contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE) 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) writeQQ(bot)
writeFully(version) writeFully(version)
encryptAndWrite(sessionKey) { encryptAndWrite(sessionKey) {
...@@ -102,22 +118,25 @@ internal inline fun PacketFactory<*, *>.buildSessionPacket( ...@@ -102,22 +118,25 @@ internal inline fun PacketFactory<*, *>.buildSessionPacket(
/** /**
* 构造一个待发送给服务器的会话数据包. * 构造一个待发送给服务器的会话数据包.
*/ */
@UseExperimental(ExperimentalContracts::class) @UseExperimental(ExperimentalContracts::class, MiraiInternalAPI::class)
@JvmOverloads @JvmOverloads
internal fun <T> PacketFactory<*, *>.buildSessionProtoPacket( fun <T> PacketFactory<*, *>.buildSessionProtoPacket0(
bot: Long, bot: Long,
sessionKey: SessionKey, sessionKey: SessionKey,
name: String? = null, name: String? = null,
id: PacketId = this.id, id: PacketId = this.id,
sequenceId: UShort = PacketFactory.atomicNextSequenceId(), sequenceId: UShort = PacketFactory.atomicNextSequenceId(),
headerSizeHint: Int = 0, headerSizeHint: Int = 0,
version: ByteArray = TIMProtocol.version0x04, version: ByteArray,
head: Any, head: Any,
serializer: SerializationStrategy<T>, serializer: SerializationStrategy<T>,
protoObj: T protoObj: T,
packetHead: ByteArray,
ver: ByteArray, // in packet head
tail: ByteArray
): OutgoingPacket { ): OutgoingPacket {
require(head is ByteArray || head is UByteArray || head is String) { "Illegal head type" } 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) writeQQ(bot)
writeFully(version) writeFully(version)
encryptAndWrite(sessionKey) { encryptAndWrite(sessionKey) {
...@@ -136,17 +155,20 @@ internal fun <T> PacketFactory<*, *>.buildSessionProtoPacket( ...@@ -136,17 +155,20 @@ internal fun <T> PacketFactory<*, *>.buildSessionProtoPacket(
writeFully(head) writeFully(head)
writeFully(proto) writeFully(proto)
} }
is String -> buildSessionProtoPacket( is String -> buildSessionProtoPacket0(
bot, bot = bot,
sessionKey, sessionKey = sessionKey,
name, name = name,
id, id = id,
sequenceId, sequenceId = sequenceId,
headerSizeHint, headerSizeHint = headerSizeHint,
version, version = version,
head.hexToBytes(), head = head.hexToBytes(),
serializer, serializer = serializer,
protoObj protoObj = protoObj,
packetHead = packetHead,
ver = ver,
tail = tail
) )
} }
} }
......
package net.mamoe.mirai.timpc.network.packet package net.mamoe.mirai.network.packet
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.readBytes import kotlinx.io.core.readBytes
...@@ -8,18 +8,18 @@ import net.mamoe.mirai.utils.io.toUHexString ...@@ -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()}" override fun toString(): String = "UnknownPacket(${id.value.toUHexString()})\nbody=${body.readBytes().toUHexString()}"
} }
/** /**
* 仅用于替换类型应为 [Unit] 的情况 * 仅用于替换类型应为 [Unit] 的情况
*/ */
internal object NoPacket : Packet { object NoPacket : Packet {
override fun toString(): String = "NoPacket" override fun toString(): String = "NoPacket"
} }
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") @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.atomicfu.atomic
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
...@@ -11,6 +11,7 @@ import kotlinx.serialization.DeserializationStrategy ...@@ -11,6 +11,7 @@ import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet 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.ByteArrayPool
import net.mamoe.mirai.utils.io.debugPrint import net.mamoe.mirai.utils.io.debugPrint
import net.mamoe.mirai.utils.io.read import net.mamoe.mirai.utils.io.read
...@@ -24,7 +25,7 @@ import net.mamoe.mirai.utils.readProtoMap ...@@ -24,7 +25,7 @@ import net.mamoe.mirai.utils.readProtoMap
* @param TPacket 服务器回复包解析结果 * @param TPacket 服务器回复包解析结果
* @param TDecrypter 服务器回复包解密器 * @param TDecrypter 服务器回复包解密器
*/ */
internal abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val decrypterType: DecrypterType<TDecrypter>) { abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val decrypterType: DecrypterType<TDecrypter>) {
@Suppress("PropertyName") @Suppress("PropertyName")
internal var _id: PacketId = NullPacketId internal var _id: PacketId = NullPacketId
...@@ -64,8 +65,8 @@ internal abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypt ...@@ -64,8 +65,8 @@ internal abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypt
companion object { companion object {
private val sequenceIdInternal = atomic(1) private val sequenceIdInternal = atomic(1)
@PublishedApi @MiraiInternalAPI
internal fun atomicNextSequenceId(): UShort = sequenceIdInternal.getAndIncrement().toUShort() fun atomicNextSequenceId(): UShort = sequenceIdInternal.getAndIncrement().toUShort()
} }
} }
......
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") @file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
package net.mamoe.mirai.timpc.network.packet package net.mamoe.mirai.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 import net.mamoe.mirai.utils.io.toUHexString
/** /**
* 通过 [value] 匹配一个 [IgnoredPacketId] 或 [KnownPacketId], 无匹配则返回一个 [UnknownPacketId]. * 通过 [value] 匹配一个 [IgnoredPacketId] 或 [KnownPacketId], 无匹配则返回一个 [UnknownPacketId].
*/ */
internal fun matchPacketId(value: UShort): PacketId = fun matchPacketId(value: UShort): PacketId =
IgnoredPacketIds.firstOrNull { it.value == value } ?: KnownPacketId.values().firstOrNull { it.value == value } ?: UnknownPacketId(value) IgnoredPacketIds.firstOrNull { it.value == value }
?: KnownPacketId.entries.firstOrNull { it.value.value == value }?.value
?: UnknownPacketId(value)
/** /**
* 包 ID. * 包 ID.
*/ */
internal interface PacketId { interface PacketId {
val value: UShort val value: UShort
val factory: PacketFactory<*, *> val factory: PacketFactory<*, *>
} }
...@@ -27,7 +25,7 @@ internal interface PacketId { ...@@ -27,7 +25,7 @@ internal interface PacketId {
* 用于代表 `null`. 调用任何属性时都将会得到一个 [error] * 用于代表 `null`. 调用任何属性时都将会得到一个 [error]
*/ */
@Suppress("unused") @Suppress("unused")
internal object NullPacketId : PacketId { object NullPacketId : PacketId {
override val factory: PacketFactory<*, *> get() = error("uninitialized") override val factory: PacketFactory<*, *> get() = error("uninitialized")
override val value: UShort get() = error("uninitialized") override val value: UShort get() = error("uninitialized")
override fun toString(): String = "NullPacketId" override fun toString(): String = "NullPacketId"
...@@ -36,65 +34,43 @@ internal object NullPacketId : PacketId { ...@@ -36,65 +34,43 @@ internal object NullPacketId : PacketId {
/** /**
* 未知的 [PacketId] * 未知的 [PacketId]
*/ */
internal inline class UnknownPacketId(override inline val value: UShort) : PacketId { inline class UnknownPacketId(override inline val value: UShort) : PacketId {
override val factory: PacketFactory<*, *> get() = UnknownPacketFactory override val factory: PacketFactory<*, *> get() = UnknownPacketFactory
override fun toString(): String = "UnknownPacketId(${value.toUHexString()})" override fun toString(): String = "UnknownPacketId(${value.toUHexString()})"
} }
internal object IgnoredPacketIds : List<IgnoredPacketId> by { object IgnoredPacketIds : List<IgnoredPacketId> by {
listOf<UShort>( listOf<UShort>(
).map { IgnoredPacketId(it.toUShort()) } ).map { IgnoredPacketId(it.toUShort()) }
}() }()
internal inline class IgnoredPacketId constructor(override val value: UShort) : PacketId { inline class IgnoredPacketId constructor(override val value: UShort) : PacketId {
override val factory: PacketFactory<*, *> get() = IgnoredPacketFactory override val factory: PacketFactory<*, *> get() = IgnoredPacketFactory
override fun toString(): String = "IgnoredPacketId(${value.toUHexString()})" override fun toString(): String = "IgnoredPacketId(${value.toUHexString()})"
} }
/** class KnownPacketId(override val value: UShort, override val factory: PacketFactory<*, *>) : PacketId {
* 已知的 [matchPacketId]. 所有在 Mirai 中实现过的包都会使用这些 Id companion object : MutableMap<UShort, KnownPacketId> by mutableMapOf() {
*/ operator fun set(key: UShort, factory: PacketFactory<*, *>) {
@Suppress("unused") this[key] = KnownPacketId(key, factory)
internal enum class KnownPacketId(override val value: UShort, override val factory: PacketFactory<*, *>) : }
PacketId {
TOUCH(0x0825u, TouchPacket), inline fun <reified PF : PacketFactory<*, *>> getOrNull(): KnownPacketId? {
SESSION_KEY(0x0828u, RequestSessionPacket), val clazz = PF::class
LOGIN(0x0836u, SubmitPasswordPacket), this.forEach {
CAPTCHA(0x00BAu, CaptchaPacket), if (clazz.isInstance(it.value)) {
SERVER_EVENT_1(0x00CEu, EventPacketFactory), return it.value
SERVER_EVENT_2(0x0017u, EventPacketFactory), }
FRIEND_ONLINE_STATUS_CHANGE(0x0081u, FriendOnlineStatusChangedPacket), }
CHANGE_ONLINE_STATUS(0x00ECu, ChangeOnlineStatusPacket), return null
}
HEARTBEAT(0x0058u, HeartbeatPacket),
S_KEY(0x001Du, RequestSKeyPacket), inline fun <reified PF : PacketFactory<*, *>> get(): KnownPacketId = getOrNull<PF>() ?: throw NoSuchElementException()
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),
; override fun toString(): String = (factory::class.simpleName ?: factory::class.simpleName) + "(${value.toUHexString()})"
init { init {
factory._id = this factory._id = this
} }
}
override fun toString(): String = (factory::class.simpleName ?: this.name) + "(${value.toUHexString()})" \ No newline at end of file
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment