Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
Mirai
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
Mirai
Commits
63a4d5f3
Commit
63a4d5f3
authored
Feb 02, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New PacketFactory structure
parent
26c86129
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
290 additions
and
418 deletions
+290
-418
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
...moe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
+7
-4
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/README.md
...tlin/net/mamoe/mirai/qqandroid/network/protocol/README.md
+0
-116
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/IncomingPacketFactory.kt
...qandroid/network/protocol/packet/IncomingPacketFactory.kt
+2
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/OutgoingPacketAndroid.kt
...qandroid/network/protocol/packet/OutgoingPacketAndroid.kt
+35
-151
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
.../mirai/qqandroid/network/protocol/packet/PacketFactory.kt
+94
-55
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImageDownPacket.kt
...oid/network/protocol/packet/chat/image/ImageDownPacket.kt
+5
-5
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImageUpPacket.kt
...droid/network/protocol/packet/chat/image/ImageUpPacket.kt
+6
-6
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
...ndroid/network/protocol/packet/chat/receive/MessageSvc.kt
+12
-15
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
...protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
+3
-7
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/list/FriendListPacket.kt
...qandroid/network/protocol/packet/list/FriendListPacket.kt
+5
-4
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/ConfigPushSvc.kt
.../qqandroid/network/protocol/packet/login/ConfigPushSvc.kt
+13
-11
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt
...ai/qqandroid/network/protocol/packet/login/LoginPacket.kt
+6
-3
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt
.../mirai/qqandroid/network/protocol/packet/login/StatSvc.kt
+2
-2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/TransEmpPacket.kt
...qqandroid/network/protocol/packet/login/TransEmpPacket.kt
+1
-1
mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/serverToClient.kt
...d/src/jvmTest/kotlin/androidPacketTests/serverToClient.kt
+2
-5
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt
...rc/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt
+97
-33
No files found.
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
View file @
63a4d5f3
...
@@ -104,7 +104,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -104,7 +104,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
}
}
override
suspend
fun
init
()
{
override
suspend
fun
init
()
{
delay
(
5000
)
//
delay(5000)
this
@QQAndroidBotNetworkHandler
.
subscribeAlways
<
ForceOfflineEvent
>
{
this
@QQAndroidBotNetworkHandler
.
subscribeAlways
<
ForceOfflineEvent
>
{
if
(
this
@QQAndroidBotNetworkHandler
.
bot
==
this
.
bot
)
{
if
(
this
@QQAndroidBotNetworkHandler
.
bot
==
this
.
bot
)
{
...
@@ -126,7 +126,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -126,7 +126,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
20
,
20
,
0
,
0
,
0
0
).
sendAndExpect
<
FriendList
.
GetFriendGroupList
.
Response
>()
).
sendAndExpect
<
FriendList
.
GetFriendGroupList
.
Response
>(
timeoutMillis
=
1000
)
totalFriendCount
=
data
.
totalFriendCount
totalFriendCount
=
data
.
totalFriendCount
data
.
friendList
.
forEach
{
data
.
friendList
.
forEach
{
...
@@ -150,7 +150,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -150,7 +150,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
bot
.
logger
.
info
(
"开始加载组信息"
)
bot
.
logger
.
info
(
"开始加载组信息"
)
val
troopData
=
FriendList
.
GetTroopListSimplify
(
val
troopData
=
FriendList
.
GetTroopListSimplify
(
bot
.
client
bot
.
client
).
sendAndExpect
<
FriendList
.
GetTroopListSimplify
.
Response
>()
).
sendAndExpect
<
FriendList
.
GetTroopListSimplify
.
Response
>(
timeoutMillis
=
1000
)
println
(
troopData
.
contentToString
())
println
(
troopData
.
contentToString
())
}
catch
(
e
:
Exception
)
{
}
catch
(
e
:
Exception
)
{
bot
.
logger
.
info
(
"加载组信息失败|一般这是由于加载过于频繁导致/将以热加载方式加载群列表"
)
bot
.
logger
.
info
(
"加载组信息失败|一般这是由于加载过于频繁导致/将以热加载方式加载群列表"
)
...
@@ -235,7 +235,10 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
...
@@ -235,7 +235,10 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
bot
.
logger
.
info
(
"Received packet: $packet"
)
bot
.
logger
.
info
(
"Received packet: $packet"
)
packetFactory
?.
run
{
packetFactory
?.
run
{
bot
.
handle
(
packet
)
when
(
this
)
{
is
OutgoingPacketFactory
<
P
>
->
bot
.
handle
(
packet
)
is
IncomingPacketFactory
<
P
>
->
bot
.
handle
(
packet
,
sequenceId
)
?.
sendWithoutExpect
()
}
}
}
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/README.md
deleted
100644 → 0
View file @
26c86129
# QQAndroid Protocol
## Overview
Note:
`head`
and
`body`
functions do nothing. They just work as
notations
PseudoCode:
```
OutgoingPacket {
int head.size + body.size + 4
head {
int 0x0A
byte 0x02
int extra data size + 4
byte[] extra data // initially={}
byte 0
int uinAccount.length + 4
byte[] uinAccount // =qqNumber.toString()
}
body { // encrypted by `ByteArray(16)` when login, after which by sessionKey
SSOPacket {
int head.size + 4
head {
int sequenceId
int subAppId
int subAppId
hex "01 00 00 00 00 00 00 00 00 00 01 00" // unknown values
int extraData.size + 4
byte[] extraData // empty when login
int commandName.length + 4
byte[] commandName // e.g. wtlogin.login
int 4 + 4
int 0x02B05B8B
int imei.length + 4
byte[] imei
int 0 + 4
short ksid.length + 2
byte[] ksid
int 0 + 4
}
int body.size + 4
body {
OicqRequestPacket {
head {
byte 2 // head flag
short 27 + 2 + remaining.length
ushort client.protocolVersion // const 8001
ushort commandId // e.g. 0x0810
ushort 0x0001
uint client.uin
byte 3 // const
ubyte encryptMethod.value // [EncryptMethod]
byte 0 // const
int 2 // const
int client.appClientVersion
int 0 // const
}
body {
// only write one of the following two structures!!
// if encryption method is ECDH
EncryptionMethodECDH {
head {
byte 1
byte 1
byte[] privateKey // random key
short 258
short [ECDH.publicKey].size // always 49
byte[] [ECDH.publicKey]
}
body {
// real body
}
}
// if encryption method is SessionKey
EncryptionMethodSessionKey {
head {
byte 1
byte if (currentLoginState == 2) 3 else 2
fully key
short 258 // const
short 0
}
body {
// real body
}
}
}
tail {
byte 3 // tail flag
}
}
}
}
}
}
```
## Packet bodies
### LoginPacket - SubCommand 9
**TO BE UPDATED**
PseudoCode:
```
short 9 // subCommand
tlvList {
}
```
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/IncomingPacketFactory.kt
0 → 100644
View file @
63a4d5f3
package
net.mamoe.mirai.qqandroid.network.protocol.packet
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/OutgoingPacketAndroid.kt
View file @
63a4d5f3
...
@@ -12,10 +12,6 @@ import net.mamoe.mirai.utils.io.writeHex
...
@@ -12,10 +12,6 @@ import net.mamoe.mirai.utils.io.writeHex
import
net.mamoe.mirai.utils.io.writeIntLVPacket
import
net.mamoe.mirai.utils.io.writeIntLVPacket
import
net.mamoe.mirai.utils.io.writeQQ
import
net.mamoe.mirai.utils.io.writeQQ
/**
* 待发送给服务器的数据包. 它代表着一个 [ByteReadPacket].
* 只有最终的包才会被包装为 [OutgoingPacket].
*/
internal
class
OutgoingPacket
constructor
(
internal
class
OutgoingPacket
constructor
(
name
:
String
?,
name
:
String
?,
val
commandName
:
String
,
val
commandName
:
String
,
...
@@ -31,25 +27,11 @@ internal val KEY_16_ZEROS = ByteArray(16)
...
@@ -31,25 +27,11 @@ internal val KEY_16_ZEROS = ByteArray(16)
internal
val
EMPTY_BYTE_ARRAY
=
ByteArray
(
0
)
internal
val
EMPTY_BYTE_ARRAY
=
ByteArray
(
0
)
/**
/**
* 最外层的包. 结构适用于登录之后的过程.
*
* 在 QQ 中这个被以 JNI 实现:
* com.tencent.qphone.base.util.CodecWarpper#encodeRequest(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, byte[], int, int, java.lang.String, byte, byte, byte, byte[], byte[], boolean)
* com.tencent.qphone.base.util.CodecWarpper#encodeRequest(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, byte[], int, int, java.lang.String, byte, byte, byte, byte[], byte[], boolean)
*
* **Packet structure**
* int remaining.length + 4
* int 0x0B
* byte 0x01
* int sequenceId
* byte 0
* int uinAccount.length + 4
* byte[] uinAccount
*
* byte[] body encrypted by 16 zero
*/
*/
@Deprecated
(
"危险"
,
level
=
DeprecationLevel
.
ERROR
)
@Deprecated
(
"危险"
,
level
=
DeprecationLevel
.
ERROR
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
inline
fun
PacketFactory
<*>.
buildOutgoingPacket
(
internal
inline
fun
Outgoing
PacketFactory
<*>.
buildOutgoingPacket
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
bodyType
:
Byte
=
1
,
// 1: PB?
bodyType
:
Byte
=
1
,
// 1: PB?
name
:
String
?
=
this
.
commandName
,
name
:
String
?
=
this
.
commandName
,
...
@@ -76,11 +58,8 @@ internal inline fun PacketFactory<*>.buildOutgoingPacket(
...
@@ -76,11 +58,8 @@ internal inline fun PacketFactory<*>.buildOutgoingPacket(
})
})
}
}
/**
* buildOutgoingPacket 与 writeUniPacket 的 fast-path
*/
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
inline
fun
PacketFactory
<*>.
buildOutgoingUniPacket
(
internal
inline
fun
Outgoing
PacketFactory
<*>.
buildOutgoingUniPacket
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
bodyType
:
Byte
=
1
,
// 1: PB?
bodyType
:
Byte
=
1
,
// 1: PB?
name
:
String
?
=
this
.
commandName
,
name
:
String
?
=
this
.
commandName
,
...
@@ -110,6 +89,37 @@ internal inline fun PacketFactory<*>.buildOutgoingUniPacket(
...
@@ -110,6 +89,37 @@ internal inline fun PacketFactory<*>.buildOutgoingUniPacket(
})
})
}
}
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
inline
fun
IncomingPacketFactory
<*>.
buildResponseUniPacket
(
client
:
QQAndroidClient
,
bodyType
:
Byte
=
1
,
// 1: PB?
name
:
String
?
=
this
.
responseCommandName
,
commandName
:
String
=
this
.
responseCommandName
,
key
:
ByteArray
=
client
.
wLoginSigInfo
.
d2Key
,
extraData
:
ByteReadPacket
=
BRP_STUB
,
sequenceId
:
Int
=
client
.
nextSsoSequenceId
(),
body
:
BytePacketBuilder
.(
sequenceId
:
Int
)
->
Unit
):
OutgoingPacket
{
return
OutgoingPacket
(
name
,
commandName
,
sequenceId
,
buildPacket
{
writeIntLVPacket
(
lengthOffset
=
{
it
+
4
})
{
writeInt
(
0
x0B
)
writeByte
(
bodyType
)
writeInt
(
sequenceId
)
writeByte
(
0
)
client
.
uin
.
toString
().
let
{
writeInt
(
it
.
length
+
4
)
writeStringUtf8
(
it
)
}
encryptAndWrite
(
key
)
{
writeUniPacket
(
commandName
,
client
.
outgoingPacketUnknownValue
,
extraData
)
{
body
(
sequenceId
)
}
}
}
})
}
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
inline
fun
BytePacketBuilder
.
writeUniPacket
(
internal
inline
fun
BytePacketBuilder
.
writeUniPacket
(
commandName
:
String
,
commandName
:
String
,
...
@@ -140,25 +150,10 @@ internal inline fun BytePacketBuilder.writeUniPacket(
...
@@ -140,25 +150,10 @@ internal inline fun BytePacketBuilder.writeUniPacket(
/**
/**
* 最外层的包. 结构适用于登录.
*
* 在 QQ 中这个被以 JNI 实现:
* com.tencent.qphone.base.util.CodecWarpper#encodeRequest(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, byte[], int, int, java.lang.String, byte, byte, byte, byte[], byte[], boolean)
* com.tencent.qphone.base.util.CodecWarpper#encodeRequest(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, byte[], int, int, java.lang.String, byte, byte, byte, byte[], byte[], boolean)
*
* **Packet structure**
* int remaining.length + 4
* int 0x0A
* byte 0x02
* int extra data size + 4
* byte[] extra data
* byte 0
* int uinAccount.length + 4
* byte[] uinAccount
*
* byte[] body encrypted by 16 zero
*/
*/
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
inline
fun
PacketFactory
<*>.
buildLoginOutgoingPacket
(
internal
inline
fun
Outgoing
PacketFactory
<*>.
buildLoginOutgoingPacket
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
bodyType
:
Byte
,
bodyType
:
Byte
,
extraData
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
extraData
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
...
@@ -193,30 +188,6 @@ internal inline fun PacketFactory<*>.buildLoginOutgoingPacket(
...
@@ -193,30 +188,6 @@ internal inline fun PacketFactory<*>.buildLoginOutgoingPacket(
private
inline
val
BRP_STUB
get
()
=
ByteReadPacket
.
Empty
private
inline
val
BRP_STUB
get
()
=
ByteReadPacket
.
Empty
/**
* The second outermost packet for login
*
* int headRemaining.size+4
* int sequenceId
* int subAppId
* int subAppId
* hex "01 00 00 00 00 00 00 00 00 00 01 00" // unknown values
* int extraData.size+4
* byte[] extraData
* int commandName.length+4
* byte[] commandName
* int 4+4
* int 0x02B05B8B
* int imei.length+4
* byte[] imei
* int 0+4
* int ksid.length+4
* byte[] ksid
* int 0+4
*
* int bodyRemaining.size+4
* byte[] body()
*/
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
inline
fun
BytePacketBuilder
.
writeSsoPacket
(
internal
inline
fun
BytePacketBuilder
.
writeSsoPacket
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
...
@@ -266,26 +237,6 @@ internal inline fun BytePacketBuilder.writeSsoPacket(
...
@@ -266,26 +237,6 @@ internal inline fun BytePacketBuilder.writeSsoPacket(
writeIntLVPacket
(
lengthOffset
=
{
it
+
4
},
builder
=
body
)
writeIntLVPacket
(
lengthOffset
=
{
it
+
4
},
builder
=
body
)
}
}
/**
* Writes a request packet
* This is the innermost packet structure
*
* **Packet Structure**
* byte 2 // head flag
* short 27 + 2 + remaining.length
* ushort client.protocolVersion // const 8001
* ushort 0x0001
* uint client.uin
* byte 3 // const
* ubyte encryptMethod.value // [EncryptMethod]
* byte 0 // const
* int 2 // const
* int client.appClientVersion
* int 0 // const
* bodyBlock()
* byte 3 // tail
*/
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
,
MiraiInternalAPI
::
class
)
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
,
MiraiInternalAPI
::
class
)
internal
fun
BytePacketBuilder
.
writeOicqRequestPacket
(
internal
fun
BytePacketBuilder
.
writeOicqRequestPacket
(
client
:
QQAndroidClient
,
client
:
QQAndroidClient
,
...
@@ -294,8 +245,6 @@ internal fun BytePacketBuilder.writeOicqRequestPacket(
...
@@ -294,8 +245,6 @@ internal fun BytePacketBuilder.writeOicqRequestPacket(
bodyBlock
:
BytePacketBuilder
.()
->
Unit
bodyBlock
:
BytePacketBuilder
.()
->
Unit
)
{
)
{
val
body
=
encryptMethod
.
makeBody
(
client
,
bodyBlock
)
val
body
=
encryptMethod
.
makeBody
(
client
,
bodyBlock
)
// writeIntLVPacket(lengthOffset = { it + 4 }) {
// Head
writeByte
(
0
x02
)
// head
writeByte
(
0
x02
)
// head
writeShort
((
27
+
2
+
body
.
remaining
).
toShort
())
// orthodox algorithm
writeShort
((
27
+
2
+
body
.
remaining
).
toShort
())
// orthodox algorithm
writeShort
(
client
.
protocolVersion
)
writeShort
(
client
.
protocolVersion
)
...
@@ -309,72 +258,7 @@ internal fun BytePacketBuilder.writeOicqRequestPacket(
...
@@ -309,72 +258,7 @@ internal fun BytePacketBuilder.writeOicqRequestPacket(
writeInt
(
client
.
appClientVersion
)
writeInt
(
client
.
appClientVersion
)
writeInt
(
0
)
// constp_always_0
writeInt
(
0
)
// constp_always_0
// Body
writePacket
(
body
)
writePacket
(
body
)
// Tail
writeByte
(
0
x03
)
// tail
writeByte
(
0
x03
)
// tail
// }
}
}
\ No newline at end of file
/*
00 00 01 64
00 00 00 0A
02
00 00 00 04
00
00 00 00 0E
31 39 39 34 37 30 31 30 32 31
// encrypted with 16zero
F8 22 FC 39 2E 93 D7 73 A9 75 A2 D4 67 D2 C4 0D F1 02 1F A5 74 8F D8 0E 8E 86 AF 4F 4A A9 C7 74 56 71 B9 03 FC B3 DE A0 F3 14 B7 E9 54 3B 22 F0 24 10 BD 52 88 FC F3 58 66 6C B9 DB 4D 45 2C EF DE 2C C9 E1 1B 27 C7 E2 EF 38 6A 7E 8B 52 3A F4 93 40 E1 A9 ED 10 C3 A3 7E 64 17 02 8F 5C 01 92 72 C7 B8 E0 E1 A5 AF 0B 27 D0 05 C1 33 37 77 37 6D 96 0B B4 1F 41 98 42 35 2C 2A 00 E4 ED E8 C6 42 C4 F4 FD 13 39 D8 E8 19 50 E9 49 06 37 CA CF 42 C3 DD B5 DC B0 E9 87 83 6E 77 AE B6 5C F5 0D 6A 08 67 D0 61 B0 86 39 F7 2E AF E7 B7 C5 F4 42 40 A1 E1 A9 90 55 26 BD C6 03 73 73 BF A2 0A 3F E6 D3 8D B3 69 63 81 83 1E F1 72 5D FA FC 5E 65 B9 C1 FE 77 A8 50 80 F1 A5 DF E0 C4 96 1D 21 CD 5B 70 62 35 51 B5 37 1F 0B 4A 6D 97 92 D0 33 2B 56 11 CB 54 E5 6A A4 B9 97 04 B3 4B 27 A6 61 B7 77 5C C0 D1 6B 98 1C 7A 7B 57 28 3B 80 3B 81 88 69 D2 1C 91 B8 4A DE 0F FD A2 82 F8 3B F6 61 90 84 EF 4A 17 B6 30 1D 09 62 11 C7 BB 00 76 8E 0D 48 1B 11 F4 90 7A 13 0F 09 2B 4E 2F BE FD D9 57 07 18 29 4C 52 23 2E AE
//decrypted:
00 00 00 C1
00 01 4E 6A
20 02 ED BD
20 02 ED BD
01 00 00 00 00 00 00 00 00 00 01 00
00 00 00 4C
B8 12 0D E1 DA 19 AF D3 EB 36 76 BD 42 08 F6 DC A5 35 69 C0 8F F2 75 28 B4 CE 09 C9 B7 86 E3 5A 14 D1 0D CA 5D D4 CB 16 77 8B 32 8D 81 3B 3F D9 52 13 77 03 D3 F7 0E CD 7B 21 95 D2 59 CE 0C 31 D6 F1 38 2A FA 82 AD 60
00 00 00 14
47 72 61 79 55 69 6E 50 72 6F 2E 43 68 65 63 6B // serviceCommand
00 00 00 08
02 B0 5B 8B
00 00 00 13
38 35 38 34 31 34 33 36 39 32 31 31 39 39 33
00 00 00 04
00 22
7C 34 35 34 30 30 31 32 32 38 34 33 37 35 39 30 7C 41 38 2E 32 2E 30 2E 32 37 66 36 65 61 39 36 00 00 00 04
00 00 00 7A // UniPacket
10
03 2C
3C 42 00 01 4E 69 56 22 4B 51 51 2E 43 6F 6E 66 69 67 53 65 72 76 69 63 65 2E 43 6F 6E 66 69 67 53 65 72 76 61 6E 74 4F 62 6A 66 09 43 6C 69 65 6E 74 52 65 71 7D 00 00 35 08 00 01 06 03 72 65 71 1D 00 00 29 0A 12 20 02 ED BD 26 0A 31 39 39 34 37 30 31 30 32 31 36 00 46 12 31 30 31 31 30 33 30 38 33 38 34 36 30 36 32 30 34 32 0B 8C 98 0C A8 0C
*/
/*
00 00 00 FC
00 00 00 0B
01 // packet type?
00 01 50 DE
00
00 00 00 0E
31 39 39 34 37 30 31 30 32 31
4E 32 1B 0F 07 DC 39 FE 14 78 ED 32 60 C4 07 31 9D CD 1A E0 C4 F6 21 6B EA 52 A4 F4 C1 D2 AF FB 17 5A C4 15 BC 35 BC 45 58 B6 11 19 DA AF 12 91 B5 A0 5D E4 FD 5A 49 1A 55 71 45 89 6F 3A 09 E6 32 F4 96 4A BB B2 EE 35 B9 39 63 5B FF E3 F0 94 69 67 99 64 A2 03 23 D0 F7 74 81 D1 20 F8 20 E6 F3 5B E6 C2 A2 25 6F 90 C5 DA CB D2 08 9D 5D 83 47 F3 27 3F 41 19 E5 9A C0 F2 05 70 B2 C5 DC F9 F1 6D 2A E9 92 84 9C 8D 98 04 E8 A1 3B 40 F2 71 60 9F 2C D8 6A CD 6B F5 2B 12 68 C7 9C 6B 0E D2 F7 16 40 47 72 3D 6A AF 36 2E 43 0C 96 28 C7 A6 B1 04 3B 29 F6 8B A4 E0 47 1A 3D 51 32 C7 AF A5 7E FD F7 50 FC 81 3D 13 45 60 6B 8D F4 A6 9B E7 46 D4 1E 9B 2C 00 D0 24 2F 0E 44 29 43 A8 F6 25
*/
/*
00 00 01 04
00 00 00 0B
01
00 01 50 CE
00
00 00 00 0E 31 39 39 34 37 30 31 30 32 31 D2 D5 37 8A 3C 47 B1 84 E2 94 B2 AF BF 14 70 4D 73 17 BB 38 BE 82 73 DF A2 87 E0 0A 7A BA 8A 81 71 77 1D E1 71 7F B7 C1 66 1D 8C 3D 41 4F 51 09 6A B7 B7 7B 88 28 A6 5A AB 7E 40 25 9B C8 35 9C C6 E2 3A 5F 94 1D 70 0F D7 89 4D 41 6B 7A 29 A2 70 77 3D F8 1D 32 65 D7 D8 D1 6D 13 42 9C 0C 72 DB 48 95 4B 66 EF B9 E6 E4 C1 3B 2C 36 B0 D7 3F E2 85 C8 2A 8C 65 0F 0B 1C F1 A7 C7 E1 1F 0C 32 F5 08 14 AA 5A 43 CD 8E A8 82 14 24 97 63 F0 53 79 4E 33 8D 5F 1C F8 1C 89 3B 39 44 CC A7 63 5F FC BF 87 42 89 2D A5 F4 BC B2 69 49 54 DD AE E6 3F A2 A2 98 DC 3B D4 A2 27 10 F2 06 42 93 C5 30 4A D4 FA F5 BA A5 B2 4B 56 45 59 94 CA 4C 4B 17 55 C7 23 AF F0 8B E5 DC 3A 1B B6 A7 2E 10 BB 9A E7 70 54 BA F5 4B 70 91
*/
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
View file @
63a4d5f3
...
@@ -5,8 +5,6 @@ import kotlinx.io.pool.useInstance
...
@@ -5,8 +5,6 @@ import kotlinx.io.pool.useInstance
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.event.Subscribable
import
net.mamoe.mirai.event.Subscribable
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.io.serialization.loadAs
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.OnlinePush
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.OnlinePush
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
...
@@ -24,19 +22,31 @@ import kotlin.contracts.ExperimentalContracts
...
@@ -24,19 +22,31 @@ import kotlin.contracts.ExperimentalContracts
import
kotlin.contracts.contract
import
kotlin.contracts.contract
import
kotlin.jvm.JvmName
import
kotlin.jvm.JvmName
internal
sealed
class
PacketFactory
<
TPacket
:
Packet
>
{
/**
* 筛选从服务器接收到的包时的 commandName
*/
abstract
val
receivingCommandName
:
String
}
/**
/**
* 一种数据包的处理工厂. 它可以解密解码服务器发来的这个包, 也可以编码加密要发送给服务器的这个包
* 一种客户端主动发送的数据包的处理工厂.
* 它必须是由客户端主动发送, 产生一个 sequenceId, 然后服务器以相同的 sequenceId 返回.
* 必须在 [KnownPacketFactories] 中注册工厂, 否则将不能收到回复.
* 应由一个 `object` 实现, 且实现 `operator fun invoke` 或按 subCommand 或其意义命名的函数来构造 [OutgoingPacket]
* 应由一个 `object` 实现, 且实现 `operator fun invoke` 或按 subCommand 或其意义命名的函数来构造 [OutgoingPacket]
*
*
* @param TPacket 服务器回复包解析结果
* @param TPacket 服务器回复包解析结果
*/
*/
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
)
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
)
internal
abstract
class
PacketFactory
<
TPacket
:
Packet
>(
internal
abstract
class
Outgoing
PacketFactory
<
TPacket
:
Packet
>(
/**
/**
* 命令名. 如 `wtlogin.login`, `ConfigPushSvc.PushDomain`
* 命令名. 如 `wtlogin.login`, `ConfigPushSvc.PushDomain`
*/
*/
val
commandName
:
String
val
commandName
:
String
)
{
)
:
PacketFactory
<
TPacket
>()
{
final
override
val
receivingCommandName
:
String
get
()
=
commandName
/**
/**
* **解码**服务器的回复数据包. 返回的包若是 [Subscribable], 则会 broadcast.
* **解码**服务器的回复数据包. 返回的包若是 [Subscribable], 则会 broadcast.
*/
*/
...
@@ -48,34 +58,81 @@ internal abstract class PacketFactory<TPacket : Packet>(
...
@@ -48,34 +58,81 @@ internal abstract class PacketFactory<TPacket : Packet>(
open
suspend
fun
QQAndroidBot
.
handle
(
packet
:
TPacket
)
{}
open
suspend
fun
QQAndroidBot
.
handle
(
packet
:
TPacket
)
{}
}
}
/**
* 处理服务器发来的包的工厂.
* 这个工厂可以在 [handle] 时回复一个 commandId 为 [responseCommandName] 的包, 也可以不回复.
* 必须先到 [KnownPacketFactories] 中注册工厂, 否则不能处理.
*/
internal
abstract
class
IncomingPacketFactory
<
TPacket
:
Packet
>(
/**
* 接收自服务器的包的 commandName
*/
override
val
receivingCommandName
:
String
,
/**
* 要返回给服务器的包的 commandName
*/
val
responseCommandName
:
String
=
""
)
:
PacketFactory
<
TPacket
>()
{
/**
* **解码**服务器的回复数据包. 返回的包若是 [Subscribable], 则会 broadcast.
*/
abstract
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
TPacket
/**
* 处理解码后的包, 返回一个 [OutgoingPacket] 以发送给服务器, 返回 null 则不作处理.
*/
open
suspend
fun
QQAndroidBot
.
handle
(
packet
:
TPacket
,
sequenceId
:
Int
):
OutgoingPacket
?
{
return
null
}
}
@JvmName
(
"decode0"
)
@JvmName
(
"decode0"
)
private
suspend
inline
fun
<
P
:
Packet
>
PacketFactory
<
P
>.
decode
(
bot
:
QQAndroidBot
,
packet
:
ByteReadPacket
):
P
=
packet
.
decode
(
bot
)
private
suspend
inline
fun
<
P
:
Packet
>
OutgoingPacketFactory
<
P
>.
decode
(
bot
:
QQAndroidBot
,
packet
:
ByteReadPacket
):
P
=
packet
.
decode
(
bot
)
@JvmName
(
"decode1"
)
private
suspend
inline
fun
<
P
:
Packet
>
IncomingPacketFactory
<
P
>.
decode
(
bot
:
QQAndroidBot
,
packet
:
ByteReadPacket
,
sequenceId
:
Int
):
P
=
packet
.
decode
(
bot
,
sequenceId
)
internal
val
DECRYPTER_16_ZERO
=
ByteArray
(
16
)
internal
val
DECRYPTER_16_ZERO
=
ByteArray
(
16
)
internal
typealias
PacketConsumer
<
T
>
=
suspend
(
packetFactory
:
PacketFactory
<
T
>,
packet
:
T
,
commandName
:
String
,
ssoSequenceId
:
Int
)
->
Unit
internal
typealias
PacketConsumer
<
T
>
=
suspend
(
packetFactory
:
PacketFactory
<
T
>,
packet
:
T
,
commandName
:
String
,
ssoSequenceId
:
Int
)
->
Unit
/**
* 数据包相关的调试输出.
* 它默认是关闭的.
*/
@PublishedApi
@PublishedApi
internal
val
PacketLogger
:
MiraiLoggerWithSwitch
=
DefaultLogger
(
"Packet"
).
withSwitch
(
false
)
internal
val
PacketLogger
:
MiraiLoggerWithSwitch
=
DefaultLogger
(
"Packet"
).
withSwitch
(
false
)
/**
* 已知的数据包工厂列表.
*/
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
)
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
)
internal
object
KnownPacketFactories
:
List
<
PacketFactory
<
*
>>
by
mutableListOf
(
internal
object
KnownPacketFactories
{
object
OutgoingFactories
:
List
<
OutgoingPacketFactory
<
*
>>
by
mutableListOf
(
LoginPacket
,
LoginPacket
,
StatSvc
.
Register
,
StatSvc
.
Register
,
OnlinePush
.
PbPushGroupMsg
,
MessageSvc
.
PushNotify
,
MessageSvc
.
PbGetMsg
,
MessageSvc
.
PbGetMsg
,
MessageSvc
.
PushForceOffline
,
MessageSvc
.
PushForceOffline
,
MessageSvc
.
PbSendMsg
,
MessageSvc
.
PbSendMsg
,
FriendList
.
GetFriendGroupList
,
FriendList
.
GetFriendGroupList
,
FriendList
.
GetTroopListSimplify
,
FriendList
.
GetTroopListSimplify
)
object
IncomingFactories
:
List
<
IncomingPacketFactory
<
*
>>
by
mutableListOf
(
OnlinePush
.
PbPushGroupMsg
,
MessageSvc
.
PushNotify
,
ConfigPushSvc
.
PushReq
ConfigPushSvc
.
PushReq
)
{
)
// SvcReqMSFLoginNotify 自己的其他设备上限
// SvcReqMSFLoginNotify 自己的其他设备上限
// MessageSvc.PushReaded 电脑阅读了别人的消息, 告知手机
// MessageSvc.PushReaded 电脑阅读了别人的消息, 告知手机
// OnlinePush.PbC2CMsgSync 电脑发消息给别人, 同步给手机
// OnlinePush.PbC2CMsgSync 电脑发消息给别人, 同步给手机
fun
findPacketFactory
(
commandName
:
String
):
PacketFactory
<
*
>?
=
this
.
firstOrNull
{
it
.
commandName
==
commandName
}
@Suppress
(
"MemberVisibilityCanBePrivate"
)
// debugging use
fun
findPacketFactory
(
commandName
:
String
):
PacketFactory
<
*
>?
{
return
OutgoingFactories
.
firstOrNull
{
it
.
receivingCommandName
==
commandName
}
?:
IncomingFactories
.
firstOrNull
{
it
.
receivingCommandName
==
commandName
}
}
// 00 00 08 70 00 00 00 0A 01 00 00 00 00 0E 31 39 39 34 37 30 31 30 32 31 F5 45 50 03 B7 F7 99 8F DC CE F6 A2 35 08 04 85 D6 1D 52 90 24 13 86 A2 9D 40 D9 CD BF 4B 08 56 E7 EF 37 E6 E7 BE 09 FD A8 E5 D8 DA 07 90 E5 CB 22 1A 5A 77 88 B5 1A 0B 36 2A 71 59 1C 79 7C B1 84 39 CF 74 31 C5 ED 4D BB 12 F3 BB 10 B2 2E CD 05 82 86 AC 78 68 74 C3 42 9F CF F9 14 0D D4 2B 89 E9 FC 4D 1D 29 F3 08 A0 3A 62 F3 B5 71 D3 A9 06 BD 45 BA 50 D6 2D 68 05 B7 B4 D3 07 D0 01 A4 F4 71 0A 76 34 1F CA 2D 3A 53 6A C5 44 CA 56 C9 FA 0F 81 5E 06 63 45 9B BD FA 81 D3 50 46 74 34 C2 A8 21 9B 1B 25 E6 23 38 E5 87 B4 D2 A7 E7 59 65 03 BB 6D 46 D5 21 66 F6 2F 2D BF A3 77 2A 33 9D E1 35 18 45 CE 22 DB C1 52 BB 87 B9 F0 CB B1 CD 39 81 43 BD C1 E5 2B 81 DE 29 EC 72 2A 56 14 23 67 7B 60 F7 FB C1 7F 9C 18 8E ED 67 35 3E 2F EA D1 EA 24 AD 12 6D 65 B3 27 0C 2B 0A 43 42 3E 0C 81 C5 02 7D E6 A5 2C 79 8D 53 2D 06 F1 EE A5 51 BC 24 A6 F5 F2 0C BC 1F 42 F2 21 8F FB DF 9C 98 6F 25 FB D0 09 E1 F3 85 76 A2 96 39 5E 73 06 24 F8 1E 6C F7 D3 03 15 44 BA 6B 42 9E CE 14 7B 1A F9 0B A1 9A 85 FD 52 2B 34 FB 0F D8 6F 34 38 6E F3 A2 7D EB DF 3F 55 6A 52 27 35 44 5C 26 05 F3 36 8E 8F 00 D2 31 85 BF 20 8A 1C 37 57 C4 74 36 BF 89 3F 44 3C 97 AA 6B 8F D1 B6 CD D6 45 88 F1 74 35 CD 8B 85 9F 60 F4 B7 00 3E 87 10 C4 3F 7C 3F 22 F0 20 58 40 CE E6 77 8B 3D EE AA EB 31 52 65 BE C4 12 2B 28 65 1A 26 16 55 E9 86 28 90 42 FD 48 D6 6F E6 63 E2 40 3F BE 68 C6 FE A7 B2 10 31 15 7E B4 C7 2C 8D D9 04 8D AD 8E 45 D2 CA EC 07 D6 D0 14 FD 93 02 4B 3D 71 6E 3E 1F D5 BC ED 98 0E 01 6B FE 1C 96 24 34 DF A3 E3 EE 67 40 F3 C7 AA 10 4E 44 62 49 D5 45 14 15 49 04 2F 9F FC 5D 40 F7 5A CC C1 78 7B 37 35 80 F9 10 80 EB 40 DB 33 06 5F 2A 70 88 F0 94 49 59 48 4B 00 66 28 E9 E9 E7 CE E4 CA 6D 21 79 09 62 7A 6E C5 47 A4 08 85 73 43 35 2D EE E4 0E 85 47 92 B4 F1 5C 76 C2 72 BC D1 70 41 6D 9B EE F4 47 67 1F 63 57 B9 65 C1 08 5C 42 D6 28 FB 6F F5 1A 4B E0 B7 5A 36 75 E6 BE ED C6 67 DA 64 19 09 11 CF 9A 74 4A F4 4E 4F 1E 02 2C 8C 21 21 DE 76 15 34 E5 F2 DF F9 34 31 99 4F 4B B2 5E E6 2B 8D 7C 64 E9 7D 78 98 4F 28 FF 2E 95 1B 5D 8E 2F 70 E6 01 0A 82 18 90 16 8F 98 5E 0F CA 30 4F 36 AF 9B 5E 2B 5B FE 59 5E 11 BC A5 68 64 55 BD 04 CE 43 60 4C C9 CB F7 88 D2 30 7A 89 75 3D 93 9D A9 D0 CE 7D 4B CE 4D 14 5E 95 0E 18 3E 75 AE 20 C6 8A 6E 15 F9 39 58 3B 17 74 99 98 07 5D 68 B1 51 57 AF 1D 85 F1 A5 8A FE 9F 07 BC CB B9 84 A5 49 AE 9F F4 50 06 27 24 7F EB 66 C0 F7 C4 4F E9 74 FA 69 8E D0 A6 A4 3E 8A A8 D9 10 A1 05 03 0F B1 E7 80 22 A9 21 22 FA 31 A1 61 0E 5A 42 75 5F 19 95 2E FE A9 38 51 BB E9 C1 6B 29 CD AE 8F 78 7C 1F A4 81 F2 20 D3 15 C1 EA 42 BD 5F 52 C1 BA 5F C7 42 97 A8 F1 FA C6 20 82 3C 00 36 96 75 69 27 FE 93 AA BD 43 BD 0E FD ED 30 97 A6 B2 A2 E8 D3 75 C2 BF 35 EC 78 8A 3E 23 9D 6D DD 3C D4 4A BC 5A A8 74 86 3C A7 31 F5 F3 8A 78 9C 3C 75 88 B1 35 4A 83 91 EB 5F 80 F3 E0 0C EC 82 5C 7B 08 61 45 E3 3B 7B F1 1F BC 6D 5E 99 3A 34 68 28 20 42 8C 42 C9 0A 3F 32 42 03 E5 9A 71 BB E1 02 C9 B4 98 6E 73 7E EC 81 79 28 01 A8 E5 AC 0F 24 0A 58 DA C1 D2 F0 2C 94 E7 4D E5 ED B3 43 58 23 73 1D 7F 33 B0 7B 1A A8 C1 AC 6E 7C F1 A6 51 0F CF E9 51 5F 06 EB 79 C4 0C E9 78 6C B8 B8 11 C0 2E 84 BC F4 4D 05 D5 B5 90 20 30 BE 73 28 83 91 3B 4D 90 2E 8F A5 A8 BF 85 63 29 05 04 33 14 7D 24 24 7D 02 9B 39 5D 30 D0 68 58 57 1A 0D 67 A6 EF 44 4C 4E 92 14 0A 2A E4 24 1E 60 78 A3 65 71 7E E3 B2 44 E1 55 3E F2 08 05 F5 59 5E EE D3 0A 12 34 C2 FC 74 4A 8C F9 BE 7F 4D EC 9E D3 14 97 7F DF 75 E2 52 21 95 65 99 F4 1D 01 AD F4 D2 4D 8C 9E 5A 16 DE 65 AA D0 AC 24 17 FE BE B9 D8 9B FB 36 33 E5 AE 1B F9 B1 AE A4 9B 15 94 91 6D 45 BE 61 33 4B 71 40 BC DB D0 BF 06 39 83 D5 5F 30 6D E0 20 D3 33 AA 78 13 DA 9A 80 A3 38 4F 3B F8 AE B9 7F 9B B7 F1 AD 10 88 96 DD 79 DD F8 86 A3 72 A2 3F C2 6E B2 6D CE 36 54 90 5F DE 23 90 CD BD BD DB 95 83 5A 94 8E B8 54 AF 0A AB 10 0C 15 B3 3D 2B 89 7D 83 64 B9 29 08 50 40 6E F6 EC 8D E7 79 6C 2B 70 A5 07 FA AD 6A A1 54 EC D7 C7 70 A6 9F 8F 8E 5B 00 5E 8D 27 0D 21 8B 38 31 02 88 13 6E F4 5C 8D 15 82 FC 3E AE 57 17 3D 6D 38 F9 8C 2B EF 87 FA 30 FB 59 D4 E2 49 CF 76 75 9C 9D 50 8D 4A CD AE F6 3C 59 E8 92 BB C1 E2 5C F6 96 8B DC 78 DF E1 27 6B F1 1C D9 68 1D 29 8A E3 09 DD 28 C7 0A ED BB 75 6B D9 87 9F 7F 71 5D D0 EE 03 5B 28 52 40 26 DD C9 C4 52 4D 58 02 3A 71 BE 6C F4 6A 30 14 52 72 CB 45 95 80 DE 28 02 8A 22 7A 05 B5 D7 22 61 06 E0 34 09 AC A9 A8 A8 D0 DF 37 BE 3F 86 33 CA B0 EA 27 A5 95 A5 F8 1C A9 C5 46 41 EB DF C8 5F AD 85 7A 0E A8 AD A9 2A BF F3 6F 39 0D AE 60 30 B2 23 3C D0 37 85 18 01 2E 4E 74 0B 5D 98 2E 1E 3B 3F 30 DC CB DA 1E 0A 4F 0B 70 74 54 28 4F 82 6C 11 7E 5C 7E 33 C7 BB 47 29 2B F6 92 01 3F 83 AE 50 CC 6E B5 87 3B D4 F6 3A 6D 8D 0D 98 37 AB A6 08 79 EE E9 AB 38 37 FA 22 4C 54 80 1F 88 E9 E9 45 37 7A AF DB 61 A9 37 61 30 05 38 46 E4 CD ED B4 71 B2 C7 2E 1F 4C 92 27 C5 AF 3C D9 26 60 1F 4E 65 5E EF F7 A7 9C CC 49 F5 20 58 60 47 ED 44 DF EF FF AD 91 24 28 28 A4 03 F3 10 1B E5 18 0D 49 FA 68 A3 F2 BA 77 32 E4 16 35 66 8F 2C 8E 04 19 5A 26 AE 8C EB D1 C4 6F 0E 38 85 B7 3C 79 F4 98 29 35 FF DF 13 03 FE 36 D7 0A 20 3D 28 14 DE A1 D4 12 5B 6B D0 BF 53 4C AB 36 4E 3A FB 91 73 9C 39 F0 AB 10 1A 25 D6 D6 AC 2F 68 E5 33 67 23 EF 7A 97 70 2C F7 0B 67 0F A6 11 CB AB EF A9 3F 67 5B 8D 1B 39 C9 99 56 79 92 44 6E 1B 6F EE FE E9 08 9C 8B D6 5D 5A 8E 7B BD 61 A4 97 B2 78 75 98 5D C3 19 79 28 26 8B 00 32 D3 E1 3A 02 7F 12 D1 02 2C 5D 27 B3 F0 A6 8B 9D B1 01 01 EC AB 0F 6D D5 E4 0B B0 BD 54 9C 73 CD C0 AB F8 7E D4 D4 D3 3C E9 05 B3 30 30 3D C6 A4 70 EA 0B D1 47 CB 71 41 27 09 DA FE 4A 0F D2 1C 28 EF A6 3E 7A F6 05 A0 52 72 A3 C0 05 BC 8E 38 69 C5 16 AD 98 9D 96 4F FB 95 1D BD B7 12 26 AB 7D E2 EA 57 2C BB 1C 12 C9 FF 90 FB 6B 4F 3D FE 26 7D 4B FF A6 8D 4C D7 FA 4E ED B1 5F 5B 92 92 68 B5 25 0C BC 56 C7 AE 01 C4 05 9A A6 7E 97 93 4E 15 67 83 40 F7 45 8C F8 FB D8 C4 5A D0 94 15 AF 33 24 4A 4E 43 A6 B7 D4 AC 0C EB 39 C9 83 D3 E1 CE 36 6B AC CE FD 3C 92 2D 5D C2 6A 1C C4 54 21 4E 06 8B BB CB 7D B4 C2 FF 53 00 3C A4 47 98 AC 7E 29 AF B2 AB EB 25 1A 7E 3C E0 C6 DF 65 13 64 C1 94 EA 86 3F CD 54 E1 5E C5 95 3D F8 C0 A5 6B 28 CA 4F B4 5A E6 93 CE 49 5E AD CD A1 6E B8 94 9D C4 C3 0E 37 C4 10 A8 C0 47 17 C4 EE 3D 61 B5 80 ED EF 5B CC B4 49 69 10 4D E9 CD 22 B3 1B 1C 52 29 9D 6D B2 84 76 C3 CE 3C 23 39 0D 68 02 6B 1F 3F 28 DA 59 78 AE EA D8 F4 E0 1B 90 21 81 77 23 52 05 53 A1 BD E7 50 1C 24 26 9F 1D 39 E4 F2 A0 F8 7E F7 29 58 41 98 12 62 1A 23 B3 D9 A4 5C D3 15 0D 04 31 48 03 1B CC 5F A0 D1 A9 75 5C D0 FD 8A 9C FA 24 89 B2 C3 A9 C2 13 5B CD 1C F9 B1 63 C7 01 D7 BD 0D 43 2F CB 6C 4B 4F 0D
// 00 00 08 70 00 00 00 0A 01 00 00 00 00 0E 31 39 39 34 37 30 31 30 32 31 F5 45 50 03 B7 F7 99 8F DC CE F6 A2 35 08 04 85 D6 1D 52 90 24 13 86 A2 9D 40 D9 CD BF 4B 08 56 E7 EF 37 E6 E7 BE 09 FD A8 E5 D8 DA 07 90 E5 CB 22 1A 5A 77 88 B5 1A 0B 36 2A 71 59 1C 79 7C B1 84 39 CF 74 31 C5 ED 4D BB 12 F3 BB 10 B2 2E CD 05 82 86 AC 78 68 74 C3 42 9F CF F9 14 0D D4 2B 89 E9 FC 4D 1D 29 F3 08 A0 3A 62 F3 B5 71 D3 A9 06 BD 45 BA 50 D6 2D 68 05 B7 B4 D3 07 D0 01 A4 F4 71 0A 76 34 1F CA 2D 3A 53 6A C5 44 CA 56 C9 FA 0F 81 5E 06 63 45 9B BD FA 81 D3 50 46 74 34 C2 A8 21 9B 1B 25 E6 23 38 E5 87 B4 D2 A7 E7 59 65 03 BB 6D 46 D5 21 66 F6 2F 2D BF A3 77 2A 33 9D E1 35 18 45 CE 22 DB C1 52 BB 87 B9 F0 CB B1 CD 39 81 43 BD C1 E5 2B 81 DE 29 EC 72 2A 56 14 23 67 7B 60 F7 FB C1 7F 9C 18 8E ED 67 35 3E 2F EA D1 EA 24 AD 12 6D 65 B3 27 0C 2B 0A 43 42 3E 0C 81 C5 02 7D E6 A5 2C 79 8D 53 2D 06 F1 EE A5 51 BC 24 A6 F5 F2 0C BC 1F 42 F2 21 8F FB DF 9C 98 6F 25 FB D0 09 E1 F3 85 76 A2 96 39 5E 73 06 24 F8 1E 6C F7 D3 03 15 44 BA 6B 42 9E CE 14 7B 1A F9 0B A1 9A 85 FD 52 2B 34 FB 0F D8 6F 34 38 6E F3 A2 7D EB DF 3F 55 6A 52 27 35 44 5C 26 05 F3 36 8E 8F 00 D2 31 85 BF 20 8A 1C 37 57 C4 74 36 BF 89 3F 44 3C 97 AA 6B 8F D1 B6 CD D6 45 88 F1 74 35 CD 8B 85 9F 60 F4 B7 00 3E 87 10 C4 3F 7C 3F 22 F0 20 58 40 CE E6 77 8B 3D EE AA EB 31 52 65 BE C4 12 2B 28 65 1A 26 16 55 E9 86 28 90 42 FD 48 D6 6F E6 63 E2 40 3F BE 68 C6 FE A7 B2 10 31 15 7E B4 C7 2C 8D D9 04 8D AD 8E 45 D2 CA EC 07 D6 D0 14 FD 93 02 4B 3D 71 6E 3E 1F D5 BC ED 98 0E 01 6B FE 1C 96 24 34 DF A3 E3 EE 67 40 F3 C7 AA 10 4E 44 62 49 D5 45 14 15 49 04 2F 9F FC 5D 40 F7 5A CC C1 78 7B 37 35 80 F9 10 80 EB 40 DB 33 06 5F 2A 70 88 F0 94 49 59 48 4B 00 66 28 E9 E9 E7 CE E4 CA 6D 21 79 09 62 7A 6E C5 47 A4 08 85 73 43 35 2D EE E4 0E 85 47 92 B4 F1 5C 76 C2 72 BC D1 70 41 6D 9B EE F4 47 67 1F 63 57 B9 65 C1 08 5C 42 D6 28 FB 6F F5 1A 4B E0 B7 5A 36 75 E6 BE ED C6 67 DA 64 19 09 11 CF 9A 74 4A F4 4E 4F 1E 02 2C 8C 21 21 DE 76 15 34 E5 F2 DF F9 34 31 99 4F 4B B2 5E E6 2B 8D 7C 64 E9 7D 78 98 4F 28 FF 2E 95 1B 5D 8E 2F 70 E6 01 0A 82 18 90 16 8F 98 5E 0F CA 30 4F 36 AF 9B 5E 2B 5B FE 59 5E 11 BC A5 68 64 55 BD 04 CE 43 60 4C C9 CB F7 88 D2 30 7A 89 75 3D 93 9D A9 D0 CE 7D 4B CE 4D 14 5E 95 0E 18 3E 75 AE 20 C6 8A 6E 15 F9 39 58 3B 17 74 99 98 07 5D 68 B1 51 57 AF 1D 85 F1 A5 8A FE 9F 07 BC CB B9 84 A5 49 AE 9F F4 50 06 27 24 7F EB 66 C0 F7 C4 4F E9 74 FA 69 8E D0 A6 A4 3E 8A A8 D9 10 A1 05 03 0F B1 E7 80 22 A9 21 22 FA 31 A1 61 0E 5A 42 75 5F 19 95 2E FE A9 38 51 BB E9 C1 6B 29 CD AE 8F 78 7C 1F A4 81 F2 20 D3 15 C1 EA 42 BD 5F 52 C1 BA 5F C7 42 97 A8 F1 FA C6 20 82 3C 00 36 96 75 69 27 FE 93 AA BD 43 BD 0E FD ED 30 97 A6 B2 A2 E8 D3 75 C2 BF 35 EC 78 8A 3E 23 9D 6D DD 3C D4 4A BC 5A A8 74 86 3C A7 31 F5 F3 8A 78 9C 3C 75 88 B1 35 4A 83 91 EB 5F 80 F3 E0 0C EC 82 5C 7B 08 61 45 E3 3B 7B F1 1F BC 6D 5E 99 3A 34 68 28 20 42 8C 42 C9 0A 3F 32 42 03 E5 9A 71 BB E1 02 C9 B4 98 6E 73 7E EC 81 79 28 01 A8 E5 AC 0F 24 0A 58 DA C1 D2 F0 2C 94 E7 4D E5 ED B3 43 58 23 73 1D 7F 33 B0 7B 1A A8 C1 AC 6E 7C F1 A6 51 0F CF E9 51 5F 06 EB 79 C4 0C E9 78 6C B8 B8 11 C0 2E 84 BC F4 4D 05 D5 B5 90 20 30 BE 73 28 83 91 3B 4D 90 2E 8F A5 A8 BF 85 63 29 05 04 33 14 7D 24 24 7D 02 9B 39 5D 30 D0 68 58 57 1A 0D 67 A6 EF 44 4C 4E 92 14 0A 2A E4 24 1E 60 78 A3 65 71 7E E3 B2 44 E1 55 3E F2 08 05 F5 59 5E EE D3 0A 12 34 C2 FC 74 4A 8C F9 BE 7F 4D EC 9E D3 14 97 7F DF 75 E2 52 21 95 65 99 F4 1D 01 AD F4 D2 4D 8C 9E 5A 16 DE 65 AA D0 AC 24 17 FE BE B9 D8 9B FB 36 33 E5 AE 1B F9 B1 AE A4 9B 15 94 91 6D 45 BE 61 33 4B 71 40 BC DB D0 BF 06 39 83 D5 5F 30 6D E0 20 D3 33 AA 78 13 DA 9A 80 A3 38 4F 3B F8 AE B9 7F 9B B7 F1 AD 10 88 96 DD 79 DD F8 86 A3 72 A2 3F C2 6E B2 6D CE 36 54 90 5F DE 23 90 CD BD BD DB 95 83 5A 94 8E B8 54 AF 0A AB 10 0C 15 B3 3D 2B 89 7D 83 64 B9 29 08 50 40 6E F6 EC 8D E7 79 6C 2B 70 A5 07 FA AD 6A A1 54 EC D7 C7 70 A6 9F 8F 8E 5B 00 5E 8D 27 0D 21 8B 38 31 02 88 13 6E F4 5C 8D 15 82 FC 3E AE 57 17 3D 6D 38 F9 8C 2B EF 87 FA 30 FB 59 D4 E2 49 CF 76 75 9C 9D 50 8D 4A CD AE F6 3C 59 E8 92 BB C1 E2 5C F6 96 8B DC 78 DF E1 27 6B F1 1C D9 68 1D 29 8A E3 09 DD 28 C7 0A ED BB 75 6B D9 87 9F 7F 71 5D D0 EE 03 5B 28 52 40 26 DD C9 C4 52 4D 58 02 3A 71 BE 6C F4 6A 30 14 52 72 CB 45 95 80 DE 28 02 8A 22 7A 05 B5 D7 22 61 06 E0 34 09 AC A9 A8 A8 D0 DF 37 BE 3F 86 33 CA B0 EA 27 A5 95 A5 F8 1C A9 C5 46 41 EB DF C8 5F AD 85 7A 0E A8 AD A9 2A BF F3 6F 39 0D AE 60 30 B2 23 3C D0 37 85 18 01 2E 4E 74 0B 5D 98 2E 1E 3B 3F 30 DC CB DA 1E 0A 4F 0B 70 74 54 28 4F 82 6C 11 7E 5C 7E 33 C7 BB 47 29 2B F6 92 01 3F 83 AE 50 CC 6E B5 87 3B D4 F6 3A 6D 8D 0D 98 37 AB A6 08 79 EE E9 AB 38 37 FA 22 4C 54 80 1F 88 E9 E9 45 37 7A AF DB 61 A9 37 61 30 05 38 46 E4 CD ED B4 71 B2 C7 2E 1F 4C 92 27 C5 AF 3C D9 26 60 1F 4E 65 5E EF F7 A7 9C CC 49 F5 20 58 60 47 ED 44 DF EF FF AD 91 24 28 28 A4 03 F3 10 1B E5 18 0D 49 FA 68 A3 F2 BA 77 32 E4 16 35 66 8F 2C 8E 04 19 5A 26 AE 8C EB D1 C4 6F 0E 38 85 B7 3C 79 F4 98 29 35 FF DF 13 03 FE 36 D7 0A 20 3D 28 14 DE A1 D4 12 5B 6B D0 BF 53 4C AB 36 4E 3A FB 91 73 9C 39 F0 AB 10 1A 25 D6 D6 AC 2F 68 E5 33 67 23 EF 7A 97 70 2C F7 0B 67 0F A6 11 CB AB EF A9 3F 67 5B 8D 1B 39 C9 99 56 79 92 44 6E 1B 6F EE FE E9 08 9C 8B D6 5D 5A 8E 7B BD 61 A4 97 B2 78 75 98 5D C3 19 79 28 26 8B 00 32 D3 E1 3A 02 7F 12 D1 02 2C 5D 27 B3 F0 A6 8B 9D B1 01 01 EC AB 0F 6D D5 E4 0B B0 BD 54 9C 73 CD C0 AB F8 7E D4 D4 D3 3C E9 05 B3 30 30 3D C6 A4 70 EA 0B D1 47 CB 71 41 27 09 DA FE 4A 0F D2 1C 28 EF A6 3E 7A F6 05 A0 52 72 A3 C0 05 BC 8E 38 69 C5 16 AD 98 9D 96 4F FB 95 1D BD B7 12 26 AB 7D E2 EA 57 2C BB 1C 12 C9 FF 90 FB 6B 4F 3D FE 26 7D 4B FF A6 8D 4C D7 FA 4E ED B1 5F 5B 92 92 68 B5 25 0C BC 56 C7 AE 01 C4 05 9A A6 7E 97 93 4E 15 67 83 40 F7 45 8C F8 FB D8 C4 5A D0 94 15 AF 33 24 4A 4E 43 A6 B7 D4 AC 0C EB 39 C9 83 D3 E1 CE 36 6B AC CE FD 3C 92 2D 5D C2 6A 1C C4 54 21 4E 06 8B BB CB 7D B4 C2 FF 53 00 3C A4 47 98 AC 7E 29 AF B2 AB EB 25 1A 7E 3C E0 C6 DF 65 13 64 C1 94 EA 86 3F CD 54 E1 5E C5 95 3D F8 C0 A5 6B 28 CA 4F B4 5A E6 93 CE 49 5E AD CD A1 6E B8 94 9D C4 C3 0E 37 C4 10 A8 C0 47 17 C4 EE 3D 61 B5 80 ED EF 5B CC B4 49 69 10 4D E9 CD 22 B3 1B 1C 52 29 9D 6D B2 84 76 C3 CE 3C 23 39 0D 68 02 6B 1F 3F 28 DA 59 78 AE EA D8 F4 E0 1B 90 21 81 77 23 52 05 53 A1 BD E7 50 1C 24 26 9F 1D 39 E4 F2 A0 F8 7E F7 29 58 41 98 12 62 1A 23 B3 D9 A4 5C D3 15 0D 04 31 48 03 1B CC 5F A0 D1 A9 75 5C D0 FD 8A 9C FA 24 89 B2 C3 A9 C2 13 5B CD 1C F9 B1 63 C7 01 D7 BD 0D 43 2F CB 6C 4B 4F 0D
// 00 00 08 E0 00 00 00 0A 01 00 00 00 00 0E 31 39 39 34 37 30 31 30 32 31 B4 16 A6 D7 A3 E4 9E 53 99 CD 77 14 70 1F 51 3E 8B 79 F6 93 2B E0 92 E4 32 E2 87 6C 3A 9C 1B 29 87 CB 3C 60 45 9C 41 71 63 6A F6 99 FC 05 01 68 86 B3 6F 37 97 52 C5 D3 0E 66 B3 F6 40 CC EB 18 A3 AE 15 3E 31 B1 E9 7C 6F EC E4 4D 31 F1 1E 2C 0C 1C 45 66 CD F7 1B 90 11 9A D8 CE DD 6D 6C 63 9F EB CD 69 33 AF 6C 8E BA 8C CB C3 FF 27 A2 A6 C3 28 06 4A B5 79 79 12 AB 52 04 62 CA 7D 11 59 85 5C 0B D6 8D 2A E7 9C 04 97 62 7D 05 11 3E 2C 11 60 E3 E3 B3 DA 7A 7C 13 AF 22 01 53 80 69 D0 F9 C8 86 EC 25 8C F3 67 5C 82 45 08 FB 34 43 50 01 0E EA 43 77 D8 CF EC 55 E6 4E 66 5B 26 21 C9 E8 78 92 AE 5C 61 F0 5E 0B E7 34 1F 53 D6 EA 28 9C 02 1A E9 F0 55 61 4B 06 F8 56 3B AC 93 B2 2C CD 66 0D D1 18 CB BD 29 50 DE 0F 82 6D 28 63 AB 21 E1 6C BA B1 9F 69 A4 E3 C9 20 F8 11 82 39 04 2B 54 44 50 FA 2E 86 68 6D DC 5D 9E 18 F4 DD 19 09 BC CF E8 41 68 A3 8D 86 42 80 51 C4 C1 ED 54 DB 50 F5 1D A7 28 2A 0D E8 14 1A 4E F7 96 29 00 6C 9D 4A 2E 3E 7B 4C AC 20 78 F1 3C 70 6B 61 96 D7 EC 77 AD CB AD AF BB 47 C3 1F A0 6C 6C 9C 9F F3 6C EB 6C A4 D0 7F 2B E1 AA 68 26 99 B9 C8 A1 F5 C4 7E E7 E7 81 EE 66 00 96 33 49 C0 EE A2 F9 F6 52 C5 A6 5D EE 9D C5 E5 CE DA 31 FC FF 4B 02 97 68 3D 6A 99 4A CF 69 D9 F4 53 68 31 E7 32 2F 85 E7 7F 16 82 AE FA 73 D5 42 09 9C CB 53 26 79 41 63 80 B0 E2 6A 8B B9 C6 71 08 B4 2B E0 48 D3 C4 0F B0 00 D0 FA 8C 29 DE E9 71 6A D7 89 76 E7 5D 33 14 10 6F E2 44 6A A0 DC C1 CB F3 9A C3 13 CB D1 82 2C DF 34 68 79 E3 09 BD CC 2B 25 79 A8 E7 BE 29 6C 97 C3 D7 F4 0E CC 2B 74 71 02 BA 2B 5B 57 1B C2 C8 C2 BF 54 23 72 EA E4 38 54 20 7D 88 E4 39 7C C5 8A 1B C0 EC D2 1E 7D 1B 6B 7A BC EC 73 1E 53 4A 6F 4F EA F0 56 12 80 BD 0B 37 67 BD FD A8 29 23 2D 8E 66 7E 31 A9 F6 CE 7E BC 4F 38 D0 33 D4 C7 4A E9 43 9D 28 2E 8F 7C D5 81 F4 8C F9 6F 21 AC A1 08 FD F4 01 FB E8 CE 61 91 BE 68 5B E4 3A 5F F8 FB DA 5D 9B 2A AF E2 0C D3 A4 1F 42 90 96 E1 28 44 85 8D E1 CF 19 A9 47 04 8D 28 D9 B3 35 79 48 70 D9 ED 45 B6 24 B5 56 FA 1E DE 02 F3 EB 69 08 7D 24 9C 60 35 97 8D 13 4A 5A 57 BA B3 14 C1 EE 70 22 CA B2 65 F7 BB 3F A2 D9 14 AA 4C 52 E6 E4 10 D3 FD C6 2B DD BF C0 CF E5 35 57 9E 9F D0 77 C8 E6 EF 2B 8E 01 88 96 F8 68 95 A7 0D 58 81 30 60 88 44 CC 31 5B C1 D4 92 6E ED 17 CA 0A 01 69 90 4E 6A C0 D7 09 6C E5 33 64 CA 6E 5C 07 C3 AD 46 36 F9 DF DE B7 71 B2 87 CB 3D 76 C0 44 B8 6B 15 27 B2 03 99 C7 51 8A 00 35 C9 1C 76 55 32 AE 49 5A 34 6A 4E FD 20 7A 24 BF 34 E8 B4 18 BC 92 64 A1 F3 0A 2E 7B 00 EA B6 52 E7 AC 34 FD AE FF 1E 5D 6D D6 1F 6D 06 31 09 9D A9 9C 86 DB 5E 05 07 BA 4A 49 2B D2 7F EE 88 64 B2 6F 15 70 39 1B E9 57 6A 4E 29 4A A4 57 EA 80 3D 86 4C E9 F7 F5 2B C4 9F 35 62 76 09 0E 1C A4 99 50 99 82 2F 84 90 0E 9E 9F 75 C3 15 B0 61 34 D1 67 2D 30 16 FE D3 BF 59 6A B1 74 02 C4 EF 92 85 E0 16 4B 0C C5 9D 65 BB 5D 52 8F 52 5B 7C 7B 74 D9 EC 41 A9 5B FA 2D 95 D4 AE 5D F1 68 88 F6 82 ED 09 05 21 2E 5D 93 64 A0 96 15 64 A6 50 3C 03 2B FC 3E 80 89 90 62 CC D9 23 8E D7 BD 05 02 30 86 32 31 6A 5F F8 C4 BD 61 D0 CE B9 54 4E 93 E9 AE B9 4F 2B 98 DC 23 31 CC A8 06 89 A8 08 60 99 DC D4 81 98 13 C9 27 36 32 24 C1 B0 6B F0 3D EB CC 3B 32 5F 20 72 23 B3 DF 0B 48 3C 35 FD F1 FB DC 3E 2A BE B9 0F 42 56 F1 39 94 86 85 C6 1E A0 4C EC B8 69 45 5F 3D AB 3C 3B A2 70 61 91 9D 2C DD 6D C5 E9 EF 47 36 A6 A3 E0 96 C2 B8 EF 92 E9 E0 26 88 C6 B5 51 BA DE FD C5 BA 4C 6A 9A FE 6F DE B8 10 05 7F 9C 5D 40 11 39 75 CD 36 4F 6B A8 A1 94 57 5F 8F F2 D0 E2 36 A0 A4 24 05 FD 9E F5 51 93 C9 6E 5A 10 8D C3 33 2D E5 09 7A E0 DB 44 63 9C EA A5 ED BF 0B 98 32 F1 BA 04 96 F6 14 49 F1 F8 58 EA 6E 5E 5E 49 CA 2D E2 93 E6 AD 20 B2 CD 98 A7 3E BA 3E A8
// 00 00 08 E0 00 00 00 0A 01 00 00 00 00 0E 31 39 39 34 37 30 31 30 32 31 B4 16 A6 D7 A3 E4 9E 53 99 CD 77 14 70 1F 51 3E 8B 79 F6 93 2B E0 92 E4 32 E2 87 6C 3A 9C 1B 29 87 CB 3C 60 45 9C 41 71 63 6A F6 99 FC 05 01 68 86 B3 6F 37 97 52 C5 D3 0E 66 B3 F6 40 CC EB 18 A3 AE 15 3E 31 B1 E9 7C 6F EC E4 4D 31 F1 1E 2C 0C 1C 45 66 CD F7 1B 90 11 9A D8 CE DD 6D 6C 63 9F EB CD 69 33 AF 6C 8E BA 8C CB C3 FF 27 A2 A6 C3 28 06 4A B5 79 79 12 AB 52 04 62 CA 7D 11 59 85 5C 0B D6 8D 2A E7 9C 04 97 62 7D 05 11 3E 2C 11 60 E3 E3 B3 DA 7A 7C 13 AF 22 01 53 80 69 D0 F9 C8 86 EC 25 8C F3 67 5C 82 45 08 FB 34 43 50 01 0E EA 43 77 D8 CF EC 55 E6 4E 66 5B 26 21 C9 E8 78 92 AE 5C 61 F0 5E 0B E7 34 1F 53 D6 EA 28 9C 02 1A E9 F0 55 61 4B 06 F8 56 3B AC 93 B2 2C CD 66 0D D1 18 CB BD 29 50 DE 0F 82 6D 28 63 AB 21 E1 6C BA B1 9F 69 A4 E3 C9 20 F8 11 82 39 04 2B 54 44 50 FA 2E 86 68 6D DC 5D 9E 18 F4 DD 19 09 BC CF E8 41 68 A3 8D 86 42 80 51 C4 C1 ED 54 DB 50 F5 1D A7 28 2A 0D E8 14 1A 4E F7 96 29 00 6C 9D 4A 2E 3E 7B 4C AC 20 78 F1 3C 70 6B 61 96 D7 EC 77 AD CB AD AF BB 47 C3 1F A0 6C 6C 9C 9F F3 6C EB 6C A4 D0 7F 2B E1 AA 68 26 99 B9 C8 A1 F5 C4 7E E7 E7 81 EE 66 00 96 33 49 C0 EE A2 F9 F6 52 C5 A6 5D EE 9D C5 E5 CE DA 31 FC FF 4B 02 97 68 3D 6A 99 4A CF 69 D9 F4 53 68 31 E7 32 2F 85 E7 7F 16 82 AE FA 73 D5 42 09 9C CB 53 26 79 41 63 80 B0 E2 6A 8B B9 C6 71 08 B4 2B E0 48 D3 C4 0F B0 00 D0 FA 8C 29 DE E9 71 6A D7 89 76 E7 5D 33 14 10 6F E2 44 6A A0 DC C1 CB F3 9A C3 13 CB D1 82 2C DF 34 68 79 E3 09 BD CC 2B 25 79 A8 E7 BE 29 6C 97 C3 D7 F4 0E CC 2B 74 71 02 BA 2B 5B 57 1B C2 C8 C2 BF 54 23 72 EA E4 38 54 20 7D 88 E4 39 7C C5 8A 1B C0 EC D2 1E 7D 1B 6B 7A BC EC 73 1E 53 4A 6F 4F EA F0 56 12 80 BD 0B 37 67 BD FD A8 29 23 2D 8E 66 7E 31 A9 F6 CE 7E BC 4F 38 D0 33 D4 C7 4A E9 43 9D 28 2E 8F 7C D5 81 F4 8C F9 6F 21 AC A1 08 FD F4 01 FB E8 CE 61 91 BE 68 5B E4 3A 5F F8 FB DA 5D 9B 2A AF E2 0C D3 A4 1F 42 90 96 E1 28 44 85 8D E1 CF 19 A9 47 04 8D 28 D9 B3 35 79 48 70 D9 ED 45 B6 24 B5 56 FA 1E DE 02 F3 EB 69 08 7D 24 9C 60 35 97 8D 13 4A 5A 57 BA B3 14 C1 EE 70 22 CA B2 65 F7 BB 3F A2 D9 14 AA 4C 52 E6 E4 10 D3 FD C6 2B DD BF C0 CF E5 35 57 9E 9F D0 77 C8 E6 EF 2B 8E 01 88 96 F8 68 95 A7 0D 58 81 30 60 88 44 CC 31 5B C1 D4 92 6E ED 17 CA 0A 01 69 90 4E 6A C0 D7 09 6C E5 33 64 CA 6E 5C 07 C3 AD 46 36 F9 DF DE B7 71 B2 87 CB 3D 76 C0 44 B8 6B 15 27 B2 03 99 C7 51 8A 00 35 C9 1C 76 55 32 AE 49 5A 34 6A 4E FD 20 7A 24 BF 34 E8 B4 18 BC 92 64 A1 F3 0A 2E 7B 00 EA B6 52 E7 AC 34 FD AE FF 1E 5D 6D D6 1F 6D 06 31 09 9D A9 9C 86 DB 5E 05 07 BA 4A 49 2B D2 7F EE 88 64 B2 6F 15 70 39 1B E9 57 6A 4E 29 4A A4 57 EA 80 3D 86 4C E9 F7 F5 2B C4 9F 35 62 76 09 0E 1C A4 99 50 99 82 2F 84 90 0E 9E 9F 75 C3 15 B0 61 34 D1 67 2D 30 16 FE D3 BF 59 6A B1 74 02 C4 EF 92 85 E0 16 4B 0C C5 9D 65 BB 5D 52 8F 52 5B 7C 7B 74 D9 EC 41 A9 5B FA 2D 95 D4 AE 5D F1 68 88 F6 82 ED 09 05 21 2E 5D 93 64 A0 96 15 64 A6 50 3C 03 2B FC 3E 80 89 90 62 CC D9 23 8E D7 BD 05 02 30 86 32 31 6A 5F F8 C4 BD 61 D0 CE B9 54 4E 93 E9 AE B9 4F 2B 98 DC 23 31 CC A8 06 89 A8 08 60 99 DC D4 81 98 13 C9 27 36 32 24 C1 B0 6B F0 3D EB CC 3B 32 5F 20 72 23 B3 DF 0B 48 3C 35 FD F1 FB DC 3E 2A BE B9 0F 42 56 F1 39 94 86 85 C6 1E A0 4C EC B8 69 45 5F 3D AB 3C 3B A2 70 61 91 9D 2C DD 6D C5 E9 EF 47 36 A6 A3 E0 96 C2 B8 EF 92 E9 E0 26 88 C6 B5 51 BA DE FD C5 BA 4C 6A 9A FE 6F DE B8 10 05 7F 9C 5D 40 11 39 75 CD 36 4F 6B A8 A1 94 57 5F 8F F2 D0 E2 36 A0 A4 24 05 FD 9E F5 51 93 C9 6E 5A 10 8D C3 33 2D E5 09 7A E0 DB 44 63 9C EA A5 ED BF 0B 98 32 F1 BA 04 96 F6 14 49 F1 F8 58 EA 6E 5E 5E 49 CA 2D E2 93 E6 AD 20 B2 CD 98 A7 3E BA 3E A8
...
@@ -139,15 +196,23 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
...
@@ -139,15 +196,23 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
when
(
flag2
)
{
when
(
flag2
)
{
1
->
//it.data.parseUniResponse(bot, it.packetFactory, it.sequenceId, consumer)
1
->
//it.data.parseUniResponse(bot, it.packetFactory, it.sequenceId, consumer)
{
when
(
it
.
packetFactory
)
{
consumer
(
is
OutgoingPacketFactory
<
*
>
->
consumer
(
it
.
packetFactory
as
PacketFactory
<
T
>,
it
.
packetFactory
as
Outgoing
PacketFactory
<
T
>,
it
.
packetFactory
.
run
{
decode
(
bot
,
it
.
data
)
},
it
.
packetFactory
.
run
{
decode
(
bot
,
it
.
data
)
},
it
.
packetFactory
.
commandName
,
it
.
packetFactory
.
commandName
,
it
.
sequenceId
it
.
sequenceId
)
)
is
IncomingPacketFactory
<
*
>
->
consumer
(
it
.
packetFactory
as
IncomingPacketFactory
<
T
>,
it
.
packetFactory
.
run
{
decode
(
bot
,
it
.
data
,
it
.
sequenceId
)
},
it
.
packetFactory
.
receivingCommandName
,
it
.
sequenceId
)
}
}
2
->
it
.
data
.
parseOicqResponse
(
bot
,
it
.
packetFactory
as
PacketFactory
<
T
>,
it
.
sequenceId
,
consumer
)
// for oicq response, factory is always OutgoingPacketFactory
2
->
it
.
data
.
parseOicqResponse
(
bot
,
it
.
packetFactory
as
OutgoingPacketFactory
<
T
>,
it
.
sequenceId
,
consumer
)
else
->
error
(
"unknown flag2: $flag2. Body to be parsed for inner packet=${it.data.readBytes().toUHexString()}"
)
else
->
error
(
"unknown flag2: $flag2. Body to be parsed for inner packet=${it.data.readBytes().toUHexString()}"
)
}
}
}
?:
inline
{
}
?:
inline
{
...
@@ -160,22 +225,6 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
...
@@ -160,22 +225,6 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
private
inline
fun
<
R
>
inline
(
block
:
()
->
R
):
R
=
block
()
private
inline
fun
<
R
>
inline
(
block
:
()
->
R
):
R
=
block
()
private
fun
parseUniFrame
(
bot
:
QQAndroidBot
,
rawInput
:
ByteReadPacket
):
IncomingPacket
=
rawInput
.
debugIfFail
(
"uni packet"
)
{
readIoBuffer
(
readInt
()
-
4
).
withUse
{
//00 01 4E 64 FF FF D8 E8 00 00 00 14 6E 65 65 64 20 41 32 20 61 6E 64 20 49 4D 45 49 00 00 00 04 00 00 00 08 60 7F B6 23 00 00 00 00 00 00 00 04
val
sequenceId
=
readInt
()
}
// TODO: 2020/1/24
readIoBuffer
(
readInt
()
-
4
).
withUse
{
debugPrintln
(
"收到 UniPacket 的 body=${this.readBytes().toUHexString()}"
)
}
return
IncomingPacket
(
null
,
0
,
TODO
())
}
class
IncomingPacket
(
class
IncomingPacket
(
val
packetFactory
:
PacketFactory
<
*
>?,
val
packetFactory
:
PacketFactory
<
*
>?,
val
sequenceId
:
Int
,
val
sequenceId
:
Int
,
...
@@ -227,7 +276,7 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
...
@@ -227,7 +276,7 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
private
suspend
fun
<
T
:
Packet
>
ByteReadPacket
.
parseOicqResponse
(
private
suspend
fun
<
T
:
Packet
>
ByteReadPacket
.
parseOicqResponse
(
bot
:
QQAndroidBot
,
bot
:
QQAndroidBot
,
packetFactory
:
PacketFactory
<
T
>,
packetFactory
:
Outgoing
PacketFactory
<
T
>,
ssoSequenceId
:
Int
,
ssoSequenceId
:
Int
,
consumer
:
PacketConsumer
<
T
>
consumer
:
PacketConsumer
<
T
>
)
{
)
{
...
@@ -276,16 +325,6 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
...
@@ -276,16 +325,6 @@ internal object KnownPacketFactories : List<PacketFactory<*>> by mutableListOf(
}
}
}
}
private
suspend
fun
ByteReadPacket
.
parseUniResponse
(
bot
:
QQAndroidBot
,
packetFactory
:
PacketFactory
<
*
>,
ssoSequenceId
:
Int
,
consumer
:
PacketConsumer
<
Packet
>
)
{
val
uni
=
readBytes
(
readInt
()
-
4
).
loadAs
(
RequestPacket
.
serializer
())
PacketLogger
.
verbose
(
uni
.
toString
())
/// consumer(packetFactory.decode(bot, uni.sBuffer.toReadPacket()), uni.sServantName + "." + uni.sFuncName, ssoSequenceId)
}
}
}
@UseExperimental
(
ExperimentalContracts
::
class
)
@UseExperimental
(
ExperimentalContracts
::
class
)
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImageDownPacket.kt
View file @
63a4d5f3
...
@@ -2,18 +2,18 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image
...
@@ -2,18 +2,18 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.writeFully
import
kotlinx.io.core.writeFully
import
net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
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.data.proto.Cmd0x352Packet
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352Packet
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.GetImgUrlReq
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.GetImgUrlReq
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildLoginOutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.writeSsoPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.writeSsoPacket
internal
object
ImageDownPacket
:
PacketFactory
<
ImageDownPacket
.
ImageDownPacketResponse
>(
"LongConn.OffPicDown"
)
{
internal
object
ImageDownPacket
:
Outgoing
PacketFactory
<
ImageDownPacket
.
ImageDownPacketResponse
>(
"LongConn.OffPicDown"
)
{
operator
fun
invoke
(
client
:
QQAndroidClient
,
req
:
GetImgUrlReq
):
OutgoingPacket
{
operator
fun
invoke
(
client
:
QQAndroidClient
,
req
:
GetImgUrlReq
):
OutgoingPacket
{
// TODO: 2020/1/24 测试: bodyType, subAppId
// TODO: 2020/1/24 测试: bodyType, subAppId
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImageUpPacket.kt
View file @
63a4d5f3
...
@@ -2,18 +2,18 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image
...
@@ -2,18 +2,18 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.writeFully
import
kotlinx.io.core.writeFully
import
net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
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.data.proto.Cmd0x352Packet
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352Packet
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.UploadImgReq
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.UploadImgReq
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildLoginOutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.writeSsoPacket
internal
object
ImageUpPacket
:
PacketFactory
<
ImageUpPacket
.
ImageUpPacketResponse
>(
"LongConn.OffPicUp"
)
{
internal
object
ImageUpPacket
:
Outgoing
PacketFactory
<
ImageUpPacket
.
ImageUpPacketResponse
>(
"LongConn.OffPicUp"
)
{
operator
fun
invoke
(
client
:
QQAndroidClient
,
req
:
UploadImgReq
):
OutgoingPacket
{
operator
fun
invoke
(
client
:
QQAndroidClient
,
req
:
UploadImgReq
):
OutgoingPacket
{
// TODO: 2020/1/24 测试: bodyType, subAppId
// TODO: 2020/1/24 测试: bodyType, subAppId
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
View file @
63a4d5f3
...
@@ -19,9 +19,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
...
@@ -19,9 +19,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgComm
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgComm
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.SyncCookie
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.SyncCookie
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
import
net.mamoe.mirai.qqandroid.utils.toMessageChain
import
net.mamoe.mirai.qqandroid.utils.toMessageChain
import
net.mamoe.mirai.qqandroid.utils.toRichTextElems
import
net.mamoe.mirai.qqandroid.utils.toRichTextElems
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.MiraiInternalAPI
...
@@ -36,19 +34,18 @@ internal class MessageSvc {
...
@@ -36,19 +34,18 @@ internal class MessageSvc {
/**
/**
* 告知要刷新好友消息
* 告知要刷新好友消息
*/
*/
internal
object
PushNotify
:
PacketFactory
<
RequestPushNotify
>(
"MessageSvc.PushNotify"
)
{
internal
object
PushNotify
:
Incoming
PacketFactory
<
RequestPushNotify
>(
"MessageSvc.PushNotify"
)
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
RequestPushNotify
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
RequestPushNotify
{
discardExact
(
8
)
discardExact
(
8
)
return
decodeUniPacket
(
RequestPushNotify
.
serializer
())
return
decodeUniPacket
(
RequestPushNotify
.
serializer
())
}
}
override
suspend
fun
QQAndroidBot
.
handle
(
packet
:
RequestPushNotify
)
{
override
suspend
fun
QQAndroidBot
.
handle
(
packet
:
RequestPushNotify
,
sequenceId
:
Int
):
OutgoingPacket
?
{
network
.
run
{
network
.
run
{
PbGetMsg
(
client
,
MsgSvc
.
SyncFlag
.
START
,
packet
.
stMsgInfo
?.
uMsgTime
?:
0
).
sendAndExpect
<
MultiPacket
<
FriendMessage
>>(
)
return
PbGetMsg
(
client
,
MsgSvc
.
SyncFlag
.
START
,
packet
.
stMsgInfo
?.
uMsgTime
?:
0
)
}
}
}
}
}
}
...
@@ -56,7 +53,7 @@ internal class MessageSvc {
...
@@ -56,7 +53,7 @@ internal class MessageSvc {
* 获取好友消息和消息记录
* 获取好友消息和消息记录
*/
*/
@UseExperimental
(
MiraiInternalAPI
::
class
)
@UseExperimental
(
MiraiInternalAPI
::
class
)
internal
object
PbGetMsg
:
PacketFactory
<
PbGetMsg
.
Response
>(
"MessageSvc.PbGetMsg"
)
{
internal
object
PbGetMsg
:
Outgoing
PacketFactory
<
PbGetMsg
.
Response
>(
"MessageSvc.PbGetMsg"
)
{
val
EXTRA_DATA
=
val
EXTRA_DATA
=
"08 00 12 33 6D 6F 64 65 6C 3A 78 69 67 6F 6D 69 20 36 3B 6F 73 3A 32 32 3B 76 65 72 73 69 6F 6E 3A 76 32 6D 61 6E 3A 78 69 61 6F 6D 69 73 79 73 3A 4C 4D 59 34 38 5A 18 E4 E1 A4 FF FE 2D 20 E9 E1 A4 FF FE 2D 28 A8 E1 A4 FF FE 2D 30 99 E1 A4 FF FE 2D"
.
hexToBytes
()
"08 00 12 33 6D 6F 64 65 6C 3A 78 69 67 6F 6D 69 20 36 3B 6F 73 3A 32 32 3B 76 65 72 73 69 6F 6E 3A 76 32 6D 61 6E 3A 78 69 61 6F 6D 69 73 79 73 3A 4C 4D 59 34 38 5A 18 E4 E1 A4 FF FE 2D 20 E9 E1 A4 FF FE 2D 28 A8 E1 A4 FF FE 2D 30 99 E1 A4 FF FE 2D"
.
hexToBytes
()
...
@@ -81,7 +78,7 @@ internal class MessageSvc {
...
@@ -81,7 +78,7 @@ internal class MessageSvc {
syncFlag
=
syncFlag
,
syncFlag
=
syncFlag
,
// serverBuf = from.serverBuf ?: EMPTY_BYTE_ARRAY,
// serverBuf = from.serverBuf ?: EMPTY_BYTE_ARRAY,
syncCookie
=
client
.
c2cMessageSync
.
syncCookie
syncCookie
=
client
.
c2cMessageSync
.
syncCookie
?:
SyncCookie
(
time
=
Random
.
nextLong
()
).
toByteArray
(
SyncCookie
.
serializer
())
//.also { client.c2cMessageSync.syncCookie = it },
?:
SyncCookie
(
time
=
msgTime
+
client
.
timeDifference
).
toByteArray
(
SyncCookie
.
serializer
())
//.also { client.c2cMessageSync.syncCookie = it },
// syncFlag = client.c2cMessageSync.syncFlag,
// syncFlag = client.c2cMessageSync.syncFlag,
//msgCtrlBuf = client.c2cMessageSync.msgCtrlBuf,
//msgCtrlBuf = client.c2cMessageSync.msgCtrlBuf,
//pubaccountCookie = client.c2cMessageSync.pubAccountCookie
//pubaccountCookie = client.c2cMessageSync.pubAccountCookie
...
@@ -160,7 +157,7 @@ internal class MessageSvc {
...
@@ -160,7 +157,7 @@ internal class MessageSvc {
/**
/**
* 被挤下线
* 被挤下线
*/
*/
internal
object
PushForceOffline
:
PacketFactory
<
ForceOfflineEvent
>(
"MessageSvc.PushForceOffline"
)
{
internal
object
PushForceOffline
:
Outgoing
PacketFactory
<
ForceOfflineEvent
>(
"MessageSvc.PushForceOffline"
)
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
ForceOfflineEvent
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
ForceOfflineEvent
{
discardExact
(
4
)
discardExact
(
4
)
val
struct
=
this
.
decodeUniPacket
(
RequestPushForceOffline
.
serializer
())
val
struct
=
this
.
decodeUniPacket
(
RequestPushForceOffline
.
serializer
())
...
@@ -168,7 +165,7 @@ internal class MessageSvc {
...
@@ -168,7 +165,7 @@ internal class MessageSvc {
}
}
}
}
internal
object
PbSendMsg
:
PacketFactory
<
PbSendMsg
.
Response
>(
"MessageSvc.PbSendMsg"
)
{
internal
object
PbSendMsg
:
Outgoing
PacketFactory
<
PbSendMsg
.
Response
>(
"MessageSvc.PbSendMsg"
)
{
sealed
class
Response
:
Packet
{
sealed
class
Response
:
Packet
{
object
SUCCESS
:
Response
()
{
object
SUCCESS
:
Response
()
{
override
fun
toString
():
String
=
"MessageSvc.PbSendMsg.Response.SUCCESS"
override
fun
toString
():
String
=
"MessageSvc.PbSendMsg.Response.SUCCESS"
...
@@ -230,9 +227,9 @@ internal class MessageSvc {
...
@@ -230,9 +227,9 @@ internal class MessageSvc {
elems
=
message
.
toRichTextElems
()
elems
=
message
.
toRichTextElems
()
)
)
),
),
msgSeq
=
client
.
atomicNextMessageSequenceId
()
msgSeq
=
client
.
atomicNextMessageSequenceId
()
,
//
msgRand = 123
//
msgRand = Random.nextInt() and 0x7FFF,
//syncCookie = client.c2cMessageSync.syncCookie?.takeIf { it.isNotEmpty() } ?:
syncCookie
=
client
.
c2cMessageSync
.
syncCookie
?.
takeIf
{
it
.
isNotEmpty
()
}
?:
EMPTY_BYTE_ARRAY
//SyncCookie(currentTimeSeconds, Random.nextLong().absoluteValue, Random.nextLong().absoluteValue).toByteArray(SyncCookie.serializer())
//SyncCookie(currentTimeSeconds, Random.nextLong().absoluteValue, Random.nextLong().absoluteValue).toByteArray(SyncCookie.serializer())
// msgVia = 1
// msgVia = 1
)
)
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
View file @
63a4d5f3
...
@@ -11,7 +11,7 @@ import net.mamoe.mirai.qqandroid.QQAndroidBot
...
@@ -11,7 +11,7 @@ import net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import
net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgOnlinePush
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgOnlinePush
import
net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.
Incoming
PacketFactory
import
net.mamoe.mirai.qqandroid.utils.toMessageChain
import
net.mamoe.mirai.qqandroid.utils.toMessageChain
...
@@ -19,9 +19,9 @@ internal class OnlinePush {
...
@@ -19,9 +19,9 @@ internal class OnlinePush {
/**
/**
* 接受群消息
* 接受群消息
*/
*/
internal
object
PbPushGroupMsg
:
PacketFactory
<
GroupMessage
>(
"OnlinePush.PbPushGroupMsg"
)
{
internal
object
PbPushGroupMsg
:
Incoming
PacketFactory
<
GroupMessage
>(
"OnlinePush.PbPushGroupMsg"
)
{
@UseExperimental
(
ExperimentalStdlibApi
::
class
)
@UseExperimental
(
ExperimentalStdlibApi
::
class
)
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
GroupMessage
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
GroupMessage
{
// 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00
// 00 00 02 E4 0A D5 05 0A 4F 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 52 20 00 28 BC 3D 30 8C 82 AB F1 05 38 D2 80 E0 8C 80 80 80 80 02 4A 21 08 E7 C1 AD B8 02 10 01 18 BA 05 22 09 48 69 6D 31 38 38 6D 6F 65 30 06 38 02 42 05 4D 69 72 61 69 50 01 58 01 60 00 88 01 08 12 06 08 01 10 00 18 00 1A F9 04 0A F6 04 0A 26 08 00 10 87 82 AB F1 05 18 B7 B4 BF 30 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 E6 03 42 E3 03 12 2A 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 22 00 2A 04 03 00 00 00 32 60 15 36 20 39 36 6B 45 31 41 38 35 32 32 39 64 63 36 39 38 34 37 39 37 37 62 20 20 20 20 20 20 35 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7B 34 45 31 38 35 38 32 32 2D 30 45 37 42 2D 46 38 30 46 2D 43 35 42 31 2D 33 34 34 38 38 33 37 34 44 33 39 43 7D 2E 6A 70 67 31 32 31 32 41 38 C6 BB 8A A9 08 40 FB AE 9E C2 09 48 50 50 41 5A 00 60 01 6A 10 4E 18 58 22 0E 7B F8 0F C5 B1 34 48 83 74 D3 9C 72 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 31 39 38 3F 74 65 72 6D 3D 32 82 01 57 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 30 3F 74 65 72 6D 3D 32 B0 01 4D B8 01 2E C8 01 FF 05 D8 01 4D E0 01 2E FA 01 59 2F 67 63 68 61 74 70 69 63 5F 6E 65 77 2F 31 30 34 30 34 30 30 32 39 30 2F 36 35 35 30 35 37 31 32 37 2D 32 32 33 33 36 33 38 33 34 32 2D 34 45 31 38 35 38 32 32 30 45 37 42 46 38 30 46 43 35 42 31 33 34 34 38 38 33 37 34 44 33 39 43 2F 34 30 30 3F 74 65 72 6D 3D 32 80 02 4D 88 02 2E 12 45 AA 02 42 50 03 60 00 68 00 9A 01 39 08 09 20 BF 50 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 98 03 00 A0 03 20 B0 03 00 C0 03 00 D0 03 00 E8 03 00 8A 04 04 08 02 08 01 90 04 80 80 80 10 B8 04 00 C0 04 00 12 06 4A 04 08 00 40 01 12 14 82 01 11 0A 09 48 69 6D 31 38 38 6D 6F 65 18 06 20 08 28 03 10 8A CA 9D A1 07 1A 00
discardExact
(
4
)
discardExact
(
4
)
val
pbPushMsg
=
ProtoBufWithNullableSupport
.
load
(
MsgOnlinePush
.
PbPushMsg
.
serializer
(),
readBytes
())
val
pbPushMsg
=
ProtoBufWithNullableSupport
.
load
(
MsgOnlinePush
.
PbPushMsg
.
serializer
(),
readBytes
())
...
@@ -48,9 +48,5 @@ internal class OnlinePush {
...
@@ -48,9 +48,5 @@ internal class OnlinePush {
}
}
)
)
}
}
override
suspend
fun
QQAndroidBot
.
handle
(
packet
:
GroupMessage
)
{
}
}
}
}
}
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/list/FriendListPacket.kt
View file @
63a4d5f3
...
@@ -14,7 +14,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.jce.*
...
@@ -14,7 +14,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.jce.*
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.Vec0xd50
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.Vec0xd50
import
net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
import
net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
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.
Outgoing
PacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
import
net.mamoe.mirai.utils.io.discardExact
import
net.mamoe.mirai.utils.io.discardExact
...
@@ -22,7 +22,7 @@ import net.mamoe.mirai.utils.io.discardExact
...
@@ -22,7 +22,7 @@ import net.mamoe.mirai.utils.io.discardExact
internal
class
FriendList
{
internal
class
FriendList
{
internal
object
GetTroopMemberList
:
internal
object
GetTroopMemberList
:
PacketFactory
<
GetTroopMemberList
.
Response
>(
"friendlist.GetTroopMemberListReq"
)
{
Outgoing
PacketFactory
<
GetTroopMemberList
.
Response
>(
"friendlist.GetTroopMemberListReq"
)
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
GetTroopMemberList
.
Response
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
GetTroopMemberList
.
Response
{
TODO
()
TODO
()
}
}
...
@@ -65,7 +65,7 @@ internal class FriendList {
...
@@ -65,7 +65,7 @@ internal class FriendList {
}
}
internal
object
GetTroopListSimplify
:
internal
object
GetTroopListSimplify
:
PacketFactory
<
GetTroopListSimplify
.
Response
>(
"friendlist.GetTroopListReqV2"
)
{
Outgoing
PacketFactory
<
GetTroopListSimplify
.
Response
>(
"friendlist.GetTroopListReqV2"
)
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
GetTroopListSimplify
.
Response
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
GetTroopListSimplify
.
Response
{
val
res
=
this
.
decodeUniPacket
(
GetTroopListRespV2
.
serializer
())
val
res
=
this
.
decodeUniPacket
(
GetTroopListRespV2
.
serializer
())
return
Response
(
res
.
vecTroopList
.
orEmpty
())
return
Response
(
res
.
vecTroopList
.
orEmpty
())
...
@@ -109,7 +109,8 @@ internal class FriendList {
...
@@ -109,7 +109,8 @@ internal class FriendList {
}
}
}
}
}
}
internal
object
GetFriendGroupList
:
PacketFactory
<
GetFriendGroupList
.
Response
>(
"friendlist.getFriendGroupList"
)
{
internal
object
GetFriendGroupList
:
OutgoingPacketFactory
<
GetFriendGroupList
.
Response
>(
"friendlist.getFriendGroupList"
)
{
class
Response
(
class
Response
(
val
totalFriendCount
:
Short
,
val
totalFriendCount
:
Short
,
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/ConfigPushSvc.kt
View file @
63a4d5f3
...
@@ -9,23 +9,25 @@ import net.mamoe.mirai.qqandroid.io.serialization.jceRequestSBuffer
...
@@ -9,23 +9,25 @@ import net.mamoe.mirai.qqandroid.io.serialization.jceRequestSBuffer
import
net.mamoe.mirai.qqandroid.io.serialization.writeJceStruct
import
net.mamoe.mirai.qqandroid.io.serialization.writeJceStruct
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.PushResp
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.PushResp
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.IncomingPacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildResponseUniPacket
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.PushReq
as
PushReqJceStruct
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.PushReq
as
PushReqJceStruct
internal
class
ConfigPushSvc
{
internal
class
ConfigPushSvc
{
object
PushReq
:
PacketFactory
<
PushReqJceStruct
>(
"ConfigPushSvc.PushReq"
)
{
object
PushReq
:
IncomingPacketFactory
<
PushReqJceStruct
>(
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
PushReqJceStruct
{
receivingCommandName
=
"ConfigPushSvc.PushReq"
,
responseCommandName
=
"ConfigPushSvc.PushResp"
)
{
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
,
sequenceId
:
Int
):
PushReqJceStruct
{
discardExact
(
4
)
discardExact
(
4
)
val
pushReq
=
decodeUniPacket
(
PushReqJceStruct
.
serializer
())
return
decodeUniPacket
(
PushReqJceStruct
.
serializer
())
//println(pushReq.contentToString())
return
pushReq
}
}
override
suspend
fun
QQAndroidBot
.
handle
(
packet
:
PushReqJceStruct
)
{
override
suspend
fun
QQAndroidBot
.
handle
(
packet
:
PushReqJceStruct
,
sequenceId
:
Int
):
OutgoingPacket
?
{
network
.
run
{
return
network
.
run
{
build
Outgoing
UniPacket
(
build
Response
UniPacket
(
client
,
client
,
sequenceId
=
client
.
configPushSvcPushReqSequenceId
,
sequenceId
=
client
.
configPushSvcPushReqSequenceId
,
commandName
=
"ConfigPushSvc.PushResp"
,
commandName
=
"ConfigPushSvc.PushResp"
,
...
@@ -51,7 +53,7 @@ internal class ConfigPushSvc {
...
@@ -51,7 +53,7 @@ internal class ConfigPushSvc {
charset
=
JceCharset
.
UTF8
charset
=
JceCharset
.
UTF8
)
)
// writePacket(this.build().debugPrintThis())
// writePacket(this.build().debugPrintThis())
}
.
sendWithoutExpect
()
}
}
}
}
}
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt
View file @
63a4d5f3
...
@@ -11,16 +11,19 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.*
...
@@ -11,16 +11,19 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.*
import
net.mamoe.mirai.qqandroid.utils.GuidSource
import
net.mamoe.mirai.qqandroid.utils.GuidSource
import
net.mamoe.mirai.qqandroid.utils.MacOrAndroidIdChangeFlag
import
net.mamoe.mirai.qqandroid.utils.MacOrAndroidIdChangeFlag
import
net.mamoe.mirai.qqandroid.utils.guidFlag
import
net.mamoe.mirai.qqandroid.utils.guidFlag
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.MiraiDebugAPI
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.cryptor.decryptBy
import
net.mamoe.mirai.utils.cryptor.decryptBy
import
net.mamoe.mirai.utils.currentTimeSeconds
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.io.discardExact
import
net.mamoe.mirai.utils.io.discardExact
import
net.mamoe.mirai.utils.md5
/**
/**
* OicqRequest
* OicqRequest
*/
*/
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
)
@UseExperimental
(
ExperimentalUnsignedTypes
::
class
)
internal
object
LoginPacket
:
PacketFactory
<
LoginPacket
.
LoginPacketResponse
>(
"wtlogin.login"
)
{
internal
object
LoginPacket
:
Outgoing
PacketFactory
<
LoginPacket
.
LoginPacketResponse
>(
"wtlogin.login"
)
{
/**
/**
* 提交验证码
* 提交验证码
...
@@ -686,7 +689,7 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
...
@@ -686,7 +689,7 @@ internal object LoginPacket : PacketFactory<LoginPacket.LoginPacketResponse>("wt
*/
*/
private
fun
QQAndroidClient
.
analysisTlv130
(
t130
:
ByteArray
)
=
t130
.
read
{
private
fun
QQAndroidClient
.
analysisTlv130
(
t130
:
ByteArray
)
=
t130
.
read
{
discardExact
(
2
)
discardExact
(
2
)
timeDifference
=
readUInt
().
toLong
()
-
currentTime
Milli
s
timeDifference
=
readUInt
().
toLong
()
-
currentTime
Second
s
ipFromT149
=
readBytes
(
4
)
ipFromT149
=
readBytes
(
4
)
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/StatSvc.kt
View file @
63a4d5f3
...
@@ -10,7 +10,7 @@ import net.mamoe.mirai.qqandroid.network.QQAndroidClient
...
@@ -10,7 +10,7 @@ import net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.SvcReqRegister
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.SvcReqRegister
import
net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
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.
Outgoing
PacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildLoginOutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildLoginOutgoingPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.oidb.oidb0x769.Oidb0x769
import
net.mamoe.mirai.qqandroid.network.protocol.packet.oidb.oidb0x769.Oidb0x769
import
net.mamoe.mirai.qqandroid.network.protocol.packet.writeSsoPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.writeSsoPacket
...
@@ -33,7 +33,7 @@ internal enum class RegPushReason {
...
@@ -33,7 +33,7 @@ internal enum class RegPushReason {
}
}
internal
class
StatSvc
{
internal
class
StatSvc
{
internal
object
Register
:
PacketFactory
<
Register
.
Response
>(
"StatSvc.register"
)
{
internal
object
Register
:
Outgoing
PacketFactory
<
Register
.
Response
>(
"StatSvc.register"
)
{
internal
object
Response
:
Packet
{
internal
object
Response
:
Packet
{
override
fun
toString
():
String
=
"Response(StatSvc.register)"
override
fun
toString
():
String
=
"Response(StatSvc.register)"
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/TransEmpPacket.kt
View file @
63a4d5f3
...
@@ -7,7 +7,7 @@ import net.mamoe.mirai.qqandroid.QQAndroidBot
...
@@ -7,7 +7,7 @@ import net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.protocol.packet.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.*
internal
object
TransEmpPacket
:
PacketFactory
<
TransEmpPacket
.
Response
>(
"wtlogin.trans_emp"
)
{
internal
object
TransEmpPacket
:
Outgoing
PacketFactory
<
TransEmpPacket
.
Response
>(
"wtlogin.trans_emp"
)
{
private
const
val
appId
=
16L
private
const
val
appId
=
16L
private
const
val
subAppId
=
537062845L
private
const
val
subAppId
=
537062845L
...
...
mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/serverToClient.kt
View file @
63a4d5f3
...
@@ -4,10 +4,7 @@ package androidPacketTests
...
@@ -4,10 +4,7 @@ package androidPacketTests
import
kotlinx.io.core.*
import
kotlinx.io.core.*
import
kotlinx.io.pool.useInstance
import
kotlinx.io.pool.useInstance
import
net.mamoe.mirai.qqandroid.network.protocol.packet.DECRYPTER_16_ZERO
import
net.mamoe.mirai.qqandroid.network.protocol.packet.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.KnownPacketFactories
import
net.mamoe.mirai.qqandroid.network.protocol.packet.PacketLogger
import
net.mamoe.mirai.qqandroid.network.protocol.packet.withUse
import
net.mamoe.mirai.utils.cryptor.ECDH
import
net.mamoe.mirai.utils.cryptor.ECDH
import
net.mamoe.mirai.utils.cryptor.adjustToPublicKey
import
net.mamoe.mirai.utils.cryptor.adjustToPublicKey
import
net.mamoe.mirai.utils.cryptor.decryptBy
import
net.mamoe.mirai.utils.cryptor.decryptBy
...
@@ -99,7 +96,7 @@ private fun processFullPacketWithoutLength(packet: ByteReadPacket) {
...
@@ -99,7 +96,7 @@ private fun processFullPacketWithoutLength(packet: ByteReadPacket) {
try
{
try
{
bytes
.
toReadPacket
().
parseOicqResponse
{
bytes
.
toReadPacket
().
parseOicqResponse
{
debugIfFail
{
debugIfFail
{
if
(
it
.
packetFactory
.
commandName
==
"wtlogin.login"
)
{
if
(
(
it
.
packetFactory
as
?
OutgoingPacketFactory
<
*
>)
?
.
commandName
==
"wtlogin.login"
)
{
DebugLogger
.
info
(
"服务器发来了 wtlogin.login. 正在解析 key"
)
DebugLogger
.
info
(
"服务器发来了 wtlogin.login. 正在解析 key"
)
try
{
try
{
val
subCommand
=
readUShort
().
toInt
()
val
subCommand
=
readUShort
().
toInt
()
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/MiraiLogger.kt
View file @
63a4d5f3
...
@@ -5,59 +5,73 @@ import kotlin.jvm.JvmOverloads
...
@@ -5,59 +5,73 @@ import kotlin.jvm.JvmOverloads
/**
/**
* 用于创建默认的日志记录器. 在一些需要使用日志的 Mirai 的组件, 如 [Bot], 都会通过这个函数构造日志记录器
* 用于创建默认的日志记录器. 在一些需要使用日志的 Mirai 的组件, 如 [Bot], 都会通过这个函数构造日志记录器
.
* 可直接修改这个变量的值来重定向日志输出.
* 可直接修改这个变量的值来重定向日志输出.
*/
var
DefaultLogger
:
(
identity
:
String
?)
->
MiraiLogger
=
{
PlatformLogger
(
it
)
}
/**
* 当前平台的默认的日志记录器.
* 在 _JVM 控制台_ 端的实现为 [println]
* 在 _Android_ 端的实现为 [android.util.Log]
*
*
* 不应该直接构造这个类的实例. 请使用 [DefaultLogger], 或使用默认的顶层日志记录 [MiraiLogger.Companion]
* **注意:** 请务必将所有的输出定向到日志记录系统, 否则在某些情况下 (如 web 控制台中) 将无法接收到输出
*
* **注意:** 请为日志做好分类, 即不同的模块使用不同的 [MiraiLogger].
* 如, [Bot] 中使用 identity 为 "Bot(qqId)" 的 [MiraiLogger]
* 而 [Bot] 的网络处理中使用 identity 为 "BotNetworkHandler" 的.
*/
*/
expect
open
class
PlatformLogger
@JvmOverloads
internal
constructor
(
identity
:
String
?
=
"Mirai"
)
:
MiraiLoggerPlatformBase
var
DefaultLogger
:
(
identity
:
String
?)
->
MiraiLogger
=
{
PlatformLogger
(
it
)
}
/**
/**
* 给这个 logger 添加一个开关, 用于控制是否记录 log
* 给这个 logger 添加一个开关, 用于控制是否记录 log
*
*/
*/
@JvmOverloads
@JvmOverloads
fun
MiraiLogger
.
withSwitch
(
default
:
Boolean
=
true
):
MiraiLoggerWithSwitch
=
MiraiLoggerWithSwitch
(
this
,
default
)
fun
MiraiLogger
.
withSwitch
(
default
:
Boolean
=
true
):
MiraiLoggerWithSwitch
=
MiraiLoggerWithSwitch
(
this
,
default
)
/**
/**
* 日志记录器. 所有的输出均依赖于它.
* 日志记录器. 所有的输出均依赖于它.
* 不同的对象可能拥有只属于自己的 logger. 通过 [identity] 来区分.
* 不同的对象可拥有只属于自己的 logger. 通过 [identity] 来区分.
*
* 注意: 如果你需要重新实现日志, 请不要直接实现这个接口, 请继承 [MiraiLoggerPlatformBase]
*
*
*
注意: 请不要直接实现这个接口, 请继承 [MiraiLoggerPlatformBase]
*
在定义 logger 变量时, 请一直使用 [MiraiLogger] 或者 [MiraiLoggerWithSwitch].
*
*
* @see MiraiLoggerPlatformBase 平台通用基础实现
* @see SimpleLogger 简易 logger, 它将所有的日志记录操作都转移给 lambda `(String?, Throwable?) -> Unit`
* @see PlatformLogger 各个平台下的默认日志记录实现.
* @see SilentLogger 忽略任何日志记录操作的 logger 实例.
*
* @see MiraiLoggerPlatformBase 平台通用基础实现. 若
*/
*/
interface
MiraiLogger
{
interface
MiraiLogger
{
/**
/**
* 顶层日志记录器.
* 顶层日志记录器.
*
* 顶层日志会导致混乱并难以定位问题. 请自行构造 logger 实例并使用.
* 请参考使用 [DefaultLogger]
*/
*/
@Deprecated
(
message
=
"顶层日志会导致混乱并难以定位问题. 请自行构造 logger 实例并使用."
,
level
=
DeprecationLevel
.
WARNING
)
companion
object
:
MiraiLogger
by
DefaultLogger
(
"Mirai"
)
companion
object
:
MiraiLogger
by
DefaultLogger
(
"Mirai"
)
/**
* 日志的标记. 在 Mirai 中, identity 可为
* - "Bot"
* - "BotNetworkHandler"
* 等.
*
* 它只用于帮助调试或统计. 十分建议清晰定义 identity
*/
val
identity
:
String
?
val
identity
:
String
?
/**
/**
* 随从. 在 this 中调用所有方法后都应继续往 [follower] 传递调用.
* 随从. 在 this 中调用所有方法后都应继续往 [follower] 传递调用.
* [follower] 的存在可以让一次日志被多个日志记录器记录.
* [follower] 的存在可以让一次日志被多个日志记录器记录.
*
*
* 例:
* 一般不建议直接修改这个属性. 请通过 [plus] 来连接两个日志记录器.
* ```kotlin
* 如: `val logger = bot.logger + MyOwnLogger()`
* val bot = Bot( ... )
* 这样, 当调用 `logger.info()` 时, bot.logger 会首先记录, MyOwnLogger 会随后记录.
* bot.follower = MyOwnLogger()
*
*
* bot.info("Hi")
* 当然, 多个 logger 也可以加在一起: `val logger = bot.logger + MyOwnLogger() + MyOwnLogger2()`
* ```
* 在这个例子中的 `MyOwnLogger` 将可以记录到 "Hi".
*/
*/
var
follower
:
MiraiLogger
?
var
follower
:
MiraiLogger
?
/**
/**
* 记录一个 `verbose` 级别的日志.
* 记录一个 `verbose` 级别的日志.
* 无关紧要的, 经常大量输出的日志应使用它.
*/
*/
fun
verbose
(
any
:
Any
?)
fun
verbose
(
any
:
Any
?)
...
@@ -65,7 +79,7 @@ interface MiraiLogger {
...
@@ -65,7 +79,7 @@ interface MiraiLogger {
fun
verbose
(
message
:
String
?,
e
:
Throwable
?)
fun
verbose
(
message
:
String
?,
e
:
Throwable
?)
/**
/**
* 记录一个
`debug`
级别的日志.
* 记录一个
_调试_
级别的日志.
*/
*/
fun
debug
(
any
:
Any
?)
fun
debug
(
any
:
Any
?)
...
@@ -74,7 +88,7 @@ interface MiraiLogger {
...
@@ -74,7 +88,7 @@ interface MiraiLogger {
/**
/**
* 记录一个
`info`
级别的日志.
* 记录一个
_信息_
级别的日志.
*/
*/
fun
info
(
any
:
Any
?)
fun
info
(
any
:
Any
?)
...
@@ -83,7 +97,7 @@ interface MiraiLogger {
...
@@ -83,7 +97,7 @@ interface MiraiLogger {
/**
/**
* 记录一个
`warning`
级别的日志.
* 记录一个
_警告_
级别的日志.
*/
*/
fun
warning
(
any
:
Any
?)
fun
warning
(
any
:
Any
?)
...
@@ -92,7 +106,7 @@ interface MiraiLogger {
...
@@ -92,7 +106,7 @@ interface MiraiLogger {
/**
/**
* 记录一个
`error`
级别的日志.
* 记录一个
_错误_
级别的日志.
*/
*/
fun
error
(
e
:
Any
?)
fun
error
(
e
:
Any
?)
...
@@ -109,10 +123,9 @@ interface MiraiLogger {
...
@@ -109,10 +123,9 @@ interface MiraiLogger {
* | base | <-- | follower | <-- | follower | <-- | follower |
* | base | <-- | follower | <-- | follower | <-- | follower |
* +------+ +----------+ +----------+ +----------+
* +------+ +----------+ +----------+ +----------+
*
*
* @see follower
* @return [follower]
* @return [follower]
*/
*/
operator
fun
plus
(
follower
:
MiraiLogger
):
MiraiLogger
operator
fun
<
T
:
MiraiLogger
>
plus
(
follower
:
T
):
T
/**
/**
* 添加一个 [follower]
* 添加一个 [follower]
...
@@ -123,6 +136,15 @@ interface MiraiLogger {
...
@@ -123,6 +136,15 @@ interface MiraiLogger {
operator
fun
plusAssign
(
follower
:
MiraiLogger
)
operator
fun
plusAssign
(
follower
:
MiraiLogger
)
}
}
/**
* 当前平台的默认的日志记录器.
* 在 _JVM 控制台_ 端的实现为 [println]
* 在 _Android_ 端的实现为 [android.util.Log]
*
* 不应该直接构造这个类的实例. 请使用 [DefaultLogger], 或使用默认的顶层日志记录 [MiraiLogger.Companion]
*/
expect
open
class
PlatformLogger
@JvmOverloads
internal
constructor
(
identity
:
String
?
=
"Mirai"
)
:
MiraiLoggerPlatformBase
/**
/**
* 不做任何事情的 logger, keep silent.
* 不做任何事情的 logger, keep silent.
*/
*/
...
@@ -167,7 +189,11 @@ class SimpleLogger(override val identity: String?, private val logger: (String?,
...
@@ -167,7 +189,11 @@ class SimpleLogger(override val identity: String?, private val logger: (String?,
class
MiraiLoggerWithSwitch
internal
constructor
(
private
val
delegate
:
MiraiLogger
,
default
:
Boolean
)
:
MiraiLoggerPlatformBase
()
{
class
MiraiLoggerWithSwitch
internal
constructor
(
private
val
delegate
:
MiraiLogger
,
default
:
Boolean
)
:
MiraiLoggerPlatformBase
()
{
override
val
identity
:
String
?
get
()
=
delegate
.
identity
override
val
identity
:
String
?
get
()
=
delegate
.
identity
private
var
switch
:
Boolean
=
default
/**
* true 为开启.
*/
@PublishedApi
internal
var
switch
:
Boolean
=
default
fun
enable
()
{
fun
enable
()
{
switch
=
true
switch
=
true
...
@@ -188,15 +214,53 @@ class MiraiLoggerWithSwitch internal constructor(private val delegate: MiraiLogg
...
@@ -188,15 +214,53 @@ class MiraiLoggerWithSwitch internal constructor(private val delegate: MiraiLogg
override
fun
error0
(
any
:
Any
?)
=
if
(
switch
)
delegate
.
error
(
any
)
else
Unit
override
fun
error0
(
any
:
Any
?)
=
if
(
switch
)
delegate
.
error
(
any
)
else
Unit
override
fun
error0
(
message
:
String
?,
e
:
Throwable
?)
=
if
(
switch
)
delegate
.
error
(
message
,
e
)
else
Unit
override
fun
error0
(
message
:
String
?,
e
:
Throwable
?)
=
if
(
switch
)
delegate
.
error
(
message
,
e
)
else
Unit
inline
fun
verbose
(
lazyMessage
:
()
->
String
)
{
if
(
switch
)
verbose
(
lazyMessage
())
}
inline
fun
verbose
(
lazyMessage
:
()
->
String
,
e
:
Throwable
?)
{
if
(
switch
)
verbose
(
lazyMessage
(),
e
)
}
inline
fun
debug
(
lazyMessage
:
()
->
Any
?)
{
if
(
switch
)
debug
(
lazyMessage
())
}
inline
fun
debug
(
lazyMessage
:
()
->
String
?,
e
:
Throwable
?)
{
if
(
switch
)
debug
(
lazyMessage
(),
e
)
}
inline
fun
info
(
lazyMessage
:
()
->
Any
?)
{
if
(
switch
)
info
(
lazyMessage
())
}
inline
fun
info
(
lazyMessage
:
()
->
String
?,
e
:
Throwable
?)
{
if
(
switch
)
info
(
lazyMessage
(),
e
)
}
inline
fun
warning
(
lazyMessage
:
()
->
Any
?)
{
if
(
switch
)
warning
(
lazyMessage
())
}
inline
fun
warning
(
lazyMessage
:
()
->
String
?,
e
:
Throwable
?)
{
if
(
switch
)
warning
(
lazyMessage
(),
e
)
}
inline
fun
error
(
lazyMessage
:
()
->
Any
?)
{
if
(
switch
)
error
(
lazyMessage
())
}
inline
fun
error
(
lazyMessage
:
()
->
String
?,
e
:
Throwable
?)
{
if
(
switch
)
error
(
lazyMessage
(),
e
)
}
}
}
/**
/**
* 平台日志基类.
* 日志基类. 实现了 [follower] 的调用传递.
* 实现了 [follower] 的调用传递.
* 若 Mirai 自带的日志系统无法满足需求, 请继承这个类并实现其抽象函数.
*
* 若要自行实现日志记录, 请优先考虑继承 [PlatformLogger].
*
*
* 它不应该被用作变量的类型定义. 只应被继承
* 这个类不应该被用作变量的类型定义. 只应被作为继承对象.
* 在定义 logger 变量时, 请一直使用 [MiraiLogger] 或者 [MiraiLoggerWithSwitch].
*/
*/
abstract
class
MiraiLoggerPlatformBase
:
MiraiLogger
{
abstract
class
MiraiLoggerPlatformBase
:
MiraiLogger
{
final
override
var
follower
:
MiraiLogger
?
=
null
final
override
var
follower
:
MiraiLogger
?
=
null
...
@@ -262,7 +326,7 @@ abstract class MiraiLoggerPlatformBase : MiraiLogger {
...
@@ -262,7 +326,7 @@ abstract class MiraiLoggerPlatformBase : MiraiLogger {
protected
abstract
fun
error0
(
any
:
Any
?)
protected
abstract
fun
error0
(
any
:
Any
?)
protected
abstract
fun
error0
(
message
:
String
?,
e
:
Throwable
?)
protected
abstract
fun
error0
(
message
:
String
?,
e
:
Throwable
?)
override
fun
plus
(
follower
:
MiraiLogger
):
MiraiLogger
{
override
operator
fun
<
T
:
MiraiLogger
>
plus
(
follower
:
T
):
T
{
this
.
follower
=
follower
this
.
follower
=
follower
return
follower
return
follower
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment