Commit d5bf51a3 authored by Him188's avatar Him188

Adjust class names

parent 6c6f0a48
...@@ -85,7 +85,6 @@ kotlin { ...@@ -85,7 +85,6 @@ kotlin {
jvmTest { jvmTest {
apply plugin: 'java' apply plugin: 'java'
} }
all { all {
......
...@@ -46,6 +46,8 @@ sealed class Contact(val bot: Bot, val id: UInt) { ...@@ -46,6 +46,8 @@ sealed class Contact(val bot: Bot, val id: UInt) {
*/ */
inline class GroupId(val value: UInt) inline class GroupId(val value: UInt)
fun UInt.groupId(): GroupId = GroupId(this)
/** /**
* 一些群 API 使用的 ID. 在使用时会特别注明 * 一些群 API 使用的 ID. 在使用时会特别注明
* *
...@@ -62,7 +64,7 @@ inline class GroupInternalId(val value: UInt) ...@@ -62,7 +64,7 @@ inline class GroupInternalId(val value: UInt)
* @author Him188moe * @author Him188moe
*/ */
class Group internal constructor(bot: Bot, id: UInt) : Contact(bot, id) { class Group internal constructor(bot: Bot, id: UInt) : Contact(bot, id) {
val internalId = groupNumberToId(id) val internalId = GroupId(id).toInternalId()
val members: ContactList<QQ> val members: ContactList<QQ>
//todo members //todo members
get() = throw UnsupportedOperationException("Not yet supported") get() = throw UnsupportedOperationException("Not yet supported")
...@@ -96,42 +98,3 @@ class QQ internal constructor(bot: Bot, number: UInt) : Contact(bot, number) { ...@@ -96,42 +98,3 @@ class QQ internal constructor(bot: Bot, number: UInt) : Contact(bot, number) {
TODO() TODO()
} }
} }
\ No newline at end of file
fun Group.Companion.groupNumberToId(number: UInt): UInt {//求你别出错
val left: Long = number.toString().let {
if (it.length < 6) {
return@groupNumberToId number
}
it.substring(0, it.length - 6).toLong()
}
val right: Long = number.toString().let {
it.substring(it.length - 6).toLong()
}
return when (left) {
in 1..10 -> {
((left + 202).toString() + right.toString()).toUInt()
}
in 11..19 -> {
((left + 469).toString() + right.toString()).toUInt()
}
in 20..66 -> {
((left + 208).toString() + right.toString()).toUInt()
}
in 67..156 -> {
((left + 1943).toString() + right.toString()).toUInt()
}
in 157..209 -> {
((left + 199).toString() + right.toString()).toUInt()
}
in 210..309 -> {
((left + 389).toString() + right.toString()).toUInt()
}
in 310..499 -> {
((left + 349).toString() + right.toString()).toUInt()
}
else -> number
}
}
...@@ -7,7 +7,7 @@ import net.mamoe.mirai.Bot ...@@ -7,7 +7,7 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.Event import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.EventScope import net.mamoe.mirai.event.EventScope
import net.mamoe.mirai.event.ListeningStatus import net.mamoe.mirai.event.ListeningStatus
import net.mamoe.mirai.utils.inlinedRemoveIf import net.mamoe.mirai.utils.internal.inlinedRemoveIf
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**
......
...@@ -6,9 +6,6 @@ import kotlinx.io.core.* ...@@ -6,9 +6,6 @@ import kotlinx.io.core.*
import net.mamoe.mirai.message.* import net.mamoe.mirai.message.*
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.toUHexString import net.mamoe.mirai.utils.toUHexString
import net.mamoe.mirai.utils.writeHex
import net.mamoe.mirai.utils.writeShortLVPacket
import net.mamoe.mirai.utils.writeShortLVString
internal fun IoBuffer.parseMessageFace(): Face { internal fun IoBuffer.parseMessageFace(): Face {
//00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0 //00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0
...@@ -38,7 +35,8 @@ internal fun IoBuffer.parseMessageImage0x06(): Image { ...@@ -38,7 +35,8 @@ internal fun IoBuffer.parseMessageImage0x06(): Image {
discardExact(1) discardExact(1)
//MiraiLogger.logDebug(this.toUHexString()) //MiraiLogger.logDebug(this.toUHexString())
val filenameLength = readShort() val filenameLength = readShort()
val suffix = readString(filenameLength).substringAfter(".")
discardExact(filenameLength.toInt())
discardExact(8)//03 00 04 00 00 02 9C 04 discardExact(8)//03 00 04 00 00 02 9C 04
val length = readShort()//=27 val length = readShort()//=27
return Image(ImageId(readString(length))) return Image(ImageId(readString(length)))
......
...@@ -15,6 +15,7 @@ import net.mamoe.mirai.network.protocol.tim.packet.event.ServerEventPacket ...@@ -15,6 +15,7 @@ import net.mamoe.mirai.network.protocol.tim.packet.event.ServerEventPacket
import net.mamoe.mirai.network.protocol.tim.packet.login.RequestSKeyPacket import net.mamoe.mirai.network.protocol.tim.packet.login.RequestSKeyPacket
import net.mamoe.mirai.network.qqAccount import net.mamoe.mirai.network.qqAccount
import net.mamoe.mirai.utils.log import net.mamoe.mirai.utils.log
import kotlin.coroutines.CoroutineContext
/** /**
* 动作: 获取好友列表, 点赞, 踢人等. * 动作: 获取好友列表, 点赞, 踢人等.
...@@ -23,6 +24,9 @@ import net.mamoe.mirai.utils.log ...@@ -23,6 +24,9 @@ import net.mamoe.mirai.utils.log
* @author Him188moe * @author Him188moe
*/ */
class ActionPacketHandler(session: BotSession) : PacketHandler(session) { class ActionPacketHandler(session: BotSession) : PacketHandler(session) {
override val coroutineContext: CoroutineContext
get() = session.NetworkScope.coroutineContext
companion object Key : PacketHandler.Key<ActionPacketHandler> companion object Key : PacketHandler.Key<ActionPacketHandler>
...@@ -66,15 +70,15 @@ class ActionPacketHandler(session: BotSession) : PacketHandler(session) { ...@@ -66,15 +70,15 @@ class ActionPacketHandler(session: BotSession) : PacketHandler(session) {
} }
} }
suspend fun requestSKey() = with(session) { private suspend fun requestSKey() = with(session) {
withContext(NetworkScope.coroutineContext) { withContext(coroutineContext) {
socket.sendPacket(RequestSKeyPacket()) socket.sendPacket(RequestSKeyPacket())
} }
} }
suspend fun requestAccountInfo() = with(session) { suspend fun requestAccountInfo() = with(session) {
withContext(NetworkScope.coroutineContext) { withContext(coroutineContext) {
socket.sendPacket(RequestAccountInfoPacket(qqAccount, sessionKey)) socket.sendPacket(RequestAccountInfoPacket(qqAccount, sessionKey))
} }
} }
......
package net.mamoe.mirai.network.protocol.tim.handler package net.mamoe.mirai.network.protocol.tim.handler
import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.network.BotSession import net.mamoe.mirai.network.BotSession
import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import kotlin.reflect.KClass import kotlin.reflect.KClass
...@@ -9,7 +10,7 @@ import kotlin.reflect.KClass ...@@ -9,7 +10,7 @@ import kotlin.reflect.KClass
*/ */
abstract class PacketHandler( abstract class PacketHandler(
val session: BotSession val session: BotSession
) { ) : CoroutineScope {
abstract suspend fun onPacketReceived(packet: ServerPacket) abstract suspend fun onPacketReceived(packet: ServerPacket)
interface Key<T : PacketHandler> interface Key<T : PacketHandler>
...@@ -19,18 +20,18 @@ abstract class PacketHandler( ...@@ -19,18 +20,18 @@ abstract class PacketHandler(
} }
} }
class PacketHandlerNode<T : PacketHandler>( internal class PacketHandlerNode<T : PacketHandler>(
val clazz: KClass<T>, val clazz: KClass<T>,
val instance: T, val instance: T,
val key: PacketHandler.Key<T> val key: PacketHandler.Key<T>
) )
fun <T : PacketHandler> T.asNode(key: PacketHandler.Key<T>): PacketHandlerNode<T> { internal fun <T : PacketHandler> T.asNode(key: PacketHandler.Key<T>): PacketHandlerNode<T> {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return PacketHandlerNode(this::class as KClass<T>, this, key) return PacketHandlerNode(this::class as KClass<T>, this, key)
} }
open class PacketHandlerList : MutableList<PacketHandlerNode<*>> by mutableListOf() { internal open class PacketHandlerList : MutableList<PacketHandlerNode<*>> by mutableListOf() {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
operator fun <T : PacketHandler> get(key: PacketHandler.Key<T>): T = this.first { it.key === key }.instance as T operator fun <T : PacketHandler> get(key: PacketHandler.Key<T>): T = this.first { it.key === key }.instance as T
} }
...@@ -6,9 +6,9 @@ import kotlinx.io.core.BytePacketBuilder ...@@ -6,9 +6,9 @@ import kotlinx.io.core.BytePacketBuilder
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.writeUByte import kotlinx.io.core.writeUByte
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.utils.encryptAndWrite import net.mamoe.mirai.utils.io.encryptAndWrite
import net.mamoe.mirai.utils.writeHex import net.mamoe.mirai.utils.io.writeHex
import net.mamoe.mirai.utils.writeQQ import net.mamoe.mirai.utils.io.writeQQ
/** /**
* 获取升级天数等. * 获取升级天数等.
......
...@@ -5,9 +5,9 @@ package net.mamoe.mirai.network.protocol.tim.packet ...@@ -5,9 +5,9 @@ package net.mamoe.mirai.network.protocol.tim.packet
import kotlinx.io.core.BytePacketBuilder import kotlinx.io.core.BytePacketBuilder
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.utils.encryptAndWrite import net.mamoe.mirai.utils.io.encryptAndWrite
import net.mamoe.mirai.utils.writeHex import net.mamoe.mirai.utils.io.writeHex
import net.mamoe.mirai.utils.writeQQ import net.mamoe.mirai.utils.io.writeQQ
@PacketId(0x00_58u) @PacketId(0x00_58u)
class HeartbeatPacket( class HeartbeatPacket(
......
...@@ -5,7 +5,7 @@ package net.mamoe.mirai.network.protocol.tim.packet ...@@ -5,7 +5,7 @@ package net.mamoe.mirai.network.protocol.tim.packet
import kotlinx.atomicfu.atomic import kotlinx.atomicfu.atomic
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.utils.writeHex import net.mamoe.mirai.utils.io.writeHex
/** /**
* 发给服务器的数据包. 必须有 [PacketId] 注解或 `override` [id]. 否则将会抛出 [IllegalStateException] * 发给服务器的数据包. 必须有 [PacketId] 注解或 `override` [id]. 否则将会抛出 [IllegalStateException]
......
...@@ -4,8 +4,8 @@ package net.mamoe.mirai.network.protocol.tim.packet ...@@ -4,8 +4,8 @@ package net.mamoe.mirai.network.protocol.tim.packet
import kotlinx.io.core.BytePacketBuilder import kotlinx.io.core.BytePacketBuilder
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import net.mamoe.mirai.utils.encryptAndWrite import net.mamoe.mirai.utils.io.encryptAndWrite
import net.mamoe.mirai.utils.writeQQ import net.mamoe.mirai.utils.io.writeQQ
class OutgoingRawPacket( class OutgoingRawPacket(
override val id: UShort, override val id: UShort,
......
...@@ -4,11 +4,14 @@ package net.mamoe.mirai.network.protocol.tim.packet ...@@ -4,11 +4,14 @@ package net.mamoe.mirai.network.protocol.tim.packet
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.GroupInternalId
import net.mamoe.mirai.network.session import net.mamoe.mirai.network.session
import net.mamoe.mirai.qqAccount import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.io.read import net.mamoe.mirai.utils.hexToBytes
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.httpPostGroupImage
import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.readUnsignedVarInt
suspend fun Group.uploadImage( suspend fun Group.uploadImage(
...@@ -19,7 +22,7 @@ suspend fun Group.uploadImage( ...@@ -19,7 +22,7 @@ suspend fun Group.uploadImage(
if (it.uKey != null) { if (it.uKey != null) {
httpPostGroupImage( httpPostGroupImage(
botAccount = bot.qqAccount, botAccount = bot.qqAccount,
groupNumber = internalId, groupInternalId = internalId,
imageInput = image.input, imageInput = image.input,
inputSize = image.inputSize, inputSize = image.inputSize,
uKeyHex = it.uKey!!.toUHexString("") uKeyHex = it.uKey!!.toUHexString("")
...@@ -35,7 +38,7 @@ suspend fun Group.uploadImage( ...@@ -35,7 +38,7 @@ suspend fun Group.uploadImage(
@PacketVersion(date = "2019.10.20", timVersion = "2.3.2.21173") @PacketVersion(date = "2019.10.20", timVersion = "2.3.2.21173")
class GroupImageIdRequestPacket( class GroupImageIdRequestPacket(
private val bot: UInt, private val bot: UInt,
private val groupId: UInt, private val groupInternalId: GroupInternalId,
private val image: ExternalImage, private val image: ExternalImage,
private val sessionKey: ByteArray private val sessionKey: ByteArray
) : OutgoingPacket() { ) : OutgoingPacket() {
...@@ -146,7 +149,7 @@ class GroupImageIdRequestPacket( ...@@ -146,7 +149,7 @@ class GroupImageIdRequestPacket(
writeHex("01 12 03 98 01 01 10 01 1A") writeHex("01 12 03 98 01 01 10 01 1A")
writeUVarintLVPacket(lengthOffset = { it + 1 }) { writeUVarintLVPacket(lengthOffset = { it + 1 }) {
writeTUVarint(0x08u, groupId) writeTUVarint(0x08u, groupInternalId.value)
writeTUVarint(0x10u, bot) writeTUVarint(0x10u, bot)
writeTV(0x1800u) writeTV(0x1800u)
......
...@@ -8,9 +8,9 @@ import kotlinx.io.core.discardExact ...@@ -8,9 +8,9 @@ import kotlinx.io.core.discardExact
import kotlinx.io.core.readUShort import kotlinx.io.core.readUShort
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.* import net.mamoe.mirai.network.protocol.tim.packet.*
import net.mamoe.mirai.utils.encryptAndWrite import net.mamoe.mirai.utils.io.encryptAndWrite
import net.mamoe.mirai.utils.writeHex import net.mamoe.mirai.utils.io.writeHex
import net.mamoe.mirai.utils.writeQQ import net.mamoe.mirai.utils.io.writeQQ
/** /**
* 向服务器检查是否可添加某人为好友 * 向服务器检查是否可添加某人为好友
......
...@@ -12,8 +12,8 @@ import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket ...@@ -12,8 +12,8 @@ import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
import net.mamoe.mirai.network.protocol.tim.packet.PacketId import net.mamoe.mirai.network.protocol.tim.packet.PacketId
import net.mamoe.mirai.network.protocol.tim.packet.PacketVersion import net.mamoe.mirai.network.protocol.tim.packet.PacketVersion
import net.mamoe.mirai.network.protocol.tim.packet.ResponsePacket import net.mamoe.mirai.network.protocol.tim.packet.ResponsePacket
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.md5
fun main() { fun main() {
println("牛逼".toMessage().toChain().toPacket(true).readBytes().toUHexString()) println("牛逼".toMessage().toChain().toPacket(true).readBytes().toUHexString())
......
...@@ -4,29 +4,30 @@ package net.mamoe.mirai.network.protocol.tim.packet.action ...@@ -4,29 +4,30 @@ package net.mamoe.mirai.network.protocol.tim.packet.action
import kotlinx.io.core.BytePacketBuilder import kotlinx.io.core.BytePacketBuilder
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.contact.GroupInternalId
import net.mamoe.mirai.message.MessageChain import net.mamoe.mirai.message.MessageChain
import net.mamoe.mirai.message.internal.toPacket import net.mamoe.mirai.message.internal.toPacket
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
import net.mamoe.mirai.network.protocol.tim.packet.PacketId import net.mamoe.mirai.network.protocol.tim.packet.PacketId
import net.mamoe.mirai.network.protocol.tim.packet.ResponsePacket import net.mamoe.mirai.network.protocol.tim.packet.ResponsePacket
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.io.*
@PacketId(0x00_02u) @PacketId(0x00_02u)
class SendGroupMessagePacket( class SendGroupMessagePacket(
private val botQQ: UInt, private val botQQ: UInt,
private val groupId: UInt,//不是 number private val groupInternalId: GroupInternalId,
private val sessionKey: ByteArray, private val sessionKey: ByteArray,
private val message: MessageChain private val message: MessageChain
) : OutgoingPacket() { ) : OutgoingPacket() {
override fun encode(builder: BytePacketBuilder) = with(builder) { override fun encode(builder: BytePacketBuilder) = with(builder) {
this.writeQQ(botQQ) writeQQ(botQQ)
this.writeHex(TIMProtocol.fixVer2) writeHex(TIMProtocol.fixVer2)
this.encryptAndWrite(sessionKey) { encryptAndWrite(sessionKey) {
writeByte(0x2A) writeByte(0x2A)
writeGroup(groupId) writeGroup(groupInternalId)
writeShortLVPacket { writeShortLVPacket {
writeHex("00 01 01") writeHex("00 01 01")
......
...@@ -26,7 +26,7 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP ...@@ -26,7 +26,7 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP
* 发送方权限. * 发送方权限.
*/ */
lateinit var senderPermission: SenderPermission lateinit var senderPermission: SenderPermission
lateinit var message: MessageChain var message: MessageChain by Delegates.notNull()
override fun decode() = with(input) { override fun decode() = with(input) {
discardExact(31) discardExact(31)
...@@ -95,7 +95,7 @@ class ServerFriendMessageEventPacket(input: ByteReadPacket, eventIdentity: Event ...@@ -95,7 +95,7 @@ class ServerFriendMessageEventPacket(input: ByteReadPacket, eventIdentity: Event
*/ */
var isPrevious: Boolean = false var isPrevious: Boolean = false
lateinit var message: MessageChain var message: MessageChain by Delegates.notNull()
//来自自己发送给自己 //来自自己发送给自己
//00 00 00 20 00 05 00 02 00 06 00 06 00 04 00 01 01 07 00 09 00 06 03 E9 20 02 EB 94 00 0A 00 04 01 00 00 00 0C 17 76 E4 B8 DD 76 E4 B8 DD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B A6 D2 5D A3 2A 3F 00 00 5D A3 2A 3F 01 00 00 00 00 4D 53 47 00 00 00 00 00 5D A3 2A 3F 0C 8A 59 3D 00 00 00 00 0A 00 86 02 00 06 E5 AE 8B E4 BD 93 00 00 01 00 06 01 00 03 31 32 33 19 00 1F 01 00 1C AA 02 19 08 00 88 01 00 9A 01 11 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00 0E 00 0E 01 00 04 00 00 00 00 0A 00 04 00 00 00 00 //00 00 00 20 00 05 00 02 00 06 00 06 00 04 00 01 01 07 00 09 00 06 03 E9 20 02 EB 94 00 0A 00 04 01 00 00 00 0C 17 76 E4 B8 DD 76 E4 B8 DD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0B A6 D2 5D A3 2A 3F 00 00 5D A3 2A 3F 01 00 00 00 00 4D 53 47 00 00 00 00 00 5D A3 2A 3F 0C 8A 59 3D 00 00 00 00 0A 00 86 02 00 06 E5 AE 8B E4 BD 93 00 00 01 00 06 01 00 03 31 32 33 19 00 1F 01 00 1C AA 02 19 08 00 88 01 00 9A 01 11 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00 0E 00 0E 01 00 04 00 00 00 00 0A 00 04 00 00 00 00
......
...@@ -8,10 +8,9 @@ import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket ...@@ -8,10 +8,9 @@ import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import net.mamoe.mirai.network.protocol.tim.packet.applySequence import net.mamoe.mirai.network.protocol.tim.packet.applySequence
import net.mamoe.mirai.network.protocol.tim.packet.decryptBy import net.mamoe.mirai.network.protocol.tim.packet.decryptBy
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.io.readBoolean import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.io.readIoBuffer import net.mamoe.mirai.utils.toByteArray
import net.mamoe.mirai.utils.io.toUHexString
/** /**
* 事件的识别 ID. 在 [事件确认包][ServerEventPacket.ResponsePacket] 中被使用. * 事件的识别 ID. 在 [事件确认包][ServerEventPacket.ResponsePacket] 中被使用.
......
...@@ -6,25 +6,21 @@ import kotlinx.io.core.* ...@@ -6,25 +6,21 @@ import kotlinx.io.core.*
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.* import net.mamoe.mirai.network.protocol.tim.packet.*
import net.mamoe.mirai.utils.Tested import net.mamoe.mirai.utils.Tested
import net.mamoe.mirai.utils.encryptAndWrite import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.io.readIoBuffer
import net.mamoe.mirai.utils.io.toReadPacket
import net.mamoe.mirai.utils.writeHex
import net.mamoe.mirai.utils.writeQQ
/** /**
* 客户端请求验证码图片数据的第几部分 * 客户端请求验证码图片数据的第几部分
*/ */
@PacketId(0x00_BAu) @PacketId(0x00_BAu)
class OutgoingCaptchaTransmissionRequestPacket( class RequestCaptchaTransmissionPacket(
private val qq: UInt, private val bot: UInt,
private val token0825: ByteArray, private val token0825: ByteArray,
private val verificationSequence: Int, private val verificationSequence: Int,
private val token00BA: ByteArray private val token00BA: ByteArray
) : OutgoingPacket() { ) : OutgoingPacket() {
@Tested @Tested
override fun encode(builder: BytePacketBuilder) = with(builder) { override fun encode(builder: BytePacketBuilder) = with(builder) {
this.writeQQ(qq) this.writeQQ(bot)
this.writeHex(TIMProtocol.fixVer) this.writeHex(TIMProtocol.fixVer)
this.writeHex(TIMProtocol.key00BA) this.writeHex(TIMProtocol.key00BA)
this.encryptAndWrite(TIMProtocol.key00BA) { this.encryptAndWrite(TIMProtocol.key00BA) {
...@@ -48,8 +44,8 @@ class OutgoingCaptchaTransmissionRequestPacket( ...@@ -48,8 +44,8 @@ class OutgoingCaptchaTransmissionRequestPacket(
* 提交验证码 * 提交验证码
*/ */
@PacketId(0x00_BAu) @PacketId(0x00_BAu)
class OutgoingCaptchaSubmitPacket( class SubmitCaptchaPacket(
private val qq: UInt, private val bot: UInt,
private val token0825: ByteArray, private val token0825: ByteArray,
private val captcha: String, private val captcha: String,
private val verificationToken: IoBuffer private val verificationToken: IoBuffer
...@@ -59,7 +55,7 @@ class OutgoingCaptchaSubmitPacket( ...@@ -59,7 +55,7 @@ class OutgoingCaptchaSubmitPacket(
} }
override fun encode(builder: BytePacketBuilder) = with(builder) { override fun encode(builder: BytePacketBuilder) = with(builder) {
this.writeQQ(qq) this.writeQQ(bot)
this.writeHex(TIMProtocol.fixVer) this.writeHex(TIMProtocol.fixVer)
this.writeHex(TIMProtocol.key00BA) this.writeHex(TIMProtocol.key00BA)
this.encryptAndWrite(TIMProtocol.key00BA) { this.encryptAndWrite(TIMProtocol.key00BA) {
...@@ -114,7 +110,7 @@ class OutgoingCaptchaRefreshPacket( ...@@ -114,7 +110,7 @@ class OutgoingCaptchaRefreshPacket(
* @author Him188moe * @author Him188moe
*/ */
@PacketId(0x00_BAu) @PacketId(0x00_BAu)
open class ServerCaptchaTransmissionPacket(input: ByteReadPacket) : ServerCaptchaPacket(input) { open class CaptchaTransmissionResponsePacket(input: ByteReadPacket) : ServerCaptchaPacket(input) {
lateinit var captchaSectionN: IoBuffer lateinit var captchaSectionN: IoBuffer
lateinit var verificationToken: IoBuffer//56bytes lateinit var verificationToken: IoBuffer//56bytes
...@@ -141,7 +137,7 @@ open class ServerCaptchaTransmissionPacket(input: ByteReadPacket) : ServerCaptch ...@@ -141,7 +137,7 @@ open class ServerCaptchaTransmissionPacket(input: ByteReadPacket) : ServerCaptch
/* /*
fun main() { fun main() {
val data = "13 00 05 01 00 00 01 23 00 38 59 32 29 5A 3E 3D 2D FC F5 22 EB 9E 2D FB 9C 4F AA 06 C8 32 3D F0 3C 2C 2B BA 8D 05 C4 9B C1 74 3B 70 F1 99 90 BB 6E 3E 6F 74 48 97 D3 61 B7 04 C0 A3 F1 DF 40 A4 DC 2B 00 A2 01 2D BB BB E8 FE B8 AF B3 6F 39 7C EA E2 5B 91 BE DB 59 38 CF 58 BC F2 88 F1 09 CF 92 E9 F7 FB 13 76 C5 68 29 23 3F 8E 43 16 2E 50 D7 FA 4D C1 F7 67 EF 27 FB C6 F1 A7 25 A4 BC 45 39 3A EA B2 A5 38 02 FF 4B C9 FF EB BD 89 E5 5D B9 4A 2A BE 5F 52 F1 EB 09 29 CB 3E 66 CF EF 97 89 47 BB 6B E0 7B 4A 3E A1 BC 3F FB F2 0A 83 CB E3 EA B9 43 E1 26 88 03 0B A7 E0 B2 AD 7F 83 CC DA 74 85 83 72 08 EC D2 F9 95 05 15 05 96 F7 1C FF 00 82 C3 90 22 A4 BA 90 D5 00 00 00 00 49 45 4E 44 AE 42 60 82 03 00 00 28 EA 32 5A 85 C8 D2 73 B3 40 39 77 85 65 98 00 FE 03 A2 A5 95 B4 2F E6 79 7A DE 5A 03 10 C8 3D BF 6D 3D 8B 51 84 C2 6D 49 00 10 92 AA 69 FB C6 3D 60 5A 7A A4 AC 7A B0 71 00 36".hexToBytes() val data = "13 00 05 01 00 00 01 23 00 38 59 32 29 5A 3E 3D 2D FC F5 22 EB 9E 2D FB 9C 4F AA 06 C8 32 3D F0 3C 2C 2B BA 8D 05 C4 9B C1 74 3B 70 F1 99 90 BB 6E 3E 6F 74 48 97 D3 61 B7 04 C0 A3 F1 DF 40 A4 DC 2B 00 A2 01 2D BB BB E8 FE B8 AF B3 6F 39 7C EA E2 5B 91 BE DB 59 38 CF 58 BC F2 88 F1 09 CF 92 E9 F7 FB 13 76 C5 68 29 23 3F 8E 43 16 2E 50 D7 FA 4D C1 F7 67 EF 27 FB C6 F1 A7 25 A4 BC 45 39 3A EA B2 A5 38 02 FF 4B C9 FF EB BD 89 E5 5D B9 4A 2A BE 5F 52 F1 EB 09 29 CB 3E 66 CF EF 97 89 47 BB 6B E0 7B 4A 3E A1 BC 3F FB F2 0A 83 CB E3 EA B9 43 E1 26 88 03 0B A7 E0 B2 AD 7F 83 CC DA 74 85 83 72 08 EC D2 F9 95 05 15 05 96 F7 1C FF 00 82 C3 90 22 A4 BA 90 D5 00 00 00 00 49 45 4E 44 AE 42 60 82 03 00 00 28 EA 32 5A 85 C8 D2 73 B3 40 39 77 85 65 98 00 FE 03 A2 A5 95 B4 2F E6 79 7A DE 5A 03 10 C8 3D BF 6D 3D 8B 51 84 C2 6D 49 00 10 92 AA 69 FB C6 3D 60 5A 7A A4 AC 7A B0 71 00 36".hexToBytes()
ServerCaptchaTransmissionPacket(data.toReadPacket(), data.size, "00 BA 31 01".hexToBytes()).let { CaptchaTransmissionResponsePacket(data.toReadPacket(), data.size, "00 BA 31 01".hexToBytes()).let {
it.dataDecode() it.dataDecode()
println(it.toString()) println(it.toString())
} }
...@@ -153,7 +149,7 @@ fun main() { ...@@ -153,7 +149,7 @@ fun main() {
* @author Him188moe * @author Him188moe
*/ */
@PacketId(0x00_BAu) @PacketId(0x00_BAu)
class ServerCaptchaCorrectPacket(input: ByteReadPacket) : ServerCaptchaPacket(input) { class CaptchaCorrectPacket(input: ByteReadPacket) : ServerCaptchaPacket(input) {
lateinit var token00BA: ByteArray//56 bytes lateinit var token00BA: ByteArray//56 bytes
override fun decode() = with(input) { override fun decode() = with(input) {
...@@ -172,9 +168,9 @@ abstract class ServerCaptchaPacket(input: ByteReadPacket) : ServerPacket(input) ...@@ -172,9 +168,9 @@ abstract class ServerCaptchaPacket(input: ByteReadPacket) : ServerPacket(input)
return when (data.size) { return when (data.size) {
66, 66,
95 -> ServerCaptchaCorrectPacket(data.toReadPacket()) 95 -> CaptchaCorrectPacket(data.toReadPacket())
//66 -> ServerCaptchaUnknownPacket(data.toReadPacket()) //66 -> ServerCaptchaUnknownPacket(data.toReadPacket())
else -> ServerCaptchaTransmissionPacket(data.toReadPacket()) else -> CaptchaTransmissionResponsePacket(data.toReadPacket())
}.applySequence(sequenceId) }.applySequence(sequenceId)
} }
} }
......
...@@ -8,9 +8,9 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol ...@@ -8,9 +8,9 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
import net.mamoe.mirai.network.protocol.tim.packet.PacketId import net.mamoe.mirai.network.protocol.tim.packet.PacketId
import net.mamoe.mirai.utils.OnlineStatus import net.mamoe.mirai.utils.OnlineStatus
import net.mamoe.mirai.utils.encryptAndWrite import net.mamoe.mirai.utils.io.encryptAndWrite
import net.mamoe.mirai.utils.writeHex import net.mamoe.mirai.utils.io.writeHex
import net.mamoe.mirai.utils.writeQQ import net.mamoe.mirai.utils.io.writeQQ
/** /**
* 改变在线状态: "我在线上", "隐身" 等 * 改变在线状态: "我在线上", "隐身" 等
......
...@@ -8,14 +8,17 @@ import kotlinx.io.core.writeFully ...@@ -8,14 +8,17 @@ import kotlinx.io.core.writeFully
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
import net.mamoe.mirai.network.protocol.tim.packet.PacketId import net.mamoe.mirai.network.protocol.tim.packet.PacketId
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.TEA
import net.mamoe.mirai.utils.hexToBytes
import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.writeCRC32
/** /**
* 提交密码 * 提交密码
*/ */
@PacketId(0x08_36u) @PacketId(0x08_36u)
class OutgoingPasswordSubmissionPacket constructor( class SubmitPasswordPacket constructor(
private val bot: UInt, private val bot: UInt,
private val password: String, private val password: String,
private val loginTime: Int, private val loginTime: Int,
......
@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE") @file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE", "FunctionName")
package net.mamoe.mirai.network.protocol.tim.packet.login package net.mamoe.mirai.network.protocol.tim.packet.login
...@@ -11,13 +11,7 @@ import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket ...@@ -11,13 +11,7 @@ import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
import net.mamoe.mirai.network.protocol.tim.packet.PacketId import net.mamoe.mirai.network.protocol.tim.packet.PacketId
import net.mamoe.mirai.network.protocol.tim.packet.ResponsePacket import net.mamoe.mirai.network.protocol.tim.packet.ResponsePacket
import net.mamoe.mirai.network.qqAccount import net.mamoe.mirai.network.qqAccount
import net.mamoe.mirai.utils.encryptAndWrite import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.io.DebugLogger
import net.mamoe.mirai.utils.io.readRemainingBytes
import net.mamoe.mirai.utils.io.readString
import net.mamoe.mirai.utils.io.toUHexString
import net.mamoe.mirai.utils.writeHex
import net.mamoe.mirai.utils.writeQQ
fun BotSession.RequestSKeyPacket() = RequestSKeyPacket(qqAccount, sessionKey) fun BotSession.RequestSKeyPacket() = RequestSKeyPacket(qqAccount, sessionKey)
...@@ -27,11 +21,11 @@ fun BotSession.RequestSKeyPacket() = RequestSKeyPacket(qqAccount, sessionKey) ...@@ -27,11 +21,11 @@ fun BotSession.RequestSKeyPacket() = RequestSKeyPacket(qqAccount, sessionKey)
*/ */
@PacketId(0x00_1Du) @PacketId(0x00_1Du)
class RequestSKeyPacket( class RequestSKeyPacket(
private val qq: UInt, private val bot: UInt,
private val sessionKey: ByteArray private val sessionKey: ByteArray
) : OutgoingPacket() { ) : OutgoingPacket() {
override fun encode(builder: BytePacketBuilder) = with(builder) { override fun encode(builder: BytePacketBuilder) = with(builder) {
writeQQ(qq) writeQQ(bot)
writeHex(TIMProtocol.fixVer2) writeHex(TIMProtocol.fixVer2)
encryptAndWrite(sessionKey) { encryptAndWrite(sessionKey) {
writeHex("33 00 05 00 08 74 2E 71 71 2E 63 6F 6D 00 0A 71 75 6E 2E 71 71 2E 63 6F 6D 00 0C 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 00 0C 6A 75 62 61 6F 2E 71 71 2E 63 6F 6D 00 09 6B 65 2E 71 71 2E 63 6F 6D") writeHex("33 00 05 00 08 74 2E 71 71 2E 63 6F 6D 00 0A 71 75 6E 2E 71 71 2E 63 6F 6D 00 0C 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 00 0C 6A 75 62 61 6F 2E 71 71 2E 63 6F 6D 00 09 6B 65 2E 71 71 2E 63 6F 6D")
......
...@@ -16,13 +16,13 @@ import kotlin.properties.Delegates ...@@ -16,13 +16,13 @@ import kotlin.properties.Delegates
sealed class ServerLoginResponsePacket(input: ByteReadPacket) : ServerPacket(input) sealed class ServerLoginResponsePacket(input: ByteReadPacket) : ServerPacket(input)
@PacketId(0x08_36u) @PacketId(0x08_36u)
class ServerLoginResponseFailedPacket(val loginResult: LoginResult, input: ByteReadPacket) : ServerLoginResponsePacket(input) class LoginResponseFailedPacket(val loginResult: LoginResult, input: ByteReadPacket) : ServerLoginResponsePacket(input)
/** /**
* 服务器进行加密后返回 privateKey * 服务器进行加密后返回 privateKey
*/ */
@PacketId(0x08_36u) @PacketId(0x08_36u)
class ServerLoginResponseKeyExchangePacket(input: ByteReadPacket) : ServerLoginResponsePacket(input) { class LoginResponseKeyExchangeResponsePacket(input: ByteReadPacket) : ServerLoginResponsePacket(input) {
lateinit var tlv0006: IoBuffer//120bytes lateinit var tlv0006: IoBuffer//120bytes
var tokenUnknown: ByteArray? = null var tokenUnknown: ByteArray? = null
...@@ -47,7 +47,8 @@ class ServerLoginResponseKeyExchangePacket(input: ByteReadPacket) : ServerLoginR ...@@ -47,7 +47,8 @@ class ServerLoginResponseKeyExchangePacket(input: ByteReadPacket) : ServerLoginR
@PacketId(0x08_36u) @PacketId(0x08_36u)
class Encrypted(input: ByteReadPacket) : ServerPacket(input) { class Encrypted(input: ByteReadPacket) : ServerPacket(input) {
@Tested @Tested
fun decrypt(privateKey: ByteArray): ServerLoginResponseKeyExchangePacket = ServerLoginResponseKeyExchangePacket(this.decryptBy(TIMProtocol.shareKey, privateKey)).applySequence(sequenceId) fun decrypt(privateKey: ByteArray): LoginResponseKeyExchangeResponsePacket =
LoginResponseKeyExchangeResponsePacket(this.decryptBy(TIMProtocol.shareKey, privateKey)).applySequence(sequenceId)
} }
} }
...@@ -60,7 +61,7 @@ enum class Gender(val id: Boolean) { ...@@ -60,7 +61,7 @@ enum class Gender(val id: Boolean) {
* @author NaturalHG * @author NaturalHG
*/ */
@PacketId(0x08_36u) @PacketId(0x08_36u)
class ServerLoginResponseSuccessPacket(input: ByteReadPacket) : ServerLoginResponsePacket(input) { class LoginResponseSuccessPacket(input: ByteReadPacket) : ServerLoginResponsePacket(input) {
lateinit var sessionResponseDecryptionKey: IoBuffer//16 bytes| lateinit var sessionResponseDecryptionKey: IoBuffer//16 bytes|
lateinit var token38: IoBuffer//56 lateinit var token38: IoBuffer//56
...@@ -116,7 +117,7 @@ class ServerLoginResponseSuccessPacket(input: ByteReadPacket) : ServerLoginRespo ...@@ -116,7 +117,7 @@ class ServerLoginResponseSuccessPacket(input: ByteReadPacket) : ServerLoginRespo
@PacketId(0x08_36u) @PacketId(0x08_36u)
class Encrypted(input: ByteReadPacket) : ServerPacket(input) { class Encrypted(input: ByteReadPacket) : ServerPacket(input) {
fun decrypt(privateKey: ByteArray): ServerLoginResponseSuccessPacket = ServerLoginResponseSuccessPacket(this.decryptBy(TIMProtocol.shareKey, privateKey)).applySequence(sequenceId) fun decrypt(privateKey: ByteArray): LoginResponseSuccessPacket = LoginResponseSuccessPacket(this.decryptBy(TIMProtocol.shareKey, privateKey)).applySequence(sequenceId)
} }
} }
...@@ -127,7 +128,7 @@ class ServerLoginResponseSuccessPacket(input: ByteReadPacket) : ServerLoginRespo ...@@ -127,7 +128,7 @@ class ServerLoginResponseSuccessPacket(input: ByteReadPacket) : ServerLoginRespo
* @author Him188moe * @author Him188moe
*/ */
@PacketId(0x08_36u) @PacketId(0x08_36u)
class ServerLoginResponseCaptchaInitPacket(input: ByteReadPacket) : ServerLoginResponsePacket(input) { class LoginResponseCaptchaInitPacket(input: ByteReadPacket) : ServerLoginResponsePacket(input) {
lateinit var captchaPart1: IoBuffer lateinit var captchaPart1: IoBuffer
lateinit var token00BA: ByteArray lateinit var token00BA: ByteArray
...@@ -152,6 +153,6 @@ class ServerLoginResponseCaptchaInitPacket(input: ByteReadPacket) : ServerLoginR ...@@ -152,6 +153,6 @@ class ServerLoginResponseCaptchaInitPacket(input: ByteReadPacket) : ServerLoginR
@PacketId(0x08_36u) @PacketId(0x08_36u)
class Encrypted(input: ByteReadPacket) : ServerPacket(input) { class Encrypted(input: ByteReadPacket) : ServerPacket(input) {
fun decrypt(): ServerLoginResponseCaptchaInitPacket = ServerLoginResponseCaptchaInitPacket(decryptAsByteArray(TIMProtocol.shareKey).toReadPacket()).applySequence(sequenceId) fun decrypt(): LoginResponseCaptchaInitPacket = LoginResponseCaptchaInitPacket(decryptAsByteArray(TIMProtocol.shareKey).toReadPacket()).applySequence(sequenceId)
} }
} }
\ No newline at end of file
...@@ -5,11 +5,12 @@ package net.mamoe.mirai.network.protocol.tim.packet.login ...@@ -5,11 +5,12 @@ package net.mamoe.mirai.network.protocol.tim.packet.login
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.* import net.mamoe.mirai.network.protocol.tim.packet.*
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.Tested
import net.mamoe.mirai.utils.io.readIoBuffer import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.localIpAddress
@PacketId(0x08_28u) @PacketId(0x08_28u)
class OutgoingSessionRequestPacket( class RequestSessionPacket(
private val bot: UInt, private val bot: UInt,
private val serverIp: String, private val serverIp: String,
private val token38: IoBuffer, private val token38: IoBuffer,
...@@ -61,7 +62,7 @@ class OutgoingSessionRequestPacket( ...@@ -61,7 +62,7 @@ class OutgoingSessionRequestPacket(
@PacketId(0x08_28u) @PacketId(0x08_28u)
class ServerSessionKeyResponsePacket(input: ByteReadPacket) : ServerPacket(input) { class SessionKeyResponsePacket(input: ByteReadPacket) : ServerPacket(input) {
lateinit var sessionKey: ByteArray lateinit var sessionKey: ByteArray
lateinit var tlv0105: ByteReadPacket lateinit var tlv0105: ByteReadPacket
...@@ -111,7 +112,7 @@ Discarded(11) =41 01 00 02 03 3C 01 03 00 00 86 ...@@ -111,7 +112,7 @@ Discarded(11) =41 01 00 02 03 3C 01 03 00 00 86
@PacketId(0x08_28u) @PacketId(0x08_28u)
class Encrypted(input: ByteReadPacket) : ServerPacket(input) { class Encrypted(input: ByteReadPacket) : ServerPacket(input) {
fun decrypt(sessionResponseDecryptionKey: IoBuffer): ServerSessionKeyResponsePacket = fun decrypt(sessionResponseDecryptionKey: IoBuffer): SessionKeyResponsePacket =
ServerSessionKeyResponsePacket(decryptBy(sessionResponseDecryptionKey)).applySequence(sequenceId) SessionKeyResponsePacket(decryptBy(sessionResponseDecryptionKey)).applySequence(sequenceId)
} }
} }
\ No newline at end of file
...@@ -8,20 +8,21 @@ import kotlinx.io.core.discardExact ...@@ -8,20 +8,21 @@ import kotlinx.io.core.discardExact
import kotlinx.io.core.readBytes import kotlinx.io.core.readBytes
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.* import net.mamoe.mirai.network.protocol.tim.packet.*
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.hexToBytes
import net.mamoe.mirai.utils.io.readIP import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.toUHexString
/** /**
* The packet received when logging in, used to redirect server address * The packet received when logging in, used to redirect server address
* *
* @see OutgoingTouchRedirectionPacket * @see OutgoingTouchRedirectionPacket
* @see OutgoingPasswordSubmissionPacket * @see SubmitPasswordPacket
* *
* @author Him188moe * @author Him188moe
*/ */
@Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") @Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
@PacketId(0x08_25u) @PacketId(0x08_25u)
class ServerTouchResponsePacket(input: ByteReadPacket) : ServerPacket(input) { class TouchResponsePacket(input: ByteReadPacket) : ServerPacket(input) {
var serverIP: String? = null var serverIP: String? = null
var loginTime: Int = 0 var loginTime: Int = 0
...@@ -51,7 +52,7 @@ class ServerTouchResponsePacket(input: ByteReadPacket) : ServerPacket(input) { ...@@ -51,7 +52,7 @@ class ServerTouchResponsePacket(input: ByteReadPacket) : ServerPacket(input) {
@PacketId(0x08_25u) @PacketId(0x08_25u)
class Encrypted(input: ByteReadPacket) : ServerPacket(input) { class Encrypted(input: ByteReadPacket) : ServerPacket(input) {
fun decrypt(): ServerTouchResponsePacket = ServerTouchResponsePacket(decryptBy(TIMProtocol.touchKey.hexToBytes())).applySequence(sequenceId) fun decrypt(): TouchResponsePacket = TouchResponsePacket(decryptBy(TIMProtocol.touchKey.hexToBytes())).applySequence(sequenceId)
} }
} }
......
...@@ -2,37 +2,39 @@ package net.mamoe.mirai.utils ...@@ -2,37 +2,39 @@ package net.mamoe.mirai.utils
import com.soywiz.klock.TimeSpan import com.soywiz.klock.TimeSpan
import com.soywiz.klock.seconds import com.soywiz.klock.seconds
import net.mamoe.mirai.network.protocol.tim.packet.login.ServerTouchResponsePacket import net.mamoe.mirai.network.protocol.tim.packet.login.TouchResponsePacket
import kotlin.jvm.JvmField import kotlin.jvm.JvmField
import kotlin.jvm.JvmOverloads
/** /**
* 网络配置 * 网络配置
*/ */
class BotNetworkConfiguration { class BotNetworkConfiguration @JvmOverloads constructor(
/** /**
* 等待 [ServerTouchResponsePacket] 的时间 * 等待 [TouchResponsePacket] 的时间
*/ */
var touchTimeout: TimeSpan = 2.seconds var touchTimeout: TimeSpan = 2.seconds,
/** /**
* 是否使用随机的设备名. * 是否使用随机的设备名.
* 使用随机可以降低被封禁的风险, 但可能导致每次登录都需要输入验证码 * 使用随机可以降低被封禁的风险, 但可能导致每次登录都需要输入验证码
* 当一台设备只登录少量账号时, 将此项设置为 `true` 可能更好. * 当一台设备只登录少量账号时, 将此项设置为 `true` 可能更好.
*/ */
var randomDeviceName: Boolean = false var randomDeviceName: Boolean = false,
/** /**
* 心跳周期. 过长会导致被服务器断开连接. * 心跳周期. 过长会导致被服务器断开连接.
*/ */
var heartbeatPeriod: TimeSpan = 60.seconds var heartbeatPeriod: TimeSpan = 60.seconds,
/** /**
* 每次心跳时等待结果的时间. * 每次心跳时等待结果的时间.
* 一旦心跳超时, 整个网络服务将会重启 (将消耗约 1s). 除正在进行的任务 (如图片上传) 会被中断外, 事件和插件均不受影响. * 一旦心跳超时, 整个网络服务将会重启 (将消耗约 1s). 除正在进行的任务 (如图片上传) 会被中断外, 事件和插件均不受影响.
*/ */
var heartbeatTimeout: TimeSpan = 2.seconds var heartbeatTimeout: TimeSpan = 2.seconds
) {
companion object { companion object {
/**
* 默认的配置实例
*/
@JvmField @JvmField
val Default = BotNetworkConfiguration() val Default = BotNetworkConfiguration()
} }
......
...@@ -10,6 +10,7 @@ import io.ktor.http.HttpStatusCode ...@@ -10,6 +10,7 @@ import io.ktor.http.HttpStatusCode
import io.ktor.http.URLProtocol import io.ktor.http.URLProtocol
import io.ktor.http.userAgent import io.ktor.http.userAgent
import kotlinx.io.core.Input import kotlinx.io.core.Input
import net.mamoe.mirai.contact.GroupInternalId
/** /**
* 时间戳 * 时间戳
...@@ -72,7 +73,7 @@ suspend fun httpPostFriendImage( ...@@ -72,7 +73,7 @@ suspend fun httpPostFriendImage(
@Suppress("DuplicatedCode") @Suppress("DuplicatedCode")
suspend fun httpPostGroupImage( suspend fun httpPostGroupImage(
botAccount: UInt, botAccount: UInt,
groupNumber: UInt, groupInternalId: GroupInternalId,
uKeyHex: String, uKeyHex: String,
imageInput: Input, imageInput: Input,
inputSize: Long inputSize: Long
...@@ -80,7 +81,7 @@ suspend fun httpPostGroupImage( ...@@ -80,7 +81,7 @@ suspend fun httpPostGroupImage(
url { url {
parameters["htcmd"] = "0x6ff0071" parameters["htcmd"] = "0x6ff0071"
parameters["uin"] = botAccount.toLong().toString() parameters["uin"] = botAccount.toLong().toString()
parameters["groupcode"] = groupNumber.toLong().toString() parameters["groupcode"] = groupInternalId.value.toLong().toString()
} }
} as HttpStatusCode).value.also { println(it) } == 200 } as HttpStatusCode).value.also { println(it) } == 200
......
@file:JvmName("IterableUtil") @file:JvmName("IterableUtil")
package net.mamoe.mirai.utils package net.mamoe.mirai.utils.internal
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
......
...@@ -33,18 +33,19 @@ fun ByteReadPacket.parseServerPacket(size: Int): ServerPacket { ...@@ -33,18 +33,19 @@ fun ByteReadPacket.parseServerPacket(size: Int): ServerPacket {
discardExact(7)//4 for qq number, 3 for 0x00 0x00 0x00. 但更可能是应该 discard 8 discardExact(7)//4 for qq number, 3 for 0x00 0x00 0x00. 但更可能是应该 discard 8
return when (id.toUInt()) { return when (id.toUInt()) {
0x08_25u -> ServerTouchResponsePacket.Encrypted(this) 0x08_25u -> TouchResponsePacket.Encrypted(this)
0x08_36u -> { 0x08_36u -> {
//todo 不要用size分析 //todo 不要用size分析
when (size) { when (size) {
271, 207 -> return ServerLoginResponseKeyExchangePacket.Encrypted(this).applySequence(sequenceId) 271, 207 -> return LoginResponseKeyExchangeResponsePacket.Encrypted(this).applySequence(sequenceId)
871 -> return ServerLoginResponseCaptchaInitPacket.Encrypted(this).applySequence(sequenceId) 871 -> return LoginResponseCaptchaInitPacket.Encrypted(this).applySequence(sequenceId)
} }
if (size > 700) return ServerLoginResponseSuccessPacket.Encrypted(this).applySequence(sequenceId) if (size > 700) return LoginResponseSuccessPacket.Encrypted(this).applySequence(sequenceId)
println("登录包size=$size") println("登录包size=$size")
return ServerLoginResponseFailedPacket(when (size) { return LoginResponseFailedPacket(
when (size) {
135 -> {//包数据错误. 目前怀疑是 tlv0006 135 -> {//包数据错误. 目前怀疑是 tlv0006
this.readRemainingBytes().cutTail(1).decryptBy(TIMProtocol.shareKey).read { this.readRemainingBytes().cutTail(1).decryptBy(TIMProtocol.shareKey).read {
discardExact(51) discardExact(51)
...@@ -70,7 +71,7 @@ fun ByteReadPacket.parseServerPacket(size: Int): ServerPacket { ...@@ -70,7 +71,7 @@ fun ByteReadPacket.parseServerPacket(size: Int): ServerPacket {
else -> throw IllegalArgumentException(bytes.size.toString())*/ else -> throw IllegalArgumentException(bytes.size.toString())*/
}, this).applySequence(sequenceId) }, this).applySequence(sequenceId)
} }
0x08_28u -> ServerSessionKeyResponsePacket.Encrypted(this) 0x08_28u -> SessionKeyResponsePacket.Encrypted(this)
0x00_ECu -> ServerLoginSuccessPacket(this) 0x00_ECu -> ServerLoginSuccessPacket(this)
0x00_BAu -> ServerCaptchaPacket.Encrypted(this) 0x00_BAu -> ServerCaptchaPacket.Encrypted(this)
......
@file:Suppress("EXPERIMENTAL_API_USAGE") @file:Suppress("EXPERIMENTAL_API_USAGE")
package net.mamoe.mirai.utils package net.mamoe.mirai.utils.io
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.contact.GroupId
import net.mamoe.mirai.contact.GroupInternalId
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.utils.*
import kotlin.random.Random import kotlin.random.Random
import kotlin.random.nextInt import kotlin.random.nextInt
...@@ -14,9 +17,8 @@ fun BytePacketBuilder.writeRandom(length: Int) = repeat(length) { this.writeByte ...@@ -14,9 +17,8 @@ fun BytePacketBuilder.writeRandom(length: Int) = repeat(length) { this.writeByte
fun BytePacketBuilder.writeQQ(qq: Long) = this.writeUInt(qq.toUInt()) fun BytePacketBuilder.writeQQ(qq: Long) = this.writeUInt(qq.toUInt())
fun BytePacketBuilder.writeQQ(qq: UInt) = this.writeUInt(qq) fun BytePacketBuilder.writeQQ(qq: UInt) = this.writeUInt(qq)
fun BytePacketBuilder.writeGroup(groupId: GroupId) = this.writeUInt(groupId.value)
fun BytePacketBuilder.writeGroup(groupIdOrGroupNumber: Long) = this.writeUInt(groupIdOrGroupNumber.toUInt()) fun BytePacketBuilder.writeGroup(groupInternalId: GroupInternalId) = this.writeUInt(groupInternalId.value)
fun BytePacketBuilder.writeGroup(groupIdOrGroupNumber: UInt) = this.writeUInt(groupIdOrGroupNumber)
fun BytePacketBuilder.writeShortLVByteArray(byteArray: ByteArray) { fun BytePacketBuilder.writeShortLVByteArray(byteArray: ByteArray) {
this.writeShort(byteArray.size.toShort()) this.writeShort(byteArray.size.toShort())
...@@ -98,7 +100,9 @@ fun BytePacketBuilder.writeTByteArray(tag: UByte, value: UByteArray) { ...@@ -98,7 +100,9 @@ fun BytePacketBuilder.writeTByteArray(tag: UByte, value: UByteArray) {
} }
fun BytePacketBuilder.encryptAndWrite(key: IoBuffer, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(key.readBytes(), encoder) fun BytePacketBuilder.encryptAndWrite(key: IoBuffer, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(key.readBytes(), encoder)
fun BytePacketBuilder.encryptAndWrite(key: ByteArray, encoder: BytePacketBuilder.() -> Unit) = writeFully(TEA.encrypt(BytePacketBuilder().apply(encoder).use { it.build().readBytes() }, key)) fun BytePacketBuilder.encryptAndWrite(key: ByteArray, encoder: BytePacketBuilder.() -> Unit) = writeFully(TEA.encrypt(BytePacketBuilder().apply(encoder).use {
it.build().readBytes()
}, key))
fun BytePacketBuilder.encryptAndWrite(keyHex: String, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(keyHex.hexToBytes(), encoder) fun BytePacketBuilder.encryptAndWrite(keyHex: String, encoder: BytePacketBuilder.() -> Unit) = encryptAndWrite(keyHex.hexToBytes(), encoder)
fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, loginIP: String, privateKey: ByteArray) { fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, loginIP: String, privateKey: ByteArray) {
......
...@@ -75,7 +75,7 @@ internal actual fun HttpRequestBuilder.configureBody( ...@@ -75,7 +75,7 @@ internal actual fun HttpRequestBuilder.configureBody(
override val contentType: ContentType = ContentType.Image.GIF override val contentType: ContentType = ContentType.Image.GIF
override val contentLength: Long = inputSize override val contentLength: Long = inputSize
override suspend fun writeTo(channel: ByteWriteChannel) { override suspend fun writeTo(channel: ByteWriteChannel) {//不知道为什么这个 channel 在 common 找不到...
val buffer = byteArrayOf(1) val buffer = byteArrayOf(1)
while (!input.endOfInput) { while (!input.endOfInput) {
input.readFully(buffer) input.readFully(buffer)
......
@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS") @file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS")
import net.mamoe.mirai.contact.groupId
import net.mamoe.mirai.contact.toInternalId
import net.mamoe.mirai.network.protocol.tim.packet.GroupImageIdRequestPacket import net.mamoe.mirai.network.protocol.tim.packet.GroupImageIdRequestPacket
import net.mamoe.mirai.utils.hexToBytes import net.mamoe.mirai.utils.hexToBytes
import net.mamoe.mirai.utils.io.readRemainingBytes import net.mamoe.mirai.utils.io.readRemainingBytes
...@@ -16,7 +18,7 @@ fun main() = println({ ...@@ -16,7 +18,7 @@ fun main() = println({
// File("C:\\Users\\Him18\\Desktop\\test2.jpg").writeBytes(image.fileData.readBytes()) // File("C:\\Users\\Him18\\Desktop\\test2.jpg").writeBytes(image.fileData.readBytes())
GroupImageIdRequestPacket( GroupImageIdRequestPacket(
1994701021u, 1994701021u,
580266363u, 580266363u.groupId().toInternalId(),
image, image,
sessionKey sessionKey
).packet.readRemainingBytes().toUHexString() ).packet.readRemainingBytes().toUHexString()
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
package demo1 package demo1
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
...@@ -40,7 +39,7 @@ private fun readTestAccount(): BotAccount? { ...@@ -40,7 +39,7 @@ private fun readTestAccount(): BotAccount? {
} }
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
suspend fun main() = coroutineScope { suspend fun main() {
val bot = Bot( val bot = Bot(
readTestAccount() ?: BotAccount(//填写你的账号 readTestAccount() ?: BotAccount(//填写你的账号
id = 1994701121u, id = 1994701121u,
...@@ -58,7 +57,7 @@ suspend fun main() = coroutineScope { ...@@ -58,7 +57,7 @@ suspend fun main() = coroutineScope {
} }
subscribeAlways<GroupMessageEvent> { subscribeAlways<GroupMessageEvent> {
if (it.message eq "复读" && it.group.internalId == 580266363u) { if (it.message eq "复读" && it.group.internalId.value == 580266363u) {
it.reply(it.message) it.reply(it.message)
} }
} }
......
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