1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-04-25 04:50:26 +08:00

Daily QQA update

This commit is contained in:
Him188 2020-01-14 22:01:30 +08:00
parent 9b564a2ade
commit 5a0cab2f10
5 changed files with 50 additions and 16 deletions
README.md
mirai-api-http/src/main/kotlin/net.mamoe.mirai.api.http
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network

View File

@ -115,5 +115,5 @@ bot.subscribeAlways<MemberPermissionChangedEvent> {
- (见 LICENSE 第 4 节) 您可以免费或收费地传递这个项目的源代码或目标代码(即编译结果), **但前提是提供明显的版权声明** (您需要标注本 `GitHub` 项目地址)
## Acknowledgement
特别感谢 [JetBrains](https://www.jetbrains.com/) 提供的免费 [IntelliJ IDEA](https://www.jetbrains.com/idea/) 等 IDE 授权
[<img src=".github/jetbrains-variant-3.png" width="200"/>](https://www.jetbrains.com/)
特别感谢 [JetBrains](https://www.jetbrains.com/?from=mirai) 提供的免费 [IntelliJ IDEA](https://www.jetbrains.com/idea/?from=mirai) 等 IDE 授权
[<img src=".github/jetbrains-variant-3.png" width="200"/>](https://www.jetbrains.com/?from=mirai)

View File

@ -50,8 +50,8 @@ fun Application.mirai() {
mirai("/addFriend") {
Bot.instanceWhose(qq = param("bot")).addFriend(
id = param("qq"),
message = paramOrNull<String?>("message")?.let { it },
remark = paramOrNull<String?>("remark")?.let { it }
message = paramOrNull("message"),
remark = paramOrNull("remark")
)
call.ok()

View File

@ -16,6 +16,9 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.cryptor.ECDH
import net.mamoe.mirai.utils.cryptor.contentToString
import net.mamoe.mirai.utils.io.hexToBytes
import net.mamoe.mirai.utils.io.read
import net.mamoe.mirai.utils.io.readUShortLVByteArray
import net.mamoe.mirai.utils.io.readUShortLVString
import net.mamoe.mirai.utils.unsafeWeakRef
/*
@ -123,6 +126,8 @@ internal open class QQAndroidClient(
lateinit var qrPushSig: ByteArray
lateinit var mainDisplayName: ByteArray
var transportSequenceId = 1
}
class ReserveUinInfo(
@ -191,6 +196,9 @@ class WLoginSigInfo(
val a2CreationTime: Long,
val tgtKey: ByteArray,
val userStSig: UserStSig,
/**
* TransEmpPacket 加密使用
*/
val userStKey: ByteArray,
val userStWebSig: UserStWebSig,
val userA5: UserA5,
@ -206,7 +214,8 @@ class WLoginSigInfo(
val d2Key: ByteArray,
val sid: Sid,
val aqSig: AqSig,
val psKey: PSKey,
val psKeyMap: PSKeyMap,
val pt4TokenMap: Pt4TokenMap,
val superKey: ByteArray,
val payToken: ByteArray,
val pf: ByteArray,
@ -218,7 +227,7 @@ class WLoginSigInfo(
val deviceToken: ByteArray
) {
override fun toString(): String {
return "WLoginSigInfo(uin=$uin, encryptA1=${encryptA1.contentToString()}, noPicSig=${noPicSig.contentToString()}, G=${G.contentToString()}, dpwd=${dpwd.contentToString()}, randSeed=${randSeed.contentToString()}, simpleInfo=$simpleInfo, appPri=$appPri, a2ExpiryTime=$a2ExpiryTime, loginBitmap=$loginBitmap, tgt=${tgt.contentToString()}, a2CreationTime=$a2CreationTime, tgtKey=${tgtKey.contentToString()}, userStSig=$userStSig, userStKey=${userStKey.contentToString()}, userStWebSig=$userStWebSig, userA5=$userA5, userA8=$userA8, lsKey=$lsKey, sKey=$sKey, userSig64=$userSig64, openId=${openId.contentToString()}, openKey=$openKey, vKey=$vKey, accessToken=$accessToken, d2=$d2, d2Key=${d2Key.contentToString()}, sid=$sid, aqSig=$aqSig, psKey=$psKey, superKey=${superKey.contentToString()}, payToken=${payToken.contentToString()}, pf=${pf.contentToString()}, pfKey=${pfKey.contentToString()}, da2=${da2.contentToString()}, wtSessionTicket=$wtSessionTicket, wtSessionTicketKey=${wtSessionTicketKey.contentToString()}, deviceToken=${deviceToken.contentToString()})"
return "WLoginSigInfo(uin=$uin, encryptA1=${encryptA1.contentToString()}, noPicSig=${noPicSig.contentToString()}, G=${G.contentToString()}, dpwd=${dpwd.contentToString()}, randSeed=${randSeed.contentToString()}, simpleInfo=$simpleInfo, appPri=$appPri, a2ExpiryTime=$a2ExpiryTime, loginBitmap=$loginBitmap, tgt=${tgt.contentToString()}, a2CreationTime=$a2CreationTime, tgtKey=${tgtKey.contentToString()}, userStSig=$userStSig, userStKey=${userStKey.contentToString()}, userStWebSig=$userStWebSig, userA5=$userA5, userA8=$userA8, lsKey=$lsKey, sKey=$sKey, userSig64=$userSig64, openId=${openId.contentToString()}, openKey=$openKey, vKey=$vKey, accessToken=$accessToken, d2=$d2, d2Key=${d2Key.contentToString()}, sid=$sid, aqSig=$aqSig, psKey=${psKeyMap.contentToString()}, superKey=${superKey.contentToString()}, payToken=${payToken.contentToString()}, pf=${pf.contentToString()}, pfKey=${pfKey.contentToString()}, da2=${da2.contentToString()}, wtSessionTicket=$wtSessionTicket, wtSessionTicketKey=${wtSessionTicketKey.contentToString()}, deviceToken=${deviceToken.contentToString()})"
}
}
@ -235,7 +244,27 @@ class AccessToken(data: ByteArray, creationTime: Long) : KeyWithCreationTime(dat
class D2(data: ByteArray, creationTime: Long, expireTime: Long) : KeyWithExpiry(data, creationTime, expireTime)
class Sid(data: ByteArray, creationTime: Long, expireTime: Long) : KeyWithExpiry(data, creationTime, expireTime)
class AqSig(data: ByteArray, creationTime: Long) : KeyWithCreationTime(data, creationTime)
class PSKey(data: ByteArray, creationTime: Long) : KeyWithCreationTime(data, creationTime)
class Pt4Token(data: ByteArray, creationTime: Long, expireTime: Long) : KeyWithExpiry(data, creationTime, expireTime)
typealias PSKeyMap = MutableMap<String, PSKey>
typealias Pt4TokenMap = MutableMap<String, Pt4Token>
internal fun parsePSKeyMapAndPt4TokenMap(data: ByteArray, creationTime: Long, expireTime: Long, outPSKeyMap: PSKeyMap, outPt4TokenMap: Pt4TokenMap) = data.read {
repeat(readShort().toInt()) {
val domain = readUShortLVString()
val psKey = readUShortLVByteArray()
val pt4token = readUShortLVByteArray()
when{
psKey.size > 0 -> outPSKeyMap[domain] = PSKey(psKey, creationTime, expireTime)
pt4token.size > 0 -> outPt4TokenMap[domain] = Pt4Token(pt4token, creationTime, expireTime)
}
}
}
class PSKey(data: ByteArray, creationTime: Long, expireTime: Long) : KeyWithExpiry(data, creationTime, expireTime)
class WtSessionTicket(data: ByteArray, creationTime: Long) : KeyWithCreationTime(data, creationTime)
open class KeyWithExpiry(

View File

@ -312,9 +312,17 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse, Log
}
}
// TODO sigMap??? =0x21410e0 // from qq
val creationTime = currentTimeSeconds
val expireTime = creationTime + 2160000L
@Suppress("UNREACHABLE_CODE") // FOR STUB
val outPSKeyMap: PSKeyMap = mutableMapOf()
val outPt4TokenMap: Pt4TokenMap = mutableMapOf()
parsePSKeyMapAndPt4TokenMap(tlvMap119[0x512]?: error("Cannot find tlv 0x512, which is pskeyMap and pt4tokenMap"), creationTime, expireTime, outPSKeyMap, outPt4TokenMap)
client.wLoginSigInfo = WLoginSigInfo(
uin = client.uin,
encryptA1 = inline {
@ -354,7 +362,8 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse, Log
d2Key = tlvMap119.getOrEmpty(0x305),
sid = Sid(tlvMap119.getOrEmpty(0x164), creationTime, expireTime),
aqSig = AqSig(tlvMap119.getOrEmpty(0x171), creationTime),
psKey = PSKey(tlvMap119.getOrEmpty(0x512), creationTime),
psKeyMap = outPSKeyMap,
pt4TokenMap = outPt4TokenMap,
superKey = tlvMap119.getOrEmpty(0x16d),
payToken = payToken,
pf = pf,

View File

@ -1,14 +1,11 @@
package net.mamoe.mirai.qqandroid.network.protocol.packet.login
import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
import net.mamoe.mirai.qqandroid.network.protocol.packet.*
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildLoginOutgoingPacket
import net.mamoe.mirai.qqandroid.network.protocol.packet.writeOicqRequestPacket
import net.mamoe.mirai.utils.io.toReadPacket
internal object TransEmpPacket : PacketFactory<TransEmpPacket.Response, LoginPacketDecrypter>(LoginPacketDecrypter) {
@ -20,11 +17,11 @@ internal object TransEmpPacket : PacketFactory<TransEmpPacket.Response, LoginPac
private const val appId = 16L
private const val subAppId = 537062845L
@Suppress("FunctionName")
fun SubCommand1(
client: QQAndroidClient
): OutgoingPacket = buildLoginOutgoingPacket(client, subAppId, ssoExtraData = byteArrayOf().toReadPacket()) {
writeOicqRequestPacket(client, EncryptMethodECDH135(client.ecdh), id){
writeOicqRequestPacket(client, EncryptMethodECDH135(client.ecdh), id) {
// oicq.wlogin_sdk.request.trans_emp_1#packTransEmpBody
}
@ -36,5 +33,4 @@ internal object TransEmpPacket : PacketFactory<TransEmpPacket.Response, LoginPac
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
TODO("not implemented")
}
}