mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-23 22:30:47 +08:00
Fix StackOverflowError
This commit is contained in:
parent
f402451812
commit
39204730eb
@ -2,14 +2,12 @@ package net.mamoe.mirai.network
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.io.core.use
|
||||
import kotlinx.io.streams.inputStream
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.message.Image
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.DataPacketSocketAdapter
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.SessionKey
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import java.io.InputStream
|
||||
@ -21,8 +19,9 @@ import java.io.InputStream
|
||||
*/
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
actual class BotSession internal actual constructor(
|
||||
bot: Bot
|
||||
) : BotSessionBase(bot) {
|
||||
bot: Bot,
|
||||
sessionKey: SessionKey
|
||||
) : BotSessionBase(bot, sessionKey) {
|
||||
|
||||
suspend inline fun Image.downloadAsStream(): InputStream = download().inputStream()
|
||||
suspend inline fun Image.downloadAsBitmap(): Bitmap = withContext(Dispatchers.IO) { downloadAsStream().use { BitmapFactory.decodeStream(it) } }
|
||||
|
@ -41,10 +41,11 @@ fun GroupId.toInternalId(): GroupInternalId {//求你别出错
|
||||
)
|
||||
}
|
||||
|
||||
fun GroupInternalId.toId(): GroupId {//求你别出错
|
||||
fun GroupInternalId.toId(): GroupId = with(value) {
|
||||
//求你别出错
|
||||
var left: UInt = this.toString().let {
|
||||
if (it.length < 6) {
|
||||
return GroupId(this.value)
|
||||
return GroupId(value)
|
||||
}
|
||||
it.substring(0 until it.length - 6).toUInt()
|
||||
}
|
||||
@ -96,6 +97,6 @@ fun GroupInternalId.toId(): GroupId {//求你别出错
|
||||
left = left.toString().substring(0 until 3).toUInt()
|
||||
((left - 349u).toString() + right.toString()).toUInt()
|
||||
}
|
||||
else -> this.value
|
||||
else -> value
|
||||
})
|
||||
}
|
@ -6,8 +6,10 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.data.Profile
|
||||
import net.mamoe.mirai.network.BotSession
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.AvatarLink
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.FriendNameRemark
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.action.PreviousNameList
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
|
||||
/**
|
||||
* QQ 对象.
|
||||
@ -22,6 +24,12 @@ import net.mamoe.mirai.network.protocol.tim.packet.action.PreviousNameList
|
||||
* @author Him188moe
|
||||
*/
|
||||
interface QQ : Contact, CoroutineScope {
|
||||
/**
|
||||
* 请求头像下载链接
|
||||
*/
|
||||
// @MiraiExperimentalAPI
|
||||
//suspend fun queryAvatar(): AvatarLink
|
||||
|
||||
/**
|
||||
* 查询用户资料
|
||||
*/
|
||||
|
@ -31,7 +31,7 @@ import kotlin.coroutines.coroutineContext
|
||||
* 构造 [BotSession] 的捷径
|
||||
*/
|
||||
@Suppress("FunctionName", "NOTHING_TO_INLINE")
|
||||
internal inline fun TIMBotNetworkHandler.BotSession(): BotSession = BotSession(bot)
|
||||
internal inline fun TIMBotNetworkHandler.BotSession(sessionKey: SessionKey): BotSession = BotSession(bot, sessionKey)
|
||||
|
||||
/**
|
||||
* 登录会话. 当登录完成后, 客户端会拿到 sessionKey.
|
||||
@ -43,7 +43,8 @@ internal inline fun TIMBotNetworkHandler.BotSession(): BotSession = BotSession(b
|
||||
*/
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
expect class BotSession internal constructor(
|
||||
bot: Bot
|
||||
bot: Bot,
|
||||
sessionKey: SessionKey
|
||||
) : BotSessionBase
|
||||
|
||||
/**
|
||||
@ -52,9 +53,9 @@ expect class BotSession internal constructor(
|
||||
@MiraiInternalAPI
|
||||
// cannot be internal because of `public BotSession`
|
||||
abstract class BotSessionBase internal constructor(
|
||||
val bot: Bot
|
||||
val bot: Bot,
|
||||
internal val sessionKey: SessionKey
|
||||
) {
|
||||
internal val sessionKey: SessionKey get() = bot.sessionKey
|
||||
val socket: DataPacketSocketAdapter get() = bot.network.socket
|
||||
val NetworkScope: CoroutineScope get() = bot.network
|
||||
|
||||
|
@ -474,7 +474,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
BotLoginSucceedEvent(bot).broadcast()
|
||||
|
||||
|
||||
session = BotSession()
|
||||
session = BotSession(sessionKey)
|
||||
|
||||
val configuration = currentBotConfiguration()
|
||||
heartbeatJob = this@TIMBotNetworkHandler.launch {
|
||||
|
@ -79,6 +79,7 @@ internal enum class KnownPacketId(override inline val value: UShort, override in
|
||||
|
||||
inline REQUEST_PROFILE_AVATAR(0x0031u, RequestProfileAvatarPacket),
|
||||
inline REQUEST_PROFILE_DETAILS(0x003Cu, RequestProfileDetailsPacket),
|
||||
inline QUERY_NICKNAME(0x0126u, QueryNicknamePacket),
|
||||
|
||||
inline QUERY_PREVIOUS_NAME(0x01BCu, QueryPreviousNamePacket),
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
package net.mamoe.mirai.network.protocol.tim.packet.action
|
||||
|
||||
|
||||
// 0001
|
||||
// 已确认 查好友列表的列表
|
||||
|
||||
// send
|
||||
// 20 01 00 00 00 00 01 00 00
|
||||
|
||||
// receive
|
||||
// 20 00 01 03 00 00 00 15 01 01 03
|
||||
// 00 0C 01 02 [09] E4 BF A1 E7 94 A8 E5 8D A1
|
||||
// 00 0F 02 03 [0C] E8 BD AF E4 BB B6 E6 B3 A8 E5 86 8C
|
||||
// 00 09 03 04 [06] E6 BA 90 E7 A0 81
|
||||
// 00 00
|
||||
|
||||
|
||||
|
||||
|
||||
// 0134
|
||||
// 这里有好友也有群(为 internal id) 97208217
|
||||
// 不太确定. 可能是查好友与群列表??
|
||||
// send
|
||||
// 00 00 01 5B 5D EB 58 AD 00 00 03 E8 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
||||
// receive
|
||||
// 00 00 19 00 00 01 5D 5D EB 5D C6 00 00 00 00 01 00 00 00 19 00 54 E5 06 01 00 00 00 00 00 01 00 00 00 64 B2 1D 01 00 00 00 00 00 01 00 00 00 66 7C C5 01 00 00 00 00 00 01 00 00 01 60 31 EC 01 00 00 00 00 00 01 00 00 01 B3 E6 AC 01 00 00 00 00 00 01 00 00 02 45 16 DF 01 00 00 00 00 00 01 00 00 03 37 67 20 01 00 00 00 00 00 01 00 00 05 B0 F4 6F 01 00 00 00 00 00 01 00 00 0C D9 1F 45 01 00 00 00 00 00 01 00 00 0F 0D 35 E1 01 00 00 00 00 00 01 00 00 10 18 86 83 01 00 00 00 00 00 01 00 00 11 A9 8B F7 01 00 00 00 00 00 01 00 00 31 05 12 1C 01 00 00 00 00 00 01 00 00 37 99 77 D7 01 00 00 00 00 00 01 00 00 37 C8 4D C7 04 00 00 00 00 00 00 37 E9 68 46 01 00 00 00 00 00 01 00 00 37 E9 94 CF 01 00 00 00 00 00 01 00 00 3E 03 3F A2 01 00 00 00 00 00 01 00 00 50 BA 4A 8F 01 00 00 00 00 00 01 00 00 55 7A D6 86 01 00 00 00 00 00 01 00 00 6C 78 B1 E0 01 00 00 00 00 00 01 00 00 78 59 79 87 01 00 00 00 00 00 01 00 00 79 9B 1B 59 04 00 00 00 00 00 00 A6 81 A4 9D 01 00 00 00 00 00 01 00 00 A6 A0 EE EF 01 00 00 00 00 00 01 00 00 00 00
|
||||
|
||||
|
@ -10,12 +10,133 @@ import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.*
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
|
||||
inline class AvatarLink(val value: String) : Packet
|
||||
|
||||
inline class NicknameMap(val delegate: Map<UInt, String>) : Packet
|
||||
|
||||
/**
|
||||
* 批量查询昵称.
|
||||
*/
|
||||
@AnnotatedId(KnownPacketId.QUERY_NICKNAME)
|
||||
internal object QueryNicknamePacket : SessionPacketFactory<NicknameMap>() {
|
||||
/**
|
||||
* 单个查询.
|
||||
*/
|
||||
@PacketVersion(date = "2019.12.7", timVersion = "2.3.2 (21173)")
|
||||
operator fun invoke(
|
||||
bot: UInt,
|
||||
sessionKey: SessionKey,
|
||||
qq: UInt
|
||||
): OutgoingPacket = buildSessionPacket(bot, sessionKey) {
|
||||
writeHex("03 00 00 00 00 00 00 00 00 00 00")
|
||||
writeByte(1)
|
||||
writeUInt(qq)
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量查询.
|
||||
* 注意!! 服务器不一定全都返回... 需要重复查没返回的
|
||||
*/
|
||||
@PacketVersion(date = "2019.12.7", timVersion = "2.3.2 (21173)")
|
||||
operator fun invoke(
|
||||
bot: UInt,
|
||||
sessionKey: SessionKey,
|
||||
qq: Array<UInt>
|
||||
): OutgoingPacket = buildSessionPacket(bot, sessionKey) {
|
||||
writeHex("03 00 00 00 00 00 00 00 00 00 00")
|
||||
writeUByte(qq.size.toUByte())
|
||||
qq.forEach {
|
||||
writeUInt(it)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
批量查询昵称
|
||||
|
||||
发出包ID = UnknownPacketId(01 26)
|
||||
sequence = 44 57
|
||||
fixVer2=02 00 00 00 01 2E 01 00 00 69 35
|
||||
解密body=03 00 00 00 00 00 00 00 00 00 00 [24]
|
||||
(02 45 16 DF) (6C 78 B1 E0) (11 73 69 76) (36 79 19 E1) (49 28 A4 F4) (81 66 8B BC) (2D 6B 19 EC) (28 3D 91 25) (00 54 E5 06) (37 E9 94 CF) (55 7A D6 86)
|
||||
(01 60 31 EC) (2F B1 5E EF) (05 B0 F4 6F) (0F 0D 35 E1) (00 66 7C C5) A6 81 A4 9D 31 05 12 1C A6 A0 EE EF 10 18 86 83 37 99 77 D7 50 BA 4A 8F 10 CE 72 4C 32 71 EE 30 79 63 C6 98 (3E C2 FA 6E) 02 27 13 93 01 2E E5 D7 37 E9 68 46 00 64 B2 1D 03 37 67 20 0A 9C 58 FB 05 94 75 87
|
||||
(0B 9F C6 B6)
|
||||
(18 BE 4B 0E)
|
||||
|
||||
接收包id=UnknownPacketId(01 26),
|
||||
sequence=44 57
|
||||
解析body=UnknownPacket(01 26)
|
||||
body= 03 00 00 00 00 00 00 00 00 00 00 12 04 14 37
|
||||
(02 45 16 DF) 00 36 FF 00
|
||||
[0F] E6 94 BE E7 9D 9B E3 81 AE E5 A4 A9 E7 A9 BA
|
||||
11 88 02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 80 08 80 00 41
|
||||
(6C 78 B1 E0) 00 2D 1C 01
|
||||
[19] 61 2E E8 B4 A2 E7 A5 9E 7C 20 E6 8E A5 E5 90 84 E7 A7 8D E4 B8 9A E5 8A A1
|
||||
11 C0 02 40 07 C7 08 1C 00 4D 59 53 00 00 4B 4C 00 4B 55 4C 00 00 00 00 00 00 04 00 00 E2 10 34
|
||||
(11 73 69 76) 01 DD 19 00
|
||||
[0C] E5 BC 80 E5 BF 83 E5 B0 B1 E5 A5 BD
|
||||
11 08 82 46 07 CA 00 00 00 00 00 31 00 00 33 32 00 00 00 35 08 04 08 04 08 04 04 01 17 E3 10 32
|
||||
(36 79 19 E1) 00 00 1F 00
|
||||
[0A] 45 70 69 6D 65 74 68 65 75 73
|
||||
00 08 02 00 07 C4 02 08 00 41 42 57 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 10 49
|
||||
(49 28 A4 F4) 02 B5 17 01
|
||||
[21] E9 A1 B9 E7 9B AE 6B 61 6B 61 6F 74 61 6C 6B EF BC 88 E6 9C 89 E4 BA 8B E6 8A 96 E6 88 91 EF BC 89
|
||||
11 80 02 00 07 CC 06 0B 00 00 00 31 00 00 34 34 00 00 00 31 00 00 00 00 00 00 04 00 00 80 10 2E
|
||||
(81 66 8B BC) 02 64 77 00
|
||||
[06] E4 B8 87 E7 A0 81
|
||||
00 80 02 00 07 6C 0A 03 00 00 00 31 00 00 33 31 00 00 00 35 00 00 00 00 00 00 04 00 00 00 00 37
|
||||
(2D 6B 19 EC) 02 58 16 01
|
||||
[0F] E5 93 A5 E5 8F AA E6 98 AF E4 BC A0 E9 80 81
|
||||
11 00 02 00 07 CC 0C 0F 00 00 00 31 00 00 35 33 00 00 00 33 00 00 00 00 00 00 04 00 00 00 00 31
|
||||
28 3D 91 25 02 D9 FF FF 09 E5 B0 8F E8 A1 A8 E5 BC 9F 11 C8 02 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 04 08 04 08 04 04 20 06 E2 00 3B 00 54 E5 06 02 5B 78 00 13 61 E5 85 A8 E6 96 B0 E5 9F 9F E5 90 8D E6 89 B9 E5 8F 91 00 08 82 46 07 6B 08 16 00 00 00 31 00 00 34 33 00 00 00 31 00 00 00 00 00 00 04 00 08 02 00 4C 37 E9 94 CF 00 00 00 FF 24 E6 B3 89 E5 B7 9E E5 B8 82 E6 86 A8 E9 BC A0 E7 BD 91 E7 BB 9C E7 A7 91 E6 8A 80 E6 9C 89 E9 99 90 E5 85 AC 01 00 00 00 00 00 00 00 00 00 00 31 00 00 33 35 00 00 00 35 00 00 00 00 00 00 04 00 00 40 02 30 55 7A D6 86 02 49 1B 01 08 E5 AE A2 E6 9C 8D 56 36 11 00 02 00 07 C8 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 12 00 4A 01 60 31 EC 02 58 FF 00 22 E5 BC 80 E5 BD A9 E7 BD 91 2D E5 B0 8F E8 B1 86 28 31 32 E5 88 B0 32 32 E7 82 B9 E5 9C A8 E7 BA BF 29 00 40 00 00 00 00 05 1E 00 00 00 31 00 00 35 31 00 00 00 31 08 04 04 09 0C 04 04 00 00 02 00 38 2F B1 5E EF 00 00 00 FF 10 E4 B8 8A E6 96 B9 65 E6 8E A8 E8 BD AF E4 BB B6 01 80 00 00 00 00 00 00 00 00 00 31 00 00 34 34 00 00 00 33 00 00 00 00 00 00 04 00 00 00 00 39 05 B0 F4 6F 00 78 23 01 11 E2 99 A1 20 E2 9C BF E2 80 BF E2 9C BF 20 52 4F 4E 11 88 82 42 07 C0 09 0C 00 00 00 31 00 00 33 35 00 00 00 35 00 00 00 00 00 00 04 00 00 80 00 2E 0F 0D 35 E1 00 00 23 00 06 E5 9C B0 E8 A1 A3 00 40 02 46 07 C0 02 08 00 00 00 31 00 00 34 35 00 00 00 33 00 00 00 00 00 00 04 10 00 02 00 31 00 66 7C C5 00 00 0A 00 09 E8 B5 9A E5 B0 8F E5 AE A2 00 C8 02 42 07 D8 0C 0C 00 00 00 31 00 00 34 31 00 00 00 31 00 00 00 00 00 00 04 24 02 00 00 3A
|
||||
(A6 81 A4 9D) 02 25 29 00 12 E6 96 B0 E6 98 93 E9 80 9A E5 AE A2 E6 9C 8D E4 B8 89 11 80 02 01 07 BA 0A 10 00 00 00 31 00 00 33 35 00 00 00 35 00 00 00 00 00 00 04 00 00 00 00 3A 31 05 12 1C 01 86 1C 00 12 E5 BF A7 E4 BC A4 E8 BF 98 E6 98 AF E5 BF AB E4 B9 90 00 88 02 02 07 C7 04 13 00 00 00 31 00 00 33 35 00 00 00 35 00 00 00 00 00 00 04 00 08 20 00 00 04 5D EC AF 48
|
||||
|
||||
---------------------------
|
||||
|
||||
发出包ID = UnknownPacketId(01 26)
|
||||
sequence = 44 58
|
||||
fixVer2=02 00 00 00 01 2E 01 00 00 69 35
|
||||
解密body=03 00 00 00 00 00 00 00 00 00 00 12 A6 A0 EE EF 10 18 86 83 37 99 77 D7 50 BA 4A 8F 10 CE 72 4C 32 71 EE 30 79 63 C6 98
|
||||
(3E C2 FA 6E) 02 27 13 93 01 2E E5 D7 37 E9 68 46 (00 64 B2 1D) (03 37 67 20) 0A 9C 58 FB 05 94 75 87 (11 48 2B 1A) 0B 9F C6 B6 18 BE 4B 0E
|
||||
|
||||
接收包id=UnknownPacketId(01 26),
|
||||
sequence=44 58
|
||||
解析body=UnknownPacket(01 26)
|
||||
body=03 00 00 00 00 00 00 00 00 00 00 00 03 8E 3C A6 A0 EE EF 02 07 6C 01 14 E8 8B B9 E6 9E 9C 49 44 E4 B8 93 E4 B8 9A E8 A7 A3 E9 94 81 11 00 02 01 07 77 01 01 00 00 00 31 00 00 31 31 00 00 00 31 00 00 00 00 00 00 04 00 00 02 00 31 10 18 86 83 00 C3 22 00 09 35 35 38 E7 94 B5 E8 AE AF 00 08 02 40 07 C1 0C 01 00 00 00 31 00 00 33 35 00 00 00 35 08 04 08 04 08 04 04 00 04 00 10 35 37 99 77 D7 02 5B 2A 00 0D E8 BF 9C E6 8B 93 E7 94 B5 E8 AE AF 33 00 C0 00 02 07 B9 09 0E 00 00 00 31 00 00 33 35 00 00 00 35 00 00 00 00 00 00 04 00 00 40 00 2E 50 BA 4A 8F 02 1C 09 00 06 E6 96 B9 E5 80 8D 11 40 02 00 07 DA 01 01 00 00 00 31 00 00 34 34 00 00 00 33 00 00 00 00 00 00 04 00 00 82 00 2C 10 CE 72 4C 00 00 23 00 04 4C 6F 73 74 11 08 02 00 07 C0 02 12 00 00 00 31 00 00 31 31 00 00 00 38 08 04 00 00 00 00 04 00 08 72 00 30 32 71 EE 30 00 93 21 00 08 69 57 65 62 53 68 6F 70 00 00 02 00 07 C2 01 01 00 00 00 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 12 00 2B 79 63 C6 98 02 A6 12 00 03 5E 4F 5E 11 80 02 00 07 D1 08 12 00 00 00 31 00 00 33 37 00 00 00 32 00 00 00 00 00 00 04 00 00 60 00 3D 3E C2 FA 6E 02 2B 1D 01 15 E9 A3 8E E9 93 83 E8 8D 89 E6 95 99 E8 82 B2 E6 9C 8D E5 8A A1 00 80 00 00 07 C6 06 10 00 00 00 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 2E 02 27 13 93 02 0D FF FF 06 E7 83 82 E8 8F 9C 00 08 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 04 A2 00 33 01 2E E5 D7 00 D8 22 00 0B 4F 28 E2 88 A9 5F E2 88 A9 29 4F 11 48 82 46 07 C1 08 1A 00 00 00 31 00 00 33 35 00 00 00 35 08 04 08 04 08 04 04 00 0C 80 08 30 37 E9 68 46 00 00 00 FF 08 33 35 E4 BA 92 E8 81 94 01 00 00 00 00 00 00 00 00 00 00 31 00 00 33 35 00 00 00 32 00 00 00 00 00 00 04 00 00 40 02 37 00 64 B2 1D 00 00 FF FF 0F E5 98 89 E4 BC A6 E8 99 8E E8 99 8E E8 99 8E 01 48 06 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 01 40 8C 00 34 03 37 67 20 00 93 24 00 0C E8 93 9D E6 98 9F E7 A7 91 E6 8A 80 00 08 02 46 07 BF 0A 1A 00 00 00 31 00 00 33 35 00 00 00 35 08 04 08 04 08 04 04 00 00 00 10 2C 0A 9C 58 FB 01 53 00 00 04 4B E3 80 81 00 48 02 02 07 E3 00 00 00 00 00 31 00 00 00 00 00 00 00 00 0C 04 08 04 04 09 04 FD 03 02 00 2E 05 94 75 87 02 25 1F 00 06 54 4E 54 50 52 4F 00 40 02 00 07 C4 01 01 00 00 00 31 00 00 34 33 00 00 00 31 00 00 00 00 00 00 04 00 00 02 00 2E 11 48 2B 1A 02 0A 0B 00 06 E6 9D 8E E9 98 B3 11 08 02 02 07 D8 03 1C 00 00 00 31 00 00 34 34 00 00 00 33 00 00 00 00 00 00 04 00 00 6C 00 30 0B 9F C6 B6 00 AE 14 00 08 F0 9F 91 BC F0 9F 91 BF 11 00 02 42 07 CF 01 18 00 00 00 00 00 00 00 00 00 00 00 00 08 04 08 04 04 07 04 00 04 A0 00 34
|
||||
(18 BE 4B 0E) 00 00 36 00
|
||||
[0C] E5 B3 B0 E5 9B 9E E8 B7 AF E8 BD AC
|
||||
00 08 02 00 07 AD 02 03 00 00 00 31 00 00 31 35 00 00 32 32 00 00 00 00 00 00 04 00 00 00 00 00
|
||||
|
||||
04 5D EC AF 48
|
||||
*/
|
||||
|
||||
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): NicknameMap {
|
||||
//03 00 00 00 00 00 00 00 00 00 00 12 04 14 37
|
||||
val type = readUByte().toInt()
|
||||
if (type == 15) {
|
||||
discardExact(14)
|
||||
|
||||
val map = linkedMapOf<UInt, String>()
|
||||
while (remaining != 5L) { // 最后总是会剩余 04 5D EC AF 48
|
||||
val qq = readUInt()
|
||||
discardExact(4) // 4 个状态信息, 未知
|
||||
val nickname = readString(readUByte().toInt())
|
||||
discardExact(32) // 未知
|
||||
map[qq] = nickname
|
||||
}
|
||||
return NicknameMap(map)
|
||||
} else {
|
||||
error("Unsupported type $type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 用户资料的头像
|
||||
/**
|
||||
* 请求获取头像
|
||||
*/
|
||||
*/ // ? 这个包的数据跟下面那个包一样
|
||||
@AnnotatedId(KnownPacketId.REQUEST_PROFILE_AVATAR)
|
||||
internal object RequestProfileAvatarPacket : SessionPacketFactory<NoPacket>() {
|
||||
internal object RequestProfileAvatarPacket : SessionPacketFactory<AvatarLink>() {
|
||||
//00 01 00 17 D4 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 29 4E 22 4E 25 4E 26 4E 27 4E 29 4E 2A 4E 2B 4E 2D 4E 2E 4E 2F 4E 30 4E 31 4E 33 4E 35 4E 36 4E 37 4E 38 4E 3F 4E 40 4E 41 4E 42 4E 43 4E 45 4E 49 4E 4B 4E 4F 4E 54 4E 5B 52 0B 52 0F 5D C2 5D C8 65 97 69 9D 69 A9 9D A5 A4 91 A4 93 A4 94 A4 9C A4 B5
|
||||
operator fun invoke(
|
||||
bot: UInt,
|
||||
@ -27,9 +148,9 @@ internal object RequestProfileAvatarPacket : SessionPacketFactory<NoPacket>() {
|
||||
writeHex("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 29 4E 22 4E 25 4E 26 4E 27 4E 29 4E 2A 4E 2B 4E 2D 4E 2E 4E 2F 4E 30 4E 31 4E 33 4E 35 4E 36 4E 37 4E 38 4E 3F 4E 40 4E 41 4E 42 4E 43 4E 45 4E 49 4E 4B 4E 4F 4E 54 4E 5B 52 0B 52 0F 5D C2 5D C8 65 97 69 9D 69 A9 9D A5 A4 91 A4 93 A4 94 A4 9C A4 B5")
|
||||
}
|
||||
|
||||
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): NoPacket {
|
||||
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): AvatarLink {
|
||||
println(" RequestProfileAvatarPacket body=${this.readBytes().toUHexString()}")
|
||||
return NoPacket
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,26 @@
|
||||
|
||||
package net.mamoe.mirai
|
||||
|
||||
import kotlinx.io.core.buildPacket
|
||||
import kotlinx.io.core.readBytes
|
||||
import net.mamoe.mirai.contact.GroupInternalId
|
||||
import net.mamoe.mirai.contact.toId
|
||||
import net.mamoe.mirai.utils.io.toByteArray
|
||||
import net.mamoe.mirai.utils.io.toUHexString
|
||||
|
||||
actual object MiraiEnvironment {
|
||||
@JvmStatic
|
||||
actual val platform: Platform get() = Platform.JVM
|
||||
actual val platform: Platform
|
||||
get() = Platform.JVM
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun main() {
|
||||
println(GroupInternalId(2793514141u).toId().value.toLong())
|
||||
println(GroupInternalId(2040208217u).toId().value.toLong())
|
||||
println(289942298u.toByteArray().toUHexString())
|
||||
println(1040400290u.toByteArray().toUHexString())
|
||||
println(buildPacket {
|
||||
writeStringUtf8("信用卡")
|
||||
}.readBytes().toUByteArray().toUHexString())
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
package net.mamoe.mirai.network
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.io.core.use
|
||||
import kotlinx.io.streams.inputStream
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.message.Image
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.DataPacketSocketAdapter
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.SessionKey
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
@ -24,8 +22,9 @@ import javax.imageio.ImageIO
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
@Suppress("unused")
|
||||
actual class BotSession internal actual constructor(
|
||||
bot: Bot
|
||||
) : BotSessionBase(bot) {
|
||||
bot: Bot,
|
||||
sessionKey: SessionKey
|
||||
) : BotSessionBase(bot, sessionKey) {
|
||||
|
||||
suspend inline fun Image.downloadAsStream(): InputStream = download().inputStream()
|
||||
suspend inline fun Image.downloadAsBufferedImage(): BufferedImage = withContext(IO) { downloadAsStream().use { ImageIO.read(it) } }
|
||||
|
@ -134,27 +134,29 @@ suspend fun main() {
|
||||
println("Ready perfectly")
|
||||
}
|
||||
|
||||
suspend fun decryptRecordedPackets(filename: String) {
|
||||
File(filename).toRecorder()
|
||||
.list.forEach {
|
||||
suspend fun decryptRecordedPackets(filename: String?) {
|
||||
(if (filename == null) File(".").listFiles()?.maxBy { it.lastModified() }!!
|
||||
else File(filename)).toRecorder().also {
|
||||
println("total count = " + it.list.size)
|
||||
println()
|
||||
}.list.forEach {
|
||||
if (it.isSend) {
|
||||
try {
|
||||
dataSent(it.data)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
//e.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
dataReceived(it.data)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
||||
// e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decryptRecordedPackets("GMTDate(seconds=3, minutes=46, hours=7, dayOfWeek=SATURDAY, dayOfMonth=7, dayOfYear=341, month=DECEMBER, year=2019, timestamp=1575704763731).record")
|
||||
decryptRecordedPackets(null)
|
||||
//startPacketListening()
|
||||
}
|
||||
|
||||
@ -180,13 +182,13 @@ internal object PacketDebugger {
|
||||
* 7. 运行完 `mov eax,dword ptr ss:[ebp+10]`
|
||||
* 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `sessionKey`
|
||||
*/
|
||||
val sessionKey: SessionKey = SessionKey("98 4C 42 37 0F 87 BB A2 97 57 A1 77 A9 A9 74 37".hexToBytes())
|
||||
val sessionKey: SessionKey = SessionKey("F3 4A 4E F4 79 C4 92 62 EF 0F D8 6E D3 AB E3 80".hexToBytes())
|
||||
// TODO: 2019/12/7 无法访问 internal 是 kotlin bug, KT-34849
|
||||
|
||||
/**
|
||||
* null 则不筛选
|
||||
*/
|
||||
val qq: UInt? = null
|
||||
val qq: UInt? = 215555909u
|
||||
/**
|
||||
* 打开后则记录每一个包到文件.
|
||||
*/
|
||||
@ -229,7 +231,7 @@ internal object PacketDebugger {
|
||||
}
|
||||
.runCatching {
|
||||
decode(id, sequenceId, DebugNetworkHandler)
|
||||
}.getOrElse { it.printStackTrace(); null }
|
||||
}.getOrElse { /*it.printStackTrace();*/ null }
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,7 +239,9 @@ internal object PacketDebugger {
|
||||
if (packet !is IgnoredEventPacket) {
|
||||
println("--------------")
|
||||
println("接收包id=$id, \nsequence=${sequenceId.toUHexString()}")
|
||||
println(" 解密body=${decodedBody.toUHexString()}")
|
||||
if (packet !is UnknownPacket) {
|
||||
println(" 解密body=${decodedBody.toUHexString()}")
|
||||
}
|
||||
println(" 解析body=$packet")
|
||||
}
|
||||
|
||||
@ -390,7 +394,7 @@ internal object DebugNetworkHandler : BotNetworkHandler<DataPacketSocketAdapter>
|
||||
|
||||
}
|
||||
override val bot: Bot = Bot(qq ?: 0u, "", coroutineContext)
|
||||
override val session = BotSession(bot)
|
||||
override val session = BotSession(bot, SessionKey(byteArrayOf()))
|
||||
|
||||
override suspend fun login(): LoginResult = LoginResult.SUCCESS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user