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
12944417
Commit
12944417
authored
Nov 20, 2019
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
GroupImageDownload supports
parent
44a6ba16
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
267 additions
and
134 deletions
+267
-134
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/FriendImage.kt
...e.mirai/network/protocol/tim/packet/action/FriendImage.kt
+8
-10
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt
...oe.mirai/network/protocol/tim/packet/action/GroupImage.kt
+171
-114
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/Image.kt
...t.mamoe.mirai/network/protocol/tim/packet/action/Image.kt
+78
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Message.kt
....mamoe.mirai/network/protocol/tim/packet/event/Message.kt
+7
-5
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
.../commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
+3
-5
No files found.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/FriendImage.kt
View file @
12944417
...
...
@@ -2,11 +2,11 @@
package
net.mamoe.mirai.network.protocol.tim.packet.action
import
io.ktor.client.request.get
import
kotlinx.io.charsets.Charsets
import
kotlinx.io.core.*
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.message.ImageId
import
net.mamoe.mirai.message.ImageId0x06
import
net.mamoe.mirai.message.requireLength
import
net.mamoe.mirai.network.BotNetworkHandler
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
...
...
@@ -59,11 +59,8 @@ interface FriendImageResponse : EventPacket
* 图片数据地址.
*/
// TODO: 2019/11/15 应该为 inline class, 但 kotlin 有 bug
data class
FriendImageLink
(
inline
val
value
:
String
)
:
FriendImageResponse
{
suspend
fun
downloadAsByteArray
():
ByteArray
=
download
().
readBytes
()
suspend
fun
download
():
ByteReadPacket
=
Http
.
get
(
value
)
override
fun
toString
():
String
=
"FriendImageLink($value)"
data class
FriendImageLink
(
override
inline
val
original
:
String
)
:
FriendImageResponse
,
ImageLink
{
override
fun
toString
():
String
=
"FriendImageLink($original)"
}
/**
...
...
@@ -199,7 +196,7 @@ object FriendImagePacket : SessionPacketFactory<FriendImageResponse>() {
writeUByte
(
0
x1Au
)
writeUByte
(
0
x47u
)
writeTUVarint
(
0
x08u
,
bot
)
writeTUVarint
(
0
x10u
,
bot
)
writeTUVarint
(
0
x10u
,
bot
)
// 这里实际上应该是这张图片来自哪个 QQ 号. 但传 bot 也没事.
writeTLV
(
0
x1Au
,
imageId
.
value
.
toByteArray
(
Charsets
.
ISO_8859_1
))
writeHex
(
"20 02 30 04 38 20 40 FF 01 50 00 6A 05 32 36 39 33 33 78 01"
)
}
...
...
@@ -276,7 +273,7 @@ object FriendImagePacket : SessionPacketFactory<FriendImageResponse>() {
while
(
readUByte
().
toUInt
()
!=
0
x4Au
)
readUVarLong
()
val
uKey
=
readBytes
(
readUVarInt
().
toInt
())
//128
while
(
readUByte
().
toUInt
()
!=
0
x52u
)
readUVarLong
()
val
imageId
=
ImageId
(
readString
(
readUVarInt
().
toInt
()))
//37
val
imageId
=
ImageId
0x06
(
readString
(
readUVarInt
().
toInt
()))
//37
return
FriendImageUKey
(
imageId
,
uKey
)
}
catch
(
e
:
EOFException
)
{
val
toDiscard
=
readUByte
().
toInt
()
-
37
...
...
@@ -285,7 +282,7 @@ object FriendImagePacket : SessionPacketFactory<FriendImageResponse>() {
FriendImageOverFileSizeMax
}
else
{
discardExact
(
toDiscard
)
val
imageId
=
ImageId
(
readString
(
37
))
val
imageId
=
ImageId
0x06
(
readString
(
37
))
FriendImageAlreadyExists
(
imageId
)
}
}
...
...
@@ -302,6 +299,7 @@ object FriendImagePacket : SessionPacketFactory<FriendImageResponse>() {
// 3A 00 80 01 00
//00 00 00 08 00 00
// [02 29]
// 12 [06] 98 01 02 A0 01 00
...
...
@@ -315,7 +313,7 @@ object FriendImagePacket : SessionPacketFactory<FriendImageResponse>() {
discardExact
(
1
)
discardExact
(
2
)
// [A4 04] 后文长度
check
(
readUByte
().
toUInt
()
==
0
x0Au
)
{
"Illegal identity. Required 0x0Au"
}
/* val imageId = */
ImageId
(
readString
(
readUByte
().
toInt
()))
/* val imageId = */
ImageId
0x06
(
readString
(
readUByte
().
toInt
()))
check
(
readUByte
().
toUInt
()
==
0
x18u
)
{
"Illegal identity. Required 0x18u"
}
check
(
readUShort
().
toUInt
()
==
0
x0032u
)
{
"Illegal identity. Required 0x0032u"
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt
View file @
12944417
...
...
@@ -3,8 +3,9 @@
package
net.mamoe.mirai.network.protocol.tim.packet.action
import
kotlinx.coroutines.withContext
import
kotlinx.io.charsets.Charsets
import
kotlinx.io.core.*
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.discardExact
import
kotlinx.io.core.readBytes
import
kotlinx.serialization.SerialId
import
kotlinx.serialization.Serializable
import
kotlinx.serialization.protobuf.ProtoBuf
...
...
@@ -13,16 +14,17 @@ import net.mamoe.mirai.contact.GroupId
import
net.mamoe.mirai.contact.GroupInternalId
import
net.mamoe.mirai.contact.withSession
import
net.mamoe.mirai.message.ImageId
import
net.mamoe.mirai.message.ImageId0x03
import
net.mamoe.mirai.message.requireLength
import
net.mamoe.mirai.network.BotNetworkHandler
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.network.protocol.tim.packet.*
import
net.mamoe.mirai.network.protocol.tim.packet.event.EventPacket
import
net.mamoe.mirai.qqAccount
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.Http
import
net.mamoe.mirai.utils.assertUnreachable
import
net.mamoe.mirai.utils.io.*
import
net.mamoe.mirai.utils.io.debugPrintln
import
net.mamoe.mirai.utils.io.toUHexString
import
kotlin.coroutines.coroutineContext
...
...
@@ -64,14 +66,32 @@ interface GroupImageResponse : EventPacket
// endregion
@Suppress
(
"unused"
)
@Serializable
data class
ImageDownloadInfo
(
@SerialId
(
11
)
val
host
:
String
,
class
ImageDownloadInfo
(
@SerialId
(
3
)
val
errorCode
:
Int
=
0
,
// 0 for success
@SerialId
(
4
)
val
errorMessage
:
String
?
=
null
,
// 感动中国
@SerialId
(
10
)
private
val
_port
:
List
<
Byte
>?
=
null
,
@SerialId
(
11
)
private
val
_host
:
String
?
=
null
,
@SerialId
(
12
)
private
val
_thumbnail
:
String
?
=
null
,
@SerialId
(
13
)
private
val
_original
:
String
?
=
null
,
@SerialId
(
14
)
private
val
_compressed
:
String
?
=
null
)
:
GroupImageResponse
,
ImageLink
{
private
val
port
:
List
<
Byte
>
get
()
=
_port
!!
private
val
host
:
String
get
()
=
"http://"
+
_host
!!
val
thumbnail
:
String
get
()
=
host
+
":"
+
port
.
first
()
+
_thumbnail
!!
override
val
original
:
String
get
()
=
host
+
":"
+
port
.
first
()
+
_original
!!
val
compressed
:
String
get
()
=
host
+
":"
+
port
.
first
()
+
_compressed
!!
override
fun
toString
():
String
=
"ImageDownloadInfo(${_original?.let { original } ?: errorMessage ?: "
unknown
"}"
}
@SerialId
(
12
)
val
thumbnail
:
String
,
@SerialId
(
13
)
val
original
:
String
,
@SerialId
(
14
)
val
compressed
:
String
)
:
GroupImageResponse
fun
ImageDownloadInfo
.
requireSuccess
():
ImageDownloadInfo
{
require
(
this
.
errorCode
==
0
)
{
this
.
errorMessage
?:
"null"
}
return
this
}
@Serializable
class
ImageUploadInfo
(
...
...
@@ -86,126 +106,162 @@ class ImageUploadInfo(
@AnnotatedId
(
KnownPacketId
.
GROUP_IMAGE_ID
)
@PacketVersion
(
date
=
"2019.10.26"
,
timVersion
=
"2.3.2 (21173)"
)
object
GroupImagePacket
:
SessionPacketFactory
<
GroupImageResponse
>()
{
/*
请求上传图片
ProtoMap(
varint 0=0x5D(UVarInt(data=93))
varint 1=0x01(UVarInt(data=1))
delimi 2=98 01 01
varint 2=0x01(UVarInt(data=1))
delimi 3=08 A0 89 F7 B6 03 10 A2 FF 8C F0 03 18 00 22 10 2C F2 65 98 12 EA 9C 88 60 BD 7A 29 8E 6F 9B 4D 28 F0 0B 32 1A 43 00 4D 00 45 00 35 00 44 00 53 00 5A 00 43 00 4C 00 52 00 51 00 29 00 28 00 38 01 48 01 50 8B 02 58 BE 03 60 02 6A 05 32 36 39 33 33 70 00 78 03 80 01 00
)
*/
private
val
RequestImageIdUnknownByteArray
=
ubyteArrayOf
(
0
x98u
,
0
x01u
,
0
x01u
).
toByteArray
()
private
val
constValue3
=
byteArrayOf
(
0
x28
,
0
x00
,
0
x5A
,
0
x00
,
0
x53
,
0
x00
,
0
x41
,
0
x00
,
0
x58
,
0
x00
,
0
x40
,
0
x00
,
0
x57
,
0
x00
,
0
x4B
,
0
x00
,
0
x52
,
0
x00
,
0
x4A
,
0
x00
,
0
x5A
,
0
x00
,
0
x31
,
0
x00
,
0
x7E
,
0
x00
)
@Suppress
(
"unused"
)
@Serializable
private
class
RequestIdProto
(
@SerialId
(
2
)
val
unknown4
:
Byte
=
1
,
@SerialId
(
3
)
var
body
:
Body
)
{
@Serializable
class
Body
(
@SerialId
(
1
)
val
group
:
Int
,
@SerialId
(
2
)
val
bot
:
Int
,
@SerialId
(
3
)
val
const1
:
Byte
=
0
,
@SerialId
(
4
)
val
md5
:
ByteArray
,
@SerialId
(
5
)
val
const2
:
Short
=
0
x0E2D
,
@SerialId
(
6
)
val
const3
:
ByteArray
=
constValue3
,
@SerialId
(
7
)
val
const4
:
Byte
=
1
,
@SerialId
(
9
)
val
const5
:
Byte
=
1
,
@SerialId
(
10
)
val
width
:
Int
,
@SerialId
(
11
)
val
height
:
Int
,
@SerialId
(
12
)
val
const6
:
Byte
=
4
,
@SerialId
(
13
)
val
const7
:
ByteArray
=
constValue7
,
@SerialId
(
14
)
val
const8
:
Byte
=
0
,
@SerialId
(
15
)
val
const9
:
Byte
=
3
,
@SerialId
(
16
)
val
const10
:
Byte
=
0
)
}
@Suppress
(
"unused"
)
@Serializable
private
class
RequestLinkProto
(
@SerialId
(
2
)
val
unknown4
:
Byte
=
2
,
@SerialId
(
4
)
var
body
:
Body
)
{
/*
ProtoMap(
varint 1=0x8E87C28403(UVarInt(data=814777230))
varint 2=0xA2FF8CF003(UVarInt(data=1040400290))
varint 3=0xFBECB9A9A(UVarInt(data=2771285627))
delimi 4=66 3C 60 FB 31 67 85 84 1A 18 00 52 2C D6 C8 7E
varint 5=0x04(UVarInt(data=4))
varint 6=0x02(UVarInt(data=2))
varint 7=0x20(UVarInt(data=32))
varint 8=0xFF01(UVarInt(data=255))
varint 9=0x00(UVarInt(data=0))
varint 10=0x01(UVarInt(data=1))
delimi 11=32 36 39 33 33
varint 12=0x00(UVarInt(data=0))
varint 13=0x00(UVarInt(data=0))
varint 14=0x01(UVarInt(data=1))
varint 15=0x00(UVarInt(data=0))
varint 16=0xA412(UVarInt(data=2340))
varint 17=0xB808(UVarInt(data=1080))
varint 18=0xE807(UVarInt(data=1000))
varint 20=0x01(UVarInt(data=1))
)
*/
@Serializable
class
Body
(
@SerialId
(
1
)
val
group
:
Int
,
@SerialId
(
2
)
val
bot
:
Int
,
@SerialId
(
3
)
val
uniqueId
:
Int
,
@SerialId
(
4
)
val
md5
:
ByteArray
,
@SerialId
(
5
)
val
const2
:
Byte
=
4
,
@SerialId
(
6
)
val
const3
:
Byte
=
2
,
@SerialId
(
7
)
val
const4
:
Byte
=
32
,
@SerialId
(
8
)
val
const14
:
Int
=
255
,
@SerialId
(
9
)
val
const5
:
Byte
=
0
,
@SerialId
(
10
)
val
unknown5
:
Int
=
1
,
@SerialId
(
11
)
val
const7
:
ByteArray
=
constValue7
,
@SerialId
(
12
)
val
unknown6
:
Byte
=
0
,
@SerialId
(
13
)
val
const6
:
Byte
=
0
,
@SerialId
(
14
)
val
const8
:
Byte
=
0
,
@SerialId
(
15
)
val
const9
:
Byte
=
0
,
@SerialId
(
16
)
val
height
:
Int
,
@SerialId
(
17
)
val
width
:
Int
,
@SerialId
(
18
)
val
const12
:
Int
=
1003
,
//?? 有时候还是1000, 1004
@SerialId
(
20
)
val
const13
:
Byte
=
1
)
}
private
val
constValue7
:
ByteArray
=
byteArrayOf
(
0
x32
,
0
x36
,
0
x39
,
0
x33
,
0
x33
)
private
val
requestImageIdHead
=
ubyteArrayOf
(
0
x12u
,
0
x03u
,
0
x98u
,
0
x01u
,
0
x01u
)
@Suppress
(
"FunctionName"
)
fun
RequestImageId
(
bot
:
UInt
,
groupInternalId
:
GroupInternalId
,
image
:
ExternalImage
,
sessionKey
:
SessionKey
):
OutgoingPacket
=
buildSessionPacket
(
bot
,
sessionKey
,
version
=
TIMProtocol
.
version0x04
)
{
writeHex
(
"00 00 00 07 00 00"
)
writeShortLVPacket
(
lengthOffset
=
{
it
-
7
})
{
writeByte
(
0
x08
)
writeHex
(
"01 12 03 98 01 01 10 01 1A"
)
// 02 10 02 22
writeUVarIntLVPacket
(
lengthOffset
=
{
it
})
{
writeTUVarint
(
0
x08u
,
groupInternalId
.
value
)
writeTUVarint
(
0
x10u
,
bot
)
writeTV
(
0
x1800u
)
writeUByte
(
0
x22u
)
writeUByte
(
0
x10u
)
writeFully
(
image
.
md5
)
writeTUVarint
(
0
x28u
,
image
.
inputSize
.
toUInt
())
writeUVarIntLVPacket
(
tag
=
0
x32u
)
{
writeTV
(
0
x5B_00u
)
writeTV
(
0
x40_00u
)
writeTV
(
0
x33_00u
)
writeTV
(
0
x48_00u
)
writeTV
(
0
x5F_00u
)
writeTV
(
0
x58_00u
)
writeTV
(
0
x46_00u
)
writeTV
(
0
x51_00u
)
writeTV
(
0
x45_00u
)
writeTV
(
0
x51_00u
)
writeTV
(
0
x40_00u
)
writeTV
(
0
x24_00u
)
writeTV
(
0
x4F_00u
)
}
writeTV
(
0
x38_01u
)
writeTV
(
0
x48_01u
)
writeTUVarint
(
0
x50u
,
image
.
width
.
toUInt
())
writeTUVarint
(
0
x58u
,
image
.
height
.
toUInt
())
writeTV
(
0
x60_04u
)
//这个似乎会变 有时候是02, 有时候是03
writeTByteArray
(
0
x6Au
,
value0x6A
)
writeTV
(
0
x70_00u
)
writeTV
(
0
x78_03u
)
writeTV
(
0
x80_01u
)
writeUByte
(
0
u
)
}
}
}
):
OutgoingPacket
=
buildSessionProtoPacket
(
bot
,
sessionKey
,
name
=
"GroupImagePacket.RequestImageId"
,
head
=
requestImageIdHead
,
serializer
=
RequestIdProto
.
serializer
(),
protoObj
=
RequestIdProto
(
body
=
RequestIdProto
.
Body
(
bot
=
bot
.
toInt
(),
group
=
groupInternalId
.
value
.
toInt
(),
md5
=
image
.
md5
,
height
=
image
.
height
,
width
=
image
.
width
)
)
)
private
val
requestImageLinkHead
=
ubyteArrayOf
(
0
x08u
,
0
x01u
,
0
x12u
,
0
x03u
,
0
x98u
,
0
x01u
,
0
x2u
)
@Suppress
(
"FunctionName"
)
fun
RequestImageLink
(
bot
:
UInt
,
sessionKey
:
SessionKey
,
imageId
:
ImageId
imageId
:
ImageId
0x03
):
OutgoingPacket
{
imageId
.
requireLength
()
require
(
imageId
.
value
.
length
==
37
)
{
"ImageId.value.length must == 37"
}
// 00 00 00 07 00 00 00
// [4B]
// 08
// 01 12
// 03 98
// 01 02
// 08 02
//
// 1A [47]
// 08 [A2 FF 8C F0 03] UVarInt
// 10 [DD F1 92 B7 07] UVarInt
// 1A [25] 2F 38 65 32 63 32 38 62 64 2D 35 38 61 31 2D 34 66 37 30 2D 38 39 61 31 2D 65 37 31 39 66 63 33 30 37 65 65 66
// 20 02 30 04 38 20 40 FF 01 50 00 6A 05 32 36 39 33 33 78 01
// 00 00 00 07 00 00 00
// [4B]
// 08 01
// 12 03
// 98 01 02
// 08 02
//
// 1A
// [47]
// 08 [A2 FF 8C F0 03]
// 10 [A6 A7 F1 EA 02]
// 1A [25] 2F 39 61 31 66 37 31 36 32 2D 38 37 30 38 2D 34 39 30 38 2D 38 31 63 30 2D 66 34 63 64 66 33 35 63 38 64 37 65
// 20 02 30 04 38 20 40 FF 01 50 00 6A 05 32 36 39 33 33 78 01
return
buildSessionPacket
(
bot
,
sessionKey
,
version
=
TIMProtocol
.
version0x04
)
{
writeHex
(
"00 00 00 07 00 00"
)
writeUShort
(
0
x004Bu
)
writeUByte
(
0
x08u
)
writeTV
(
0
x01_12u
)
writeTV
(
0
x03_98u
)
writeTV
(
0
x01_02u
)
writeTV
(
0
x08_02u
)
writeUByte
(
0
x1Au
)
writeUByte
(
0
x47u
)
writeTUVarint
(
0
x08u
,
bot
)
writeTUVarint
(
0
x10u
,
bot
)
writeTLV
(
0
x1Au
,
imageId
.
value
.
toByteArray
(
Charsets
.
ISO_8859_1
))
writeHex
(
"20 02 30 04 38 20 40 FF 01 50 00 6A 05 32 36 39 33 33 78 01"
)
}
//require(imageId.value.length == 37) { "ImageId.value.length must == 37" }
//[00 00 00 07] [00 00 00 52] (08 01 12 03 98 01 02) 10 02 22 4E 08 A0 89 F7 B6 03 10 A2 FF 8C F0 03 18 BB 92 94 BF 08 22 10 64 CF BB 65 00 13 8D B5 58 E2 45 1E EA 65 88 E1 28 04 30 02 38 20 40 FF 01 48 00 50 01 5A 05 32 36 39 33 33 60 00 68 00 70 00 78 00 80 01 97 04 88 01 ED 03 90 01 04 A0 01 01
// head 长度 proto 长度 head proto
return
buildSessionProtoPacket
(
bot
,
sessionKey
,
name
=
"GroupImagePacket.RequestImageLink"
,
head
=
requestImageLinkHead
,
serializer
=
RequestLinkProto
.
serializer
(),
protoObj
=
RequestLinkProto
(
body
=
RequestLinkProto
.
Body
(
bot
=
bot
.
toInt
(),
// same bin representation, so will be decoded correctly as a unsigned value in the server
group
=
bot
.
toInt
(),
// TODO 似乎是必须要填group ??
uniqueId
=
imageId
.
uniqueId
.
toInt
(),
md5
=
imageId
.
md5
,
height
=
imageId
.
height
,
width
=
imageId
.
width
)
)
)
}
private
val
value0x6A
:
UByteArray
=
ubyteArrayOf
(
0
x05u
,
0
x32u
,
0
x36u
,
0
x36u
,
0
x35u
,
0
x36u
)
override
suspend
fun
ByteReadPacket
.
decode
(
id
:
PacketId
,
sequenceId
:
UShort
,
handler
:
BotNetworkHandler
<
*
>):
GroupImageResponse
{
discardExact
(
6
)
//00 00 00 05 00 00
discardExact
(
2
)
// 是 protobuf 的长度, 但是是错的
val
bytes
=
readBytes
()
val
headLength
=
readInt
()
val
protoLength
=
readInt
()
discardExact
(
headLength
)
val
bytes
=
readBytes
(
protoLength
)
// println(ByteReadPacket(bytes).readProtoMap())
@Serializable
...
...
@@ -214,6 +270,7 @@ object GroupImagePacket : SessionPacketFactory<GroupImageResponse>() {
@SerialId
(
4
)
val
imageDownloadInfo
:
ImageDownloadInfo
?
=
null
)
debugPrintln
(
"收到返回="
+
bytes
.
toUHexString
())
val
proto
=
ProtoBuf
.
load
(
GroupImageResponseProto
.
serializer
(),
bytes
)
return
when
{
proto
.
imageUploadInfoPacket
!=
null
->
proto
.
imageUploadInfoPacket
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/Image.kt
0 → 100644
View file @
12944417
@
file
:
Suppress
(
"EXPERIMENTAL_API_USAGE"
,
"EXPERIMENTAL_UNSIGNED_LITERALS"
,
"unused"
,
"NO_REFLECTION_IN_CLASS_PATH"
)
package
net.mamoe.mirai.network.protocol.tim.packet.action
import
io.ktor.client.request.get
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.readBytes
import
net.mamoe.mirai.utils.Http
/**
* 图片文件过大
*/
class
OverFileSizeMaxException
:
IllegalStateException
()
interface
ImageLink
{
/**
* 原图
*/
val
original
:
String
suspend
fun
downloadAsByteArray
():
ByteArray
=
download
().
readBytes
()
suspend
fun
download
():
ByteReadPacket
=
Http
.
get
(
original
)
}
/*
/**
* 似乎没有必要. 服务器的返回永远都是 01 00 00 00 02 00 00
*/
@Deprecated("Useless packet")
@AnnotatedId(KnownPacketId.SUBMIT_IMAGE_FILE_NAME)
@PacketVersion(date = "2019.10.26", timVersion = "2.3.2 (21173)")
object SubmitImageFilenamePacket : PacketFactory {
operator fun invoke(
bot: UInt,
target: UInt,
filename: String,
sessionKey: SessionKey
): OutgoingPacket = buildOutgoingPacket {
writeQQ(bot)
writeFully(TIMProtocol.fixVer2)//?
//writeHex("04 00 00 00 01 2E 01 00 00 69 35")
encryptAndWrite(sessionKey) {
writeByte(0x01)
writeQQ(bot)
writeQQ(target)
writeZero(2)
writeUByte(0x02u)
writeRandom(1)
writeHex("00 0A 00 01 00 01")
val name = "UserDataImage:$filename"
writeShort(name.length.toShort())
writeStringUtf8(name)
writeHex("00 00")
writeRandom(2)//这个也与是哪个好友有关?
writeHex("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 2E 01")//35 02? 最后这个值是与是哪个好友有关
//this.debugPrintThis("SubmitImageFilenamePacket")
}
//解密body=01 3E 03 3F A2 7C BC D3 C1 00 00 27 1A 00 0A 00 01 00 01 00 30 55 73 65 72 44 61 74 61 43 75 73 74 6F 6D 46 61 63 65 3A 31 5C 28 5A 53 41 58 40 57 4B 52 4A 5A 31 7E 33 59 4F 53 53 4C 4D 32 4B 49 2E 6A 70 67 00 00 06 E2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 2F 02
//解密body=01 3E 03 3F A2 7C BC D3 C1 00 00 27 1B 00 0A 00 01 00 01 00 30 55 73 65 72 44 61 74 61 43 75 73 74 6F 6D 46 61 63 65 3A 31 5C 28 5A 53 41 58 40 57 4B 52 4A 5A 31 7E 33 59 4F 53 53 4C 4D 32 4B 49 2E 6A 70 67 00 00 06 E2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 2F 02
//解密body=01 3E 03 3F A2 7C BC D3 C1 00 00 27 1C 00 0A 00 01 00 01 00 30 55 73 65 72 44 61 74 61 43 75 73 74 6F 6D 46 61 63 65 3A 31 5C 29 37 42 53 4B 48 32 44 35 54 51 28 5A 35 7D 35 24 56 5D 32 35 49 4E 2E 6A 70 67 00 00 03 73 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 2F 02
}
@PacketVersion(date = "2019.10.19", timVersion = "2.3.2 (21173)")
class Response {
override fun decode() = with(input) {
require(readBytes().contentEquals(expecting))
}
companion object {
private val expecting = byteArrayOf(0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00)
}
}
}*/
// regiion GroupImageResponse
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Message.kt
View file @
12944417
...
...
@@ -5,24 +5,25 @@ package net.mamoe.mirai.network.protocol.tim.packet.event
import
kotlinx.io.core.ByteReadPacket
import
kotlinx.io.core.discardExact
import
kotlinx.io.core.readUInt
import
net.mamoe.mirai.
*
import
net.mamoe.mirai.
Bot
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.MemberPermission
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.event.BroadcastControllable
import
net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.getGroup
import
net.mamoe.mirai.getQQ
import
net.mamoe.mirai.message.*
import
net.mamoe.mirai.message.internal.readMessageChain
import
net.mamoe.mirai.network.protocol.tim.packet.PacketVersion
import
net.mamoe.mirai.network.protocol.tim.packet.action.FriendImageLink
import
net.mamoe.mirai.network.protocol.tim.packet.action.FriendImagePacket
import
net.mamoe.mirai.network.sessionKey
import
net.mamoe.mirai.network.protocol.tim.packet.action.ImageLink
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.io.printTLVMap
import
net.mamoe.mirai.utils.io.read
import
net.mamoe.mirai.utils.io.readTLVMap
import
net.mamoe.mirai.utils.io.readUShortLVByteArray
import
net.mamoe.mirai.withSession
import
kotlin.jvm.JvmName
/**
...
...
@@ -87,8 +88,8 @@ abstract class MessagePacketBase<TSubject : Contact> : EventPacket, BotEvent() {
// endregion
// region Image download
suspend
inline
fun
Image
.
getLink
():
ImageLink
=
bot
.
withSession
{
getLink
()
}
suspend
fun
Image
.
getLink
():
FriendImageLink
=
bot
.
withSession
{
FriendImagePacket
.
RequestImageLink
(
bot
.
qqAccount
,
bot
.
sessionKey
,
id
).
sendAndExpect
()
}
suspend
inline
fun
Image
.
downloadAsByteArray
():
ByteArray
=
getLink
().
downloadAsByteArray
()
suspend
inline
fun
Image
.
download
():
ByteReadPacket
=
getLink
().
download
()
// endregion
...
...
@@ -106,6 +107,7 @@ data class GroupMessage(
override
val
sender
:
QQ
,
override
val
message
:
MessageChain
=
NullMessageChain
)
:
MessagePacket
<
Group
>()
{
override
val
subject
:
Group
get
()
=
group
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
View file @
12944417
...
...
@@ -7,10 +7,7 @@ import kotlinx.io.core.Input
import
net.mamoe.mirai.contact.Contact
import
net.mamoe.mirai.contact.Group
import
net.mamoe.mirai.contact.QQ
import
net.mamoe.mirai.message.Image
import
net.mamoe.mirai.message.ImageId
import
net.mamoe.mirai.message.image
import
net.mamoe.mirai.message.sendTo
import
net.mamoe.mirai.message.*
import
net.mamoe.mirai.network.protocol.tim.packet.action.uploadImage
import
net.mamoe.mirai.utils.io.toUHexString
...
...
@@ -52,7 +49,8 @@ class ExternalImage(
/**
* 用于发送消息的 [ImageId]
*/
val
groupImageId
:
ImageId
by
lazy
{
ImageId
(
"{${md5[0..3]}-${md5[4..5]}-${md5[6..7]}-${md5[8..9]}-${md5[10..15]}}.$format"
)
}
@Suppress
(
"EXPERIMENTAL_UNSIGNED_LITERALS"
)
val
groupImageId
:
ImageId
by
lazy
{
ImageId0x03
(
"{${md5[0..3]}-${md5[4..5]}-${md5[6..7]}-${md5[8..9]}-${md5[10..15]}}.$format"
,
0
u
,
height
,
width
)
}
override
fun
toString
():
String
=
"[ExternalImage(${width}x$height $format)]"
}
...
...
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