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
35dca403
Commit
35dca403
authored
Feb 03, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Image upload
parent
8e54e716
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1155 additions
and
38 deletions
+1155
-38
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
...ommonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
+79
-2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt
...tlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt
+5
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/Codec.kt
...kotlin/net/mamoe/mirai/qqandroid/network/highway/Codec.kt
+129
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Cmd0x388.kt
...e/mirai/qqandroid/network/protocol/data/proto/Cmd0x388.kt
+279
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Highway.kt
...oe/mirai/qqandroid/network/protocol/data/proto/Highway.kt
+454
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
.../mirai/qqandroid/network/protocol/packet/PacketFactory.kt
+7
-1
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
+8
-11
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImgStore.kt
.../qqandroid/network/protocol/packet/chat/image/ImgStore.kt
+101
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/LongConn.kt
.../qqandroid/network/protocol/packet/chat/image/LongConn.kt
+42
-0
mirai-core-qqandroid/src/jvmTest/kotlin/test/ProtoBufDataClassGenerator.kt
...oid/src/jvmTest/kotlin/test/ProtoBufDataClassGenerator.kt
+3
-1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
...re/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
+0
-2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
.../commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
+44
-18
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/ExternalImageJvm.kt
.../jvmMain/kotlin/net/mamoe/mirai/utils/ExternalImageJvm.kt
+4
-2
No files found.
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/ContactImpl.kt
View file @
35dca403
package
net.mamoe.mirai.qqandroid
import
kotlinx.io.core.readBytes
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.data.FriendNameRemark
import
net.mamoe.mirai.data.PreviousNameList
import
net.mamoe.mirai.data.Profile
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.NotOnlineImageFromFile
import
net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.network.highway.Highway
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import
net.mamoe.mirai.qqandroid.network.protocol.packet.withUse
import
net.mamoe.mirai.qqandroid.utils.toIpV4AddressString
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.MiraiInternalAPI
import
net.mamoe.mirai.utils.cryptor.contentToString
import
net.mamoe.mirai.utils.getValue
import
net.mamoe.mirai.utils.io.PlatformSocket
import
net.mamoe.mirai.utils.io.toUHexString
import
net.mamoe.mirai.utils.unsafeWeakRef
import
kotlin.coroutines.CoroutineContext
...
...
@@ -116,7 +127,73 @@ internal class GroupImpl(
}
override
suspend
fun
uploadImage
(
image
:
ExternalImage
):
Image
{
TODO
(
"not implemented"
)
bot
.
network
.
run
{
val
response
:
ImgStore
.
GroupPicUp
.
Response
=
ImgStore
.
GroupPicUp
(
bot
.
client
,
uin
=
bot
.
uin
,
groupCode
=
id
,
md5
=
image
.
md5
,
size
=
image
.
inputSize
,
picWidth
=
image
.
width
,
picHeight
=
image
.
height
,
picType
=
image
.
imageType
,
filename
=
image
.
filename
).
sendAndExpect
()
when
(
response
)
{
is
ImgStore
.
GroupPicUp
.
Response
.
Failed
->
error
(
"upload group image failed with reason ${response.message}"
)
is
ImgStore
.
GroupPicUp
.
Response
.
FileExists
->
{
val
resourceId
=
image
.
calculateImageResourceId
()
return
NotOnlineImageFromFile
(
resourceId
=
resourceId
,
md5
=
response
.
fileInfo
.
fileMd5
,
filepath
=
resourceId
,
fileLength
=
response
.
fileInfo
.
fileSize
.
toInt
(),
height
=
response
.
fileInfo
.
fileHeight
,
width
=
response
.
fileInfo
.
fileWidth
,
imageType
=
response
.
fileInfo
.
fileType
)
}
is
ImgStore
.
GroupPicUp
.
Response
.
RequireUpload
->
{
val
socket
=
PlatformSocket
()
socket
.
connect
(
response
.
uploadIpList
.
first
().
toIpV4AddressString
().
also
{
println
(
"serverIp=$it"
)
},
response
.
uploadPortList
.
first
())
// socket.use {
socket
.
send
(
Highway
.
RequestDataTrans
(
uin
=
bot
.
uin
,
command
=
"PicUp.DataUp"
,
buildVer
=
bot
.
client
.
buildVer
,
uKey
=
response
.
uKey
,
data
=
image
.
input
,
dataSize
=
image
.
inputSize
.
toInt
(),
md5
=
image
.
md5
,
sequenceId
=
bot
.
client
.
nextHighwayDataTransSequenceId
()
)
)
// }
//0A 3C 08 01 12 0A 31 39 39 34 37 30 31 30 32 31 1A 0C 50 69 63 55 70 2E 44 61 74 61 55 70 20 E9 A7 05 28 00 30 BD DB 8B 80 02 38 80 20 40 02 4A 0A 38 2E 32 2E 30 2E 31 32 39 36 50 84 10 12 3D 08 00 10 FD 08 18 00 20 FD 08 28 C6 01 38 00 42 10 D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E 4A 10 D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E 50 89 92 A2 FB 06 58 00 60 00 18 53 20 01 28 00 30 04 3A 00 40 E6 B7 F7 D9 80 2E 48 00 50 00
socket
.
read
().
withUse
{
readByte
()
val
headLength
=
readInt
()
val
bodyLength
=
readInt
()
val
proto
=
readProtoBuf
(
CSDataHighwayHead
.
RspDataHighwayHead
.
serializer
(),
length
=
headLength
)
println
(
proto
.
contentToString
())
println
(
readBytes
(
bodyLength
).
toUHexString
())
}
val
resourceId
=
image
.
calculateImageResourceId
()
return
NotOnlineImageFromFile
(
resourceId
=
resourceId
,
md5
=
image
.
md5
,
filepath
=
resourceId
,
fileLength
=
image
.
inputSize
.
toInt
(),
height
=
image
.
height
,
width
=
image
.
width
,
imageType
=
image
.
imageType
)
}
}
}
}
}
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt
View file @
35dca403
...
...
@@ -95,7 +95,8 @@ internal open class QQAndroidClient(
var
openAppId
:
Long
=
715019303L
val
apkVersionName
:
ByteArray
=
"8.2.0"
.
toByteArray
()
val
apkVersionName
:
ByteArray
get
()
=
"8.2.0"
.
toByteArray
()
val
buildVer
:
String
get
()
=
"8.2.0.1296"
private
val
messageSequenceId
:
AtomicInt
=
atomic
(
0
)
internal
fun
atomicNextMessageSequenceId
():
Int
=
messageSequenceId
.
getAndAdd
(
2
)
...
...
@@ -103,6 +104,9 @@ internal open class QQAndroidClient(
private
val
requestPacketRequestId
:
AtomicInt
=
atomic
(
1921334513
)
internal
fun
nextRequestPacketRequestId
():
Int
=
requestPacketRequestId
.
getAndAdd
(
2
)
private
val
highwayDataTransSequenceId
:
AtomicInt
=
atomic
(
87017
)
internal
fun
nextHighwayDataTransSequenceId
():
Int
=
highwayDataTransSequenceId
.
getAndAdd
(
2
)
val
appClientVersion
:
Int
=
0
var
networkType
:
NetworkType
=
NetworkType
.
WIFI
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/Codec.kt
0 → 100644
View file @
35dca403
package
net.mamoe.mirai.qqandroid.network.highway
import
io.ktor.client.HttpClient
import
io.ktor.client.request.post
import
io.ktor.http.ContentType
import
io.ktor.http.HttpStatusCode
import
io.ktor.http.URLProtocol
import
io.ktor.http.content.OutgoingContent
import
io.ktor.http.userAgent
import
kotlinx.coroutines.io.ByteWriteChannel
import
kotlinx.io.core.*
import
kotlinx.io.pool.useInstance
import
net.mamoe.mirai.qqandroid.io.serialization.toByteArray
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead
import
net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
import
net.mamoe.mirai.utils.io.ByteArrayPool
@Suppress
(
"SpellCheckingInspection"
)
internal
suspend
inline
fun
HttpClient
.
postImage
(
htcmd
:
String
,
uin
:
Long
,
groupcode
:
Long
?,
imageInput
:
Input
,
inputSize
:
Long
,
uKeyHex
:
String
):
Boolean
=
try
{
post
<
HttpStatusCode
>
{
url
{
protocol
=
URLProtocol
.
HTTP
host
=
"htdata2.qq.com"
path
(
"cgi-bin/httpconn"
)
parameters
[
"htcmd"
]
=
htcmd
parameters
[
"uin"
]
=
uin
.
toString
()
if
(
groupcode
!=
null
)
parameters
[
"groupcode"
]
=
groupcode
.
toString
()
parameters
[
"term"
]
=
"pc"
parameters
[
"ver"
]
=
"5603"
parameters
[
"filesize"
]
=
inputSize
.
toString
()
parameters
[
"range"
]
=
0
.
toString
()
parameters
[
"ukey"
]
=
uKeyHex
userAgent
(
"QQClient"
)
}
body
=
object
:
OutgoingContent
.
WriteChannelContent
()
{
override
val
contentType
:
ContentType
=
ContentType
.
Image
.
Any
override
val
contentLength
:
Long
=
inputSize
override
suspend
fun
writeTo
(
channel
:
ByteWriteChannel
)
{
ByteArrayPool
.
useInstance
{
buffer
:
ByteArray
->
var
size
:
Int
while
(
imageInput
.
readAvailable
(
buffer
).
also
{
size
=
it
}
!=
0
)
{
channel
.
writeFully
(
buffer
,
0
,
size
)
}
}
}
}
}
==
HttpStatusCode
.
OK
}
finally
{
imageInput
.
close
()
}
object
Highway
{
fun
RequestDataTrans
(
uin
:
Long
,
command
:
String
,
sequenceId
:
Int
,
buildVer
:
String
,
appId
:
Int
=
537062845
,
dataFlag
:
Int
=
4096
,
commandId
:
Int
=
2
,
localId
:
Int
=
2052
,
uKey
:
ByteArray
,
data
:
Input
,
dataSize
:
Int
,
md5
:
ByteArray
):
ByteReadPacket
{
val
dataHighwayHead
=
CSDataHighwayHead
.
DataHighwayHead
(
version
=
1
,
uin
=
uin
.
toString
(),
command
=
command
,
seq
=
sequenceId
,
retryTimes
=
0
,
appid
=
appId
,
dataflag
=
dataFlag
,
commandId
=
commandId
,
buildVer
=
buildVer
,
localeId
=
localId
)
val
segHead
=
CSDataHighwayHead
.
SegHead
(
datalength
=
dataSize
,
filesize
=
dataSize
.
toLong
()
and
0
xFFffFFff
,
serviceticket
=
uKey
,
md5
=
md5
,
fileMd5
=
md5
)
return
Codec
.
buildC2SData
(
dataHighwayHead
,
segHead
,
EMPTY_BYTE_ARRAY
,
null
,
data
,
dataSize
)
}
private
object
Codec
{
fun
buildC2SData
(
dataHighwayHead
:
CSDataHighwayHead
.
DataHighwayHead
,
segHead
:
CSDataHighwayHead
.
SegHead
,
extendInfo
:
ByteArray
,
loginSigHead
:
CSDataHighwayHead
.
LoginSigHead
?,
body
:
Input
,
bodySize
:
Int
):
ByteReadPacket
{
val
head
=
CSDataHighwayHead
.
ReqDataHighwayHead
(
msgBasehead
=
dataHighwayHead
,
msgSeghead
=
segHead
,
reqExtendinfo
=
extendInfo
,
msgLoginSigHead
=
loginSigHead
).
toByteArray
(
CSDataHighwayHead
.
ReqDataHighwayHead
.
serializer
())
return
buildPacket
{
writeByte
(
40
)
writeInt
(
head
.
size
)
writeInt
(
bodySize
)
writeFully
(
head
)
body
.
copyTo
(
this
)
writeByte
(
41
)
}
}
}
}
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Cmd0x388.kt
0 → 100644
View file @
35dca403
package
net.mamoe.mirai.qqandroid.network.protocol.data.proto
import
kotlinx.serialization.SerialId
import
kotlinx.serialization.Serializable
import
net.mamoe.mirai.qqandroid.io.ProtoBuf
import
net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
@Serializable
class
Cmd0x388
:
ProtoBuf
{
@Serializable
class
DelImgReq
(
@SerialId
(
1
)
val
srcUin
:
Long
=
0L
,
@SerialId
(
2
)
val
dstUin
:
Long
=
0L
,
@SerialId
(
3
)
val
reqTerm
:
Int
=
0
,
@SerialId
(
4
)
val
reqPlatformType
:
Int
=
0
,
@SerialId
(
5
)
val
buType
:
Int
=
0
,
@SerialId
(
6
)
val
buildVer
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
7
)
val
fileResid
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
8
)
val
picWidth
:
Int
=
0
,
@SerialId
(
9
)
val
picHeight
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
DelImgRsp
(
@SerialId
(
1
)
val
result
:
Int
=
0
,
@SerialId
(
2
)
val
failMsg
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
fileResid
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
ExpRoamExtendInfo
(
@SerialId
(
1
)
val
resid
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
ExpRoamPicInfo
(
@SerialId
(
1
)
val
shopFlag
:
Int
=
0
,
@SerialId
(
2
)
val
pkgId
:
Int
=
0
,
@SerialId
(
3
)
val
picId
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
ExtensionCommPicTryUp
(
@SerialId
(
1
)
val
bytesExtinfo
:
List
<
ByteArray
>?
=
null
)
:
ProtoBuf
@Serializable
class
ExtensionExpRoamTryUp
(
@SerialId
(
1
)
val
msgExproamPicInfo
:
List
<
ExpRoamPicInfo
>?
=
null
)
:
ProtoBuf
@Serializable
class
GetImgUrlReq
(
@SerialId
(
1
)
val
groupCode
:
Long
=
0L
,
@SerialId
(
2
)
val
dstUin
:
Long
=
0L
,
@SerialId
(
3
)
val
fileid
:
Long
=
0L
,
@SerialId
(
4
)
val
fileMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
5
)
val
urlFlag
:
Int
=
0
,
@SerialId
(
6
)
val
urlType
:
Int
=
0
,
@SerialId
(
7
)
val
reqTerm
:
Int
=
0
,
@SerialId
(
8
)
val
reqPlatformType
:
Int
=
0
,
@SerialId
(
9
)
val
innerIp
:
Int
=
0
,
@SerialId
(
10
)
val
buType
:
Int
=
0
,
@SerialId
(
11
)
val
buildVer
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
12
)
val
fileId
:
Long
=
0L
,
@SerialId
(
13
)
val
fileSize
:
Long
=
0L
,
@SerialId
(
14
)
val
originalPic
:
Int
=
0
,
@SerialId
(
15
)
val
retryReq
:
Int
=
0
,
@SerialId
(
16
)
val
fileHeight
:
Int
=
0
,
@SerialId
(
17
)
val
fileWidth
:
Int
=
0
,
@SerialId
(
18
)
val
picType
:
Int
=
0
,
@SerialId
(
19
)
val
picUpTimestamp
:
Int
=
0
,
@SerialId
(
20
)
val
reqTransferType
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
GetImgUrlRsp
(
@SerialId
(
1
)
val
fileid
:
Long
=
0L
,
@SerialId
(
2
)
val
fileMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
result
:
Int
=
0
,
@SerialId
(
4
)
val
failMsg
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
5
)
val
msgImgInfo
:
ImgInfo
?
=
null
,
@SerialId
(
6
)
val
bytesThumbDownUrl
:
List
<
ByteArray
>?
=
null
,
@SerialId
(
7
)
val
bytesOriginalDownUrl
:
List
<
ByteArray
>?
=
null
,
@SerialId
(
8
)
val
bytesBigDownUrl
:
List
<
ByteArray
>?
=
null
,
@SerialId
(
9
)
val
uint32DownIp
:
List
<
Int
>?
=
null
,
@SerialId
(
10
)
val
uint32DownPort
:
List
<
Int
>?
=
null
,
@SerialId
(
11
)
val
downDomain
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
12
)
val
thumbDownPara
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
13
)
val
originalDownPara
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
14
)
val
bigDownPara
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
15
)
val
fileId
:
Long
=
0L
,
@SerialId
(
16
)
val
autoDownType
:
Int
=
0
,
@SerialId
(
17
)
val
uint32OrderDownType
:
List
<
Int
>?
=
null
,
@SerialId
(
19
)
val
bigThumbDownPara
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
20
)
val
httpsUrlFlag
:
Int
=
0
,
@SerialId
(
26
)
val
msgDownIp6
:
List
<
IPv6Info
>?
=
null
,
@SerialId
(
27
)
val
clientIp6
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
GetPttUrlReq
(
@SerialId
(
1
)
val
groupCode
:
Long
=
0L
,
@SerialId
(
2
)
val
dstUin
:
Long
=
0L
,
@SerialId
(
3
)
val
fileid
:
Long
=
0L
,
@SerialId
(
4
)
val
fileMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
5
)
val
reqTerm
:
Int
=
0
,
@SerialId
(
6
)
val
reqPlatformType
:
Int
=
0
,
@SerialId
(
7
)
val
innerIp
:
Int
=
0
,
@SerialId
(
8
)
val
buType
:
Int
=
0
,
@SerialId
(
9
)
val
buildVer
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
10
)
val
fileId
:
Long
=
0L
,
@SerialId
(
11
)
val
fileKey
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
12
)
val
codec
:
Int
=
0
,
@SerialId
(
13
)
val
buId
:
Int
=
0
,
@SerialId
(
14
)
val
reqTransferType
:
Int
=
0
,
@SerialId
(
15
)
val
isAuto
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
GetPttUrlRsp
(
@SerialId
(
1
)
val
fileid
:
Long
=
0L
,
@SerialId
(
2
)
val
fileMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
result
:
Int
=
0
,
@SerialId
(
4
)
val
failMsg
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
5
)
val
bytesDownUrl
:
List
<
ByteArray
>?
=
null
,
@SerialId
(
6
)
val
uint32DownIp
:
List
<
Int
>?
=
null
,
@SerialId
(
7
)
val
uint32DownPort
:
List
<
Int
>?
=
null
,
@SerialId
(
8
)
val
downDomain
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
9
)
val
downPara
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
10
)
val
fileId
:
Long
=
0L
,
@SerialId
(
11
)
val
transferType
:
Int
=
0
,
@SerialId
(
12
)
val
allowRetry
:
Int
=
0
,
@SerialId
(
26
)
val
msgDownIp6
:
List
<
IPv6Info
>?
=
null
,
@SerialId
(
27
)
val
clientIp6
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
28
)
val
strDomain
:
String
=
""
)
:
ProtoBuf
@Suppress
(
"ArrayInDataClass"
)
@Serializable
data class
ImgInfo
(
@SerialId
(
1
)
val
fileMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
fileType
:
Int
=
0
,
@SerialId
(
3
)
val
fileSize
:
Long
=
0L
,
@SerialId
(
4
)
val
fileWidth
:
Int
=
0
,
@SerialId
(
5
)
val
fileHeight
:
Int
=
0
)
:
ProtoBuf
{
override
fun
toString
():
String
{
return
"ImgInfo(fileMd5=${fileMd5.contentToString()}, fileType=$fileType, fileSize=$fileSize, fileWidth=$fileWidth, fileHeight=$fileHeight)"
}
}
@Serializable
class
IPv6Info
(
@SerialId
(
1
)
val
ip6
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
port
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
PicSize
(
@SerialId
(
1
)
val
original
:
Int
=
0
,
@SerialId
(
2
)
val
thumb
:
Int
=
0
,
@SerialId
(
3
)
val
high
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
ReqBody
(
@SerialId
(
1
)
val
netType
:
Int
=
0
,
@SerialId
(
2
)
val
subcmd
:
Int
=
0
,
@SerialId
(
3
)
val
msgTryupImgReq
:
List
<
TryUpImgReq
>?
=
null
,
@SerialId
(
4
)
val
msgGetimgUrlReq
:
List
<
GetImgUrlReq
>?
=
null
,
@SerialId
(
5
)
val
msgTryupPttReq
:
List
<
TryUpPttReq
>?
=
null
,
@SerialId
(
6
)
val
msgGetpttUrlReq
:
List
<
GetPttUrlReq
>?
=
null
,
@SerialId
(
7
)
val
commandId
:
Int
=
0
,
@SerialId
(
8
)
val
msgDelImgReq
:
List
<
DelImgReq
>?
=
null
,
@SerialId
(
1001
)
val
extension
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
RspBody
(
@SerialId
(
1
)
val
clientIp
:
Int
=
0
,
@SerialId
(
2
)
val
subcmd
:
Int
=
0
,
@SerialId
(
3
)
val
msgTryupImgRsp
:
List
<
TryUpImgRsp
>?
=
null
,
@SerialId
(
4
)
val
msgGetimgUrlRsp
:
List
<
GetImgUrlRsp
>?
=
null
,
@SerialId
(
5
)
val
msgTryupPttRsp
:
List
<
TryUpPttRsp
>?
=
null
,
@SerialId
(
6
)
val
msgGetpttUrlRsp
:
List
<
GetPttUrlRsp
>?
=
null
,
@SerialId
(
7
)
val
msgDelImgRsp
:
List
<
DelImgRsp
>?
=
null
)
:
ProtoBuf
@Serializable
class
TryUpImgReq
(
@SerialId
(
1
)
val
groupCode
:
Long
=
0L
,
@SerialId
(
2
)
val
srcUin
:
Long
=
0L
,
@SerialId
(
3
)
val
fileId
:
Long
=
0L
,
@SerialId
(
4
)
val
fileMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
5
)
val
fileSize
:
Long
=
0L
,
@SerialId
(
6
)
val
fileName
:
String
=
""
,
@SerialId
(
7
)
val
srcTerm
:
Int
=
0
,
@SerialId
(
8
)
val
platformType
:
Int
=
0
,
@SerialId
(
9
)
val
buType
:
Int
=
0
,
@SerialId
(
10
)
val
picWidth
:
Int
=
0
,
@SerialId
(
11
)
val
picHeight
:
Int
=
0
,
@SerialId
(
12
)
val
picType
:
Int
=
0
,
@SerialId
(
13
)
val
buildVer
:
String
=
""
,
@SerialId
(
14
)
val
innerIp
:
Int
=
0
,
@SerialId
(
15
)
val
appPicType
:
Int
=
0
,
@SerialId
(
16
)
val
originalPic
:
Int
=
0
,
@SerialId
(
17
)
val
fileIndex
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
18
)
val
dstUin
:
Long
=
0L
,
@SerialId
(
19
)
val
srvUpload
:
Int
=
0
,
@SerialId
(
20
)
val
transferUrl
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
TryUpImgRsp
(
@SerialId
(
1
)
val
fileId
:
Long
=
0L
,
@SerialId
(
2
)
val
result
:
Int
=
0
,
@SerialId
(
3
)
val
failMsg
:
String
=
""
,
@SerialId
(
4
)
val
boolFileExit
:
Boolean
=
false
,
@SerialId
(
5
)
val
msgImgInfo
:
ImgInfo
?
=
null
,
@SerialId
(
6
)
val
uint32UpIp
:
List
<
Int
>?
=
null
,
@SerialId
(
7
)
val
uint32UpPort
:
List
<
Int
>?
=
null
,
@SerialId
(
8
)
val
upUkey
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
9
)
val
fileid
:
Long
=
0L
,
@SerialId
(
10
)
val
upOffset
:
Long
=
0L
,
@SerialId
(
11
)
val
blockSize
:
Long
=
0L
,
@SerialId
(
12
)
val
boolNewBigChan
:
Boolean
=
false
,
@SerialId
(
26
)
val
msgUpIp6
:
List
<
IPv6Info
>?
=
null
,
@SerialId
(
27
)
val
clientIp6
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
1001
)
val
msgInfo4busi
:
TryUpInfo4Busi
?
=
null
)
:
ProtoBuf
@Serializable
class
TryUpInfo4Busi
(
@SerialId
(
1
)
val
downDomain
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
thumbDownUrl
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
originalDownUrl
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
4
)
val
bigDownUrl
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
5
)
val
fileResid
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
TryUpPttReq
(
@SerialId
(
1
)
val
groupCode
:
Long
=
0L
,
@SerialId
(
2
)
val
srcUin
:
Long
=
0L
,
@SerialId
(
3
)
val
fileId
:
Long
=
0L
,
@SerialId
(
4
)
val
fileMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
5
)
val
fileSize
:
Long
=
0L
,
@SerialId
(
6
)
val
fileName
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
7
)
val
srcTerm
:
Int
=
0
,
@SerialId
(
8
)
val
platformType
:
Int
=
0
,
@SerialId
(
9
)
val
buType
:
Int
=
0
,
@SerialId
(
10
)
val
buildVer
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
11
)
val
innerIp
:
Int
=
0
,
@SerialId
(
12
)
val
voiceLength
:
Int
=
0
,
@SerialId
(
13
)
val
boolNewUpChan
:
Boolean
=
false
,
@SerialId
(
14
)
val
codec
:
Int
=
0
,
@SerialId
(
15
)
val
voiceType
:
Int
=
0
,
@SerialId
(
16
)
val
buId
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
TryUpPttRsp
(
@SerialId
(
1
)
val
fileId
:
Long
=
0L
,
@SerialId
(
2
)
val
result
:
Int
=
0
,
@SerialId
(
3
)
val
failMsg
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
4
)
val
boolFileExit
:
Boolean
=
false
,
@SerialId
(
5
)
val
uint32UpIp
:
List
<
Int
>?
=
null
,
@SerialId
(
6
)
val
uint32UpPort
:
List
<
Int
>?
=
null
,
@SerialId
(
7
)
val
upUkey
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
8
)
val
fileid
:
Long
=
0L
,
@SerialId
(
9
)
val
upOffset
:
Long
=
0L
,
@SerialId
(
10
)
val
blockSize
:
Long
=
0L
,
@SerialId
(
11
)
val
fileKey
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
12
)
val
channelType
:
Int
=
0
,
@SerialId
(
26
)
val
msgUpIp6
:
List
<
IPv6Info
>?
=
null
,
@SerialId
(
27
)
val
clientIp6
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
}
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Highway.kt
0 → 100644
View file @
35dca403
package
net.mamoe.mirai.qqandroid.network.protocol.data.proto
import
kotlinx.serialization.SerialId
import
kotlinx.serialization.Serializable
import
kotlinx.serialization.protobuf.ProtoNumberType
import
kotlinx.serialization.protobuf.ProtoType
import
net.mamoe.mirai.qqandroid.io.ProtoBuf
import
net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
@Serializable
class
BdhExtinfo
:
ProtoBuf
{
@Serializable
class
CommFileExtReq
(
@SerialId
(
1
)
val
actionType
:
Int
=
0
,
@SerialId
(
2
)
val
uuid
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
CommFileExtRsp
(
@SerialId
(
1
)
val
int32Retcode
:
Int
=
0
,
@SerialId
(
2
)
val
downloadUrl
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
PicInfo
(
@SerialId
(
1
)
val
idx
:
Int
=
0
,
@SerialId
(
2
)
val
size
:
Int
=
0
,
@SerialId
(
3
)
val
binMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
4
)
val
type
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
QQVoiceExtReq
(
@SerialId
(
1
)
val
qid
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
fmt
:
Int
=
0
,
@SerialId
(
3
)
val
rate
:
Int
=
0
,
@SerialId
(
4
)
val
bits
:
Int
=
0
,
@SerialId
(
5
)
val
channel
:
Int
=
0
,
@SerialId
(
6
)
val
pinyin
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
QQVoiceExtRsp
(
@SerialId
(
1
)
val
qid
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
int32Retcode
:
Int
=
0
,
@SerialId
(
3
)
val
msgResult
:
List
<
QQVoiceResult
>?
=
null
)
:
ProtoBuf
@Serializable
class
QQVoiceResult
(
@SerialId
(
1
)
val
text
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
pinyin
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
source
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
ShortVideoReqExtInfo
(
@SerialId
(
1
)
val
cmd
:
Int
=
0
,
@SerialId
(
2
)
val
sessionId
:
Long
=
0L
,
@SerialId
(
3
)
val
msgThumbinfo
:
PicInfo
?
=
null
,
@SerialId
(
4
)
val
msgVideoinfo
:
VideoInfo
?
=
null
,
@SerialId
(
5
)
val
msgShortvideoSureReq
:
ShortVideoSureReqInfo
?
=
null
,
@SerialId
(
6
)
val
boolIsMergeCmdBeforeData
:
Boolean
=
false
)
:
ProtoBuf
@Serializable
class
ShortVideoRspExtInfo
(
@SerialId
(
1
)
val
cmd
:
Int
=
0
,
@SerialId
(
2
)
val
sessionId
:
Long
=
0L
,
@SerialId
(
3
)
val
int32Retcode
:
Int
=
0
,
@SerialId
(
4
)
val
errinfo
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
5
)
val
msgThumbinfo
:
PicInfo
?
=
null
,
@SerialId
(
6
)
val
msgVideoinfo
:
VideoInfo
?
=
null
,
@SerialId
(
7
)
val
msgShortvideoSureRsp
:
ShortVideoSureRspInfo
?
=
null
,
@SerialId
(
8
)
val
retryFlag
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
ShortVideoSureReqInfo
(
@SerialId
(
1
)
val
fromuin
:
Long
=
0L
,
@SerialId
(
2
)
val
chatType
:
Int
=
0
,
@SerialId
(
3
)
val
touin
:
Long
=
0L
,
@SerialId
(
4
)
val
groupCode
:
Long
=
0L
,
@SerialId
(
5
)
val
clientType
:
Int
=
0
,
@SerialId
(
6
)
val
msgThumbinfo
:
PicInfo
?
=
null
,
@SerialId
(
7
)
val
msgMergeVideoinfo
:
List
<
VideoInfo
>?
=
null
,
@SerialId
(
8
)
val
msgDropVideoinfo
:
List
<
VideoInfo
>?
=
null
,
@SerialId
(
9
)
val
businessType
:
Int
=
0
,
@SerialId
(
10
)
val
subBusinessType
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
ShortVideoSureRspInfo
(
@SerialId
(
1
)
val
fileid
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
ukey
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
msgVideoinfo
:
VideoInfo
?
=
null
,
@SerialId
(
4
)
val
mergeCost
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
StoryVideoExtReq
:
ProtoBuf
@Serializable
class
StoryVideoExtRsp
(
@SerialId
(
1
)
val
int32Retcode
:
Int
=
0
,
@SerialId
(
2
)
val
msg
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
cdnUrl
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
4
)
val
fileKey
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
5
)
val
fileId
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
UploadPicExtInfo
(
@SerialId
(
1
)
val
fileResid
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
downloadUrl
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
thumbDownloadUrl
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
VideoInfo
(
@SerialId
(
1
)
val
idx
:
Int
=
0
,
@SerialId
(
2
)
val
size
:
Int
=
0
,
@SerialId
(
3
)
val
binMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
4
)
val
format
:
Int
=
0
,
@SerialId
(
5
)
val
resLen
:
Int
=
0
,
@SerialId
(
6
)
val
resWidth
:
Int
=
0
,
@SerialId
(
7
)
val
time
:
Int
=
0
,
@SerialId
(
8
)
val
starttime
:
Long
=
0L
,
@SerialId
(
9
)
val
isAudio
:
Int
=
0
)
:
ProtoBuf
}
@Serializable
class
CSDataHighwayHead
:
ProtoBuf
{
@Serializable
class
C2CCommonExtendinfo
(
@SerialId
(
1
)
val
infoId
:
Int
=
0
,
@SerialId
(
2
)
val
msgFilterExtendinfo
:
FilterExtendinfo
?
=
null
)
:
ProtoBuf
@Serializable
class
DataHighwayHead
(
@SerialId
(
1
)
val
version
:
Int
=
0
,
@SerialId
(
2
)
val
uin
:
String
=
""
,
@SerialId
(
3
)
val
command
:
String
=
""
,
@SerialId
(
4
)
val
seq
:
Int
=
0
,
@SerialId
(
5
)
val
retryTimes
:
Int
=
0
,
@SerialId
(
6
)
val
appid
:
Int
=
0
,
@SerialId
(
7
)
val
dataflag
:
Int
=
0
,
@SerialId
(
8
)
val
commandId
:
Int
=
0
,
@SerialId
(
9
)
val
buildVer
:
String
=
""
,
@SerialId
(
10
)
val
localeId
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
DataHole
(
@SerialId
(
1
)
val
begin
:
Long
=
0L
,
@SerialId
(
2
)
val
end
:
Long
=
0L
)
:
ProtoBuf
@Serializable
class
FilterExtendinfo
(
@SerialId
(
1
)
val
filterFlag
:
Int
=
0
,
@SerialId
(
2
)
val
msgImageFilterRequest
:
ImageFilterRequest
?
=
null
)
:
ProtoBuf
@Serializable
class
FilterStyle
(
@SerialId
(
1
)
val
styleId
:
Int
=
0
,
@SerialId
(
2
)
val
styleName
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
ImageFilterRequest
(
@SerialId
(
1
)
val
sessionId
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
clientIp
:
Int
=
0
,
@SerialId
(
3
)
val
uin
:
Long
=
0L
,
@SerialId
(
4
)
val
style
:
FilterStyle
?
=
null
,
@SerialId
(
5
)
val
width
:
Int
=
0
,
@SerialId
(
6
)
val
height
:
Int
=
0
,
@SerialId
(
7
)
val
imageData
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
ImageFilterResponse
(
@SerialId
(
1
)
val
retCode
:
Int
=
0
,
@SerialId
(
2
)
val
imageData
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
costTime
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
LoginSigHead
(
@SerialId
(
1
)
val
loginsigType
:
Int
=
0
,
@SerialId
(
2
)
val
loginsig
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
NewServiceTicket
(
@SerialId
(
1
)
val
signature
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
ukey
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
@Serializable
class
PicInfoExt
(
@SerialId
(
1
)
val
picWidth
:
Int
=
0
,
@SerialId
(
2
)
val
picHeight
:
Int
=
0
,
@SerialId
(
3
)
val
picFlag
:
Int
=
0
,
@SerialId
(
4
)
val
busiType
:
Int
=
0
,
@SerialId
(
5
)
val
srcTerm
:
Int
=
0
,
@SerialId
(
6
)
val
platType
:
Int
=
0
,
@SerialId
(
7
)
val
netType
:
Int
=
0
,
@SerialId
(
8
)
val
imgType
:
Int
=
0
,
@SerialId
(
9
)
val
appPicType
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
PicRspExtInfo
(
@SerialId
(
1
)
val
skey
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
clientIp
:
Int
=
0
,
@SerialId
(
3
)
val
upOffset
:
Long
=
0L
,
@SerialId
(
4
)
val
blockSize
:
Long
=
0L
)
:
ProtoBuf
@Serializable
class
QueryHoleRsp
(
@SerialId
(
1
)
val
result
:
Int
=
0
,
@SerialId
(
2
)
val
dataHole
:
List
<
DataHole
>?
=
null
,
@SerialId
(
3
)
val
boolCompFlag
:
Boolean
=
false
)
:
ProtoBuf
@Serializable
class
ReqDataHighwayHead
(
@SerialId
(
1
)
val
msgBasehead
:
DataHighwayHead
?
=
null
,
@SerialId
(
2
)
val
msgSeghead
:
SegHead
?
=
null
,
@SerialId
(
3
)
val
reqExtendinfo
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
4
)
val
timestamp
:
Long
=
0L
,
@SerialId
(
5
)
val
msgLoginSigHead
:
LoginSigHead
?
=
null
)
:
ProtoBuf
@Serializable
class
RspBody
(
@SerialId
(
1
)
val
msgQueryHoleRsp
:
QueryHoleRsp
?
=
null
)
:
ProtoBuf
@Serializable
class
RspDataHighwayHead
(
@SerialId
(
1
)
val
msgBasehead
:
DataHighwayHead
?
=
null
,
@SerialId
(
2
)
val
msgSeghead
:
SegHead
?
=
null
,
@SerialId
(
3
)
val
errorCode
:
Int
=
0
,
@SerialId
(
4
)
val
allowRetry
:
Int
=
0
,
@SerialId
(
5
)
val
cachecost
:
Int
=
0
,
@SerialId
(
6
)
val
htcost
:
Int
=
0
,
@SerialId
(
7
)
val
rspExtendinfo
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
8
)
val
timestamp
:
Long
=
0L
,
@SerialId
(
9
)
val
range
:
Long
=
0L
,
@SerialId
(
10
)
val
isReset
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
SegHead
(
@SerialId
(
1
)
val
serviceid
:
Int
=
0
,
@SerialId
(
2
)
val
filesize
:
Long
=
0L
,
@SerialId
(
3
)
val
dataoffset
:
Long
=
0L
,
@SerialId
(
4
)
val
datalength
:
Int
=
0
,
@SerialId
(
5
)
val
rtcode
:
Int
=
0
,
@SerialId
(
6
)
val
serviceticket
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
7
)
val
flag
:
Int
=
0
,
@SerialId
(
8
)
val
md5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
9
)
val
fileMd5
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
10
)
val
cacheAddr
:
Int
=
0
,
@SerialId
(
11
)
val
queryTimes
:
Int
=
0
,
@SerialId
(
12
)
val
updateCacheip
:
Int
=
0
)
:
ProtoBuf
}
@Serializable
class
HwConfigPersistentPB
:
ProtoBuf
{
@Serializable
class
HwConfigItemPB
(
@SerialId
(
1
)
val
ingKey
:
String
=
""
,
@SerialId
(
2
)
val
endPointList
:
List
<
HwEndPointPB
>?
=
null
)
:
ProtoBuf
@Serializable
class
HwConfigPB
(
@SerialId
(
1
)
val
configItemList
:
List
<
HwConfigItemPB
>?
=
null
,
@SerialId
(
2
)
val
netSegConfList
:
List
<
HwNetSegConfPB
>?
=
null
,
@SerialId
(
3
)
val
shortVideoNetConf
:
List
<
HwNetSegConfPB
>?
=
null
,
@SerialId
(
4
)
val
configItemListIp6
:
List
<
HwConfigItemPB
>?
=
null
)
:
ProtoBuf
@Serializable
class
HwEndPointPB
(
@SerialId
(
1
)
val
ingHost
:
String
=
""
,
@SerialId
(
2
)
val
int32Port
:
Int
=
0
,
@SerialId
(
3
)
val
int64Timestampe
:
Long
=
0L
)
:
ProtoBuf
@Serializable
class
HwNetSegConfPB
(
@SerialId
(
1
)
val
int64NetType
:
Long
=
0L
,
@SerialId
(
2
)
val
int64SegSize
:
Long
=
0L
,
@SerialId
(
3
)
val
int64SegNum
:
Long
=
0L
,
@SerialId
(
4
)
val
int64CurConnNum
:
Long
=
0L
)
:
ProtoBuf
}
@Serializable
class
HwSessionInfoPersistentPB
:
ProtoBuf
{
@Serializable
class
HwSessionInfoPB
(
@SerialId
(
1
)
val
httpconnSigSession
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
sessionKey
:
ByteArray
=
EMPTY_BYTE_ARRAY
)
:
ProtoBuf
}
@Serializable
class
Subcmd0x501
:
ProtoBuf
{
@Serializable
class
ReqBody
(
@SerialId
(
1281
)
val
msgSubcmd0x501ReqBody
:
SubCmd0x501ReqBody
?
=
null
)
:
ProtoBuf
@Serializable
class
RspBody
(
@SerialId
(
1281
)
val
msgSubcmd0x501RspBody
:
SubCmd0x501Rspbody
?
=
null
)
:
ProtoBuf
@Serializable
class
SubCmd0x501ReqBody
(
@SerialId
(
1
)
val
uin
:
Long
=
0L
,
@SerialId
(
2
)
val
idcId
:
Int
=
0
,
@SerialId
(
3
)
val
appid
:
Int
=
0
,
@SerialId
(
4
)
val
loginSigType
:
Int
=
0
,
@SerialId
(
5
)
val
loginSigTicket
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
6
)
val
requestFlag
:
Int
=
0
,
@SerialId
(
7
)
val
uint32ServiceTypes
:
List
<
Int
>?
=
null
,
@SerialId
(
8
)
val
bid
:
Int
=
0
,
@SerialId
(
9
)
val
term
:
Int
=
0
,
@SerialId
(
10
)
val
plat
:
Int
=
0
,
@SerialId
(
11
)
val
net
:
Int
=
0
,
@SerialId
(
12
)
val
caller
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
SubCmd0x501Rspbody
(
@SerialId
(
1
)
val
httpconnSigSession
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
2
)
val
sessionKey
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
msgHttpconnAddrs
:
List
<
SrvAddrs
>?
=
null
,
@SerialId
(
4
)
val
preConnection
:
Int
=
0
,
@SerialId
(
5
)
val
csConn
:
Int
=
0
,
@SerialId
(
6
)
val
msgIpLearnConf
:
IpLearnConf
?
=
null
,
@SerialId
(
7
)
val
msgDynTimeoutConf
:
DynTimeOutConf
?
=
null
,
@SerialId
(
8
)
val
msgOpenUpConf
:
OpenUpConf
?
=
null
,
@SerialId
(
9
)
val
msgDownloadEncryptConf
:
DownloadEncryptConf
?
=
null
,
@SerialId
(
10
)
val
msgShortVideoConf
:
ShortVideoConf
?
=
null
,
@SerialId
(
11
)
val
msgPtvConf
:
PTVConf
?
=
null
)
:
ProtoBuf
{
@Serializable
class
DownloadEncryptConf
(
@SerialId
(
1
)
val
boolEnableEncryptRequest
:
Boolean
=
false
,
@SerialId
(
2
)
val
boolEnableEncryptedPic
:
Boolean
=
false
,
@SerialId
(
3
)
val
ctrlFlag
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
DynTimeOutConf
(
@SerialId
(
1
)
val
tbase2g
:
Int
=
0
,
@SerialId
(
2
)
val
tbase3g
:
Int
=
0
,
@SerialId
(
3
)
val
tbase4g
:
Int
=
0
,
@SerialId
(
4
)
val
tbaseWifi
:
Int
=
0
,
@SerialId
(
5
)
val
torg2g
:
Int
=
0
,
@SerialId
(
6
)
val
torg3g
:
Int
=
0
,
@SerialId
(
7
)
val
torg4g
:
Int
=
0
,
@SerialId
(
8
)
val
torgWifi
:
Int
=
0
,
@SerialId
(
9
)
val
maxTimeout
:
Int
=
0
,
@SerialId
(
10
)
val
enableDynTimeout
:
Int
=
0
,
@SerialId
(
11
)
val
maxTimeout2g
:
Int
=
0
,
@SerialId
(
12
)
val
maxTimeout3g
:
Int
=
0
,
@SerialId
(
13
)
val
maxTimeout4g
:
Int
=
0
,
@SerialId
(
14
)
val
maxTimeoutWifi
:
Int
=
0
,
@SerialId
(
15
)
val
hbTimeout2g
:
Int
=
0
,
@SerialId
(
16
)
val
hbTimeout3g
:
Int
=
0
,
@SerialId
(
17
)
val
hbTimeout4g
:
Int
=
0
,
@SerialId
(
18
)
val
hbTimeoutWifi
:
Int
=
0
,
@SerialId
(
19
)
val
hbTimeoutDefault
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
Ip6Addr
(
@SerialId
(
1
)
val
type
:
Int
=
0
,
@SerialId
(
2
)
val
ip6
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@SerialId
(
3
)
val
port
:
Int
=
0
,
@SerialId
(
4
)
val
area
:
Int
=
0
,
@SerialId
(
5
)
val
sameIsp
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
IpAddr
(
@SerialId
(
1
)
val
type
:
Int
=
0
,
@ProtoType
(
ProtoNumberType
.
FIXED
)
@SerialId
(
2
)
val
ip
:
Int
=
0
,
@SerialId
(
3
)
val
port
:
Int
=
0
,
@SerialId
(
4
)
val
area
:
Int
=
0
,
@SerialId
(
5
)
val
sameIsp
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
IpLearnConf
(
@SerialId
(
1
)
val
refreshCachedIp
:
Int
=
0
,
@SerialId
(
2
)
val
enableIpLearn
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
NetSegConf
(
@SerialId
(
1
)
val
netType
:
Int
=
0
,
@SerialId
(
2
)
val
segsize
:
Int
=
0
,
@SerialId
(
3
)
val
segnum
:
Int
=
0
,
@SerialId
(
4
)
val
curconnnum
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
OpenUpConf
(
@SerialId
(
1
)
val
boolEnableOpenup
:
Boolean
=
false
,
@SerialId
(
2
)
val
preSendSegnum
:
Int
=
0
,
@SerialId
(
3
)
val
preSendSegnum3g
:
Int
=
0
,
@SerialId
(
4
)
val
preSendSegnum4g
:
Int
=
0
,
@SerialId
(
5
)
val
preSendSegnumWifi
:
Int
=
0
)
:
ProtoBuf
@Serializable
class
PTVConf
(
@SerialId
(
1
)
val
channelType
:
Int
=
0
,
@SerialId
(
2
)
val
msgNetsegconf
:
List
<
NetSegConf
>?
=
null
,
@SerialId
(
3
)
val
boolOpenHardwareCodec
:
Boolean
=
false
)
:
ProtoBuf
@Serializable
class
ShortVideoConf
(
@SerialId
(
1
)
val
channelType
:
Int
=
0
,
@SerialId
(
2
)
val
msgNetsegconf
:
List
<
NetSegConf
>?
=
null
,
@SerialId
(
3
)
val
boolOpenHardwareCodec
:
Boolean
=
false
,
@SerialId
(
4
)
val
boolSendAheadSignal
:
Boolean
=
false
)
:
ProtoBuf
@Serializable
class
SrvAddrs
(
@SerialId
(
1
)
val
serviceType
:
Int
=
0
,
@SerialId
(
2
)
val
msgAddrs
:
List
<
IpAddr
>?
=
null
,
@SerialId
(
3
)
val
fragmentSize
:
Int
=
0
,
@SerialId
(
4
)
val
msgNetsegconf
:
List
<
NetSegConf
>?
=
null
,
@SerialId
(
5
)
val
msgAddrsV6
:
List
<
Ip6Addr
>?
=
null
)
:
ProtoBuf
}
}
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
View file @
35dca403
...
...
@@ -5,6 +5,9 @@ import kotlinx.io.pool.useInstance
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.event.Subscribable
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImageUpPacket
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
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.list.FriendList
...
...
@@ -117,7 +120,10 @@ internal object KnownPacketFactories {
MessageSvc
.
PbSendMsg
,
FriendList
.
GetFriendGroupList
,
FriendList
.
GetTroopListSimplify
,
FriendList
.
GetTroopMemberList
FriendList
.
GetTroopMemberList
,
ImgStore
.
GroupPicUp
,
ImageUpPacket
,
LongConn
.
OffPicDown
)
object
IncomingFactories
:
List
<
IncomingPacketFactory
<
*
>>
by
mutableListOf
(
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImageUpPacket.kt
View file @
35dca403
...
...
@@ -10,15 +10,13 @@ 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.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.buildOutgoingUniPacket
internal
object
ImageUpPacket
:
OutgoingPacketFactory
<
ImageUpPacket
.
ImageUpPacketResponse
>(
"LongConn.OffPicUp"
)
{
operator
fun
invoke
(
client
:
QQAndroidClient
,
req
:
UploadImgReq
):
OutgoingPacket
{
// TODO: 2020/1/24 测试: bodyType, subAppId
return
buildLoginOutgoingPacket
(
client
,
key
=
client
.
wLoginSigInfo
.
d2Key
,
bodyType
=
1
)
{
writeSsoPacket
(
client
,
subAppId
=
0
,
commandName
=
commandName
,
sequenceId
=
it
)
{
return
buildOutgoingUniPacket
(
client
)
{
val
data
=
ProtoBufWithNullableSupport
.
dump
(
Cmd0x352Packet
.
serializer
(),
Cmd0x352Packet
.
createByImageRequest
(
req
)
...
...
@@ -27,7 +25,6 @@ internal object ImageUpPacket : OutgoingPacketFactory<ImageUpPacket.ImageUpPacke
writeFully
(
data
)
}
}
}
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
ImageUpPacketResponse
{
TODO
(
"not implemented"
)
//To change body of created functions use File | Settings | File Templates.
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImgStore.kt
0 → 100644
View file @
35dca403
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image
import
io.ktor.client.HttpClient
import
kotlinx.io.core.ByteReadPacket
import
net.mamoe.mirai.data.Packet
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.io.serialization.writeProtoBuf
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x388
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.buildOutgoingUniPacket
internal
class
ImgStore
{
object
GroupPicUp
:
OutgoingPacketFactory
<
GroupPicUp
.
Response
>(
"ImgStore.GroupPicUp"
)
{
operator
fun
invoke
(
client
:
QQAndroidClient
,
uin
:
Long
,
groupCode
:
Long
,
md5
:
ByteArray
,
size
:
Long
,
picWidth
:
Int
,
picHeight
:
Int
,
picType
:
Int
=
1000
,
fileId
:
Long
=
0
,
filename
:
String
,
srcTerm
:
Int
=
5
,
platformType
:
Int
=
9
,
buType
:
Int
=
1
,
appPicType
:
Int
=
1006
,
originalPic
:
Int
=
0
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
writeProtoBuf
(
Cmd0x388
.
ReqBody
.
serializer
(),
Cmd0x388
.
ReqBody
(
netType
=
3
,
// wifi
subcmd
=
1
,
msgTryupImgReq
=
listOf
(
Cmd0x388
.
TryUpImgReq
(
groupCode
=
groupCode
,
srcUin
=
uin
,
fileMd5
=
md5
,
fileSize
=
size
,
fileId
=
fileId
,
fileName
=
filename
,
picWidth
=
picWidth
,
picHeight
=
picHeight
,
picType
=
picType
,
appPicType
=
appPicType
,
buildVer
=
client
.
buildVer
,
srcTerm
=
srcTerm
,
platformType
=
platformType
,
originalPic
=
originalPic
,
buType
=
buType
)
)
)
)
}
sealed
class
Response
:
Packet
{
class
FileExists
(
val
fileId
:
Long
,
val
fileInfo
:
Cmd0x388
.
ImgInfo
)
:
Response
()
{
override
fun
toString
():
String
{
return
"FileExists(fileId=$fileId, fileInfo=$fileInfo)"
}
}
class
RequireUpload
(
val
fileId
:
Long
,
val
uKey
:
ByteArray
,
val
uploadIpList
:
List
<
Int
>,
val
uploadPortList
:
List
<
Int
>
)
:
Response
()
{
override
fun
toString
():
String
{
return
"RequireUpload(fileId=$fileId, uKey=${uKey.contentToString()})"
}
}
data class
Failed
(
val
resultCode
:
Int
,
val
message
:
String
)
:
Response
()
}
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
Response
{
val
resp0
=
readProtoBuf
(
Cmd0x388
.
RspBody
.
serializer
())
resp0
.
msgTryupImgRsp
?:
error
(
"cannot find `msgTryupImgRsp` from `Cmd0x388.RspBody`"
)
val
resp
=
resp0
.
msgTryupImgRsp
.
first
()
return
when
{
resp
.
result
!=
0
->
Response
.
Failed
(
resultCode
=
resp
.
result
,
message
=
resp
.
failMsg
)
resp
.
boolFileExit
->
Response
.
FileExists
(
fileId
=
resp
.
fileid
,
fileInfo
=
resp
.
msgImgInfo
!!
)
else
->
Response
.
RequireUpload
(
fileId
=
resp
.
fileid
,
uKey
=
resp
.
upUkey
,
uploadIpList
=
resp
.
uint32UpIp
!!
,
uploadPortList
=
resp
.
uint32UpPort
!!
)
}
}
}
}
\ No newline at end of file
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/
ImageDownPacket
.kt
→
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/
LongConn
.kt
View file @
35dca403
...
...
@@ -13,8 +13,9 @@ 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
ImageDownPacket
:
OutgoingPacketFactory
<
ImageDownPacket
.
ImageDownPacketResponse
>(
"LongConn.OffPicDown"
)
{
internal
class
LongConn
{
object
OffPicDown
:
OutgoingPacketFactory
<
OffPicDown
.
ImageDownPacketResponse
>(
"LongConn.OffPicDown"
){
operator
fun
invoke
(
client
:
QQAndroidClient
,
req
:
GetImgUrlReq
):
OutgoingPacket
{
// TODO: 2020/1/24 测试: bodyType, subAppId
return
buildLoginOutgoingPacket
(
client
,
key
=
client
.
wLoginSigInfo
.
d2Key
,
bodyType
=
1
)
{
...
...
@@ -37,6 +38,5 @@ internal object ImageDownPacket : OutgoingPacketFactory<ImageDownPacket.ImageDow
sealed
class
ImageDownPacketResponse
:
Packet
{
object
Success
:
ImageDownPacketResponse
()
}
}
}
\ No newline at end of file
mirai-core-qqandroid/src/jvmTest/kotlin/test/ProtoBufDataClassGenerator.kt
View file @
35dca403
...
...
@@ -6,7 +6,9 @@ import java.io.File
fun
main
()
{
println
(
File
(
"""/Users/jiahua.liu/Desktop/QQAndroid-F/app/src/main/java/tencent/im/s2c/msgtype0x210/submsgtype0xc7/bussinfo/mutualmark"""
)
File
(
"""
E:\Projects\QQAndroidFF\app\src\main\java\com\tencent\mobileqq\highway\protocol
"""
.
trimIndent
())
.
generateUnarrangedClasses
().
toMutableList
().
arrangeClasses
().
joinToString
(
"\n\n"
)
)
}
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
View file @
35dca403
...
...
@@ -31,8 +31,6 @@ interface Group : Contact, CoroutineScope {
/**
* 在 [Group] 实例创建的时候查询一次. 并与事件同步事件更新
*
* **注意**: 获得的列表仅为这一时刻的成员列表的镜像. 它将不会被更新
*/
val
members
:
ContactList
<
Member
>
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
View file @
35dca403
...
...
@@ -7,18 +7,10 @@ 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.data.*
import
net.mamoe.mirai.message.data.Image
import
net.mamoe.mirai.message.data.sendTo
import
net.mamoe.mirai.utils.io.toUHexString
@Suppress
(
"FunctionName"
)
fun
ExternalImage
(
width
:
Int
,
height
:
Int
,
md5
:
ByteArray
,
format
:
String
,
data
:
ByteReadPacket
):
ExternalImage
=
ExternalImage
(
width
,
height
,
md5
,
format
,
data
,
data
.
remaining
)
/**
* 外部图片. 图片数据还没有读取到内存.
*
...
...
@@ -33,19 +25,53 @@ class ExternalImage(
val
md5
:
ByteArray
,
imageFormat
:
String
,
val
input
:
Input
,
val
inputSize
:
Long
val
inputSize
:
Long
,
val
filename
:
String
)
{
private
val
format
:
String
companion
object
{
operator
fun
invoke
(
width
:
Int
,
height
:
Int
,
md5
:
ByteArray
,
format
:
String
,
data
:
ByteReadPacket
,
filename
:
String
):
ExternalImage
=
ExternalImage
(
width
,
height
,
md5
,
format
,
data
,
data
.
remaining
,
filename
)
}
init
{
if
(
imageFormat
==
"JPEG"
||
imageFormat
==
"jpeg"
)
{
//必须转换
this
.
format
=
"jpg"
}
else
{
this
.
format
=
imageFormat
private
val
format
:
String
=
when
(
val
it
=
imageFormat
.
toLowerCase
())
{
"jpeg"
->
"jpg"
//必须转换
else
->
it
}
/**
*
* ImgType:
* JPG: 1000
* PNG: 1001
* WEBP: 1002
* BMP: 1005
* GIG: 2000
* APNG: 2001
* SHARPP: 1004
*/
val
imageType
:
Int
get
()
=
when
(
format
){
"jpg"
->
1000
"png"
->
1001
"webp"
->
1002
"bmp"
->
1005
"gig"
->
2000
"apng"
->
2001
"sharpp"
->
1004
else
->
1000
// unsupported, just make it jpg
}
override
fun
toString
():
String
=
"[ExternalImage(${width}x$height $format)]"
fun
calculateImageResourceId
():
String
{
return
"{${md5[0..3]}-${md5[4..5]}-${md5[6..7]}-${md5[8..9]}-${md5[10..15]}}.$format"
}
}
/**
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/ExternalImageJvm.kt
View file @
35dca403
...
...
@@ -12,6 +12,7 @@ import kotlinx.io.core.copyTo
import
kotlinx.io.errors.IOException
import
kotlinx.io.streams.asInput
import
kotlinx.io.streams.asOutput
import
net.mamoe.mirai.utils.io.getRandomString
import
java.awt.image.BufferedImage
import
java.io.File
import
java.io.InputStream
...
...
@@ -44,7 +45,7 @@ fun BufferedImage.toExternalImage(formatName: String = "gif"): ExternalImage {
})
}
return
ExternalImage
(
width
,
height
,
digest
.
digest
(),
formatName
,
buffer
)
return
ExternalImage
(
width
,
height
,
digest
.
digest
(),
formatName
,
buffer
,
getRandomString
(
10
)
+
"."
+
formatName
)
}
suspend
inline
fun
BufferedImage
.
suspendToExternalImage
():
ExternalImage
=
withContext
(
IO
)
{
toExternalImage
()
}
...
...
@@ -66,7 +67,8 @@ fun File.toExternalImage(): ExternalImage {
md5
=
this
.
inputStream
().
use
{
it
.
md5
()
},
imageFormat
=
image
.
formatName
,
input
=
this
.
inputStream
().
asInput
(
IoBuffer
.
Pool
),
inputSize
=
this
.
length
()
inputSize
=
this
.
length
(),
filename
=
this
.
name
)
}
...
...
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