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
522bcba3
Commit
522bcba3
authored
Jul 11, 2020
by
Him188
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/dev' into dev
parents
1d0c3c2e
2ae91bb2
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
282 additions
and
17 deletions
+282
-17
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
...n/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
+19
-3
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/conversions.kt
...n/kotlin/net/mamoe/mirai/qqandroid/message/conversions.kt
+26
-9
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt
...et/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt
+49
-1
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
+1
-1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
.../mirai/qqandroid/network/protocol/packet/PacketFactory.kt
+3
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt
...work/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt
+9
-1
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
+1
-0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/voice/PttStore.kt
.../qqandroid/network/protocol/packet/chat/voice/PttStore.kt
+160
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
...core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
+10
-0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Voice.kt
...c/commonMain/kotlin/net.mamoe.mirai/message/data/Voice.kt
+4
-2
No files found.
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
View file @
522bcba3
...
...
@@ -11,7 +11,6 @@
package
net.mamoe.mirai.qqandroid
import
io.ktor.client.HttpClient
import
io.ktor.client.request.*
import
io.ktor.client.request.forms.MultiPartFormDataContent
import
io.ktor.client.request.forms.formData
...
...
@@ -45,6 +44,7 @@ import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.LongMsg
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.voice.PttStore
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import
net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils
import
net.mamoe.mirai.qqandroid.utils.encodeToString
...
...
@@ -56,6 +56,7 @@ import kotlin.coroutines.CoroutineContext
import
kotlin.jvm.JvmField
import
kotlin.jvm.JvmSynthetic
import
kotlin.math.absoluteValue
import
kotlin.math.log
import
kotlin.random.Random
import
net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo
as
JceFriendInfo
...
...
@@ -560,7 +561,7 @@ internal abstract class QQAndroidBotBase constructor(
@MiraiExperimentalAPI
override
suspend
fun
_lowLevelGetAnnouncement
(
groupId
:
Long
,
fid
:
String
):
GroupAnnouncement
{
val
data
=
network
.
async
{
HttpClient
()
.
post
<
String
>
{
MiraiPlatformUtils
.
Http
.
post
<
String
>
{
url
(
"https://web.qun.qq.com/cgi-bin/announce/get_feed"
)
body
=
MultiPartFormDataContent
(
formData
{
append
(
"qid"
,
groupId
)
...
...
@@ -587,7 +588,7 @@ internal abstract class QQAndroidBotBase constructor(
@MiraiExperimentalAPI
override
suspend
fun
_lowLevelGetGroupActiveData
(
groupId
:
Long
,
page
:
Int
):
GroupActiveData
{
val
data
=
network
.
async
{
HttpClient
()
.
get
<
String
>
{
MiraiPlatformUtils
.
Http
.
get
<
String
>
{
url
(
"https://qqweb.qq.com/c/activedata/get_mygroup_data"
)
parameter
(
"bkn"
,
bkn
)
parameter
(
"gc"
,
groupId
)
...
...
@@ -792,6 +793,21 @@ internal abstract class QQAndroidBotBase constructor(
}
}
@ExperimentalStdlibApi
@MiraiExperimentalAPI
@LowLevelAPI
override
suspend
fun
_lowLevelQueryGroupVoiceDownloadUrl
(
md5
:
ByteArray
,
groupId
:
Long
,
dstUin
:
Long
):
String
{
network
.
run
{
val
response
:
PttStore
.
GroupPttDown
.
Response
.
DownLoadInfo
=
PttStore
.
GroupPttDown
(
client
,
groupId
,
dstUin
,
md5
).
sendAndExpect
()
return
"http://${response.strDomain}${response.downPara.encodeToString()}"
}
}
@Suppress
(
"DEPRECATION"
,
"OverridingDeprecatedMember"
)
override
suspend
fun
queryImageUrl
(
image
:
Image
):
String
=
when
(
image
)
{
is
ConstOriginUrlAware
->
image
.
originUrl
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/conversions.kt
View file @
522bcba3
...
...
@@ -32,7 +32,9 @@ import kotlin.contracts.contract
private
val
UNSUPPORTED_MERGED_MESSAGE_PLAIN
=
PlainText
(
"你的QQ暂不支持查看[转发多条消息],请期待后续版本。"
)
private
val
UNSUPPORTED_POKE_MESSAGE_PLAIN
=
PlainText
(
"[戳一戳]请使用最新版手机QQ体验新功能。"
)
private
val
UNSUPPORTED_FLASH_MESSAGE_PLAIN
=
PlainText
(
"[闪照]请使用新版手机QQ查看闪照。"
)
private
val
UNSUPPORTED_VOICE_MESSAGE_PLAIN
=
PlainText
(
"收到语音消息,你需要升级到最新版QQ才能接收,升级地址https://im.qq.com"
)
@OptIn
(
ExperimentalStdlibApi
::
class
)
@Suppress
(
"INVISIBLE_MEMBER"
,
"INVISIBLE_REFERENCE"
)
internal
fun
MessageChain
.
toRichTextElems
(
forGroup
:
Boolean
,
withGeneralFlags
:
Boolean
):
MutableList
<
ImMsgBody
.
Elem
>
{
val
elements
=
ArrayList
<
ImMsgBody
.
Elem
>(
this
.
size
)
...
...
@@ -156,7 +158,20 @@ internal fun MessageChain.toRichTextElems(forGroup: Boolean, withGeneralFlags: B
is
VipFace
->
{
transformOneMessage
(
PlainText
(
it
.
contentToString
()))
}
is
PttMessage
,
is
PttMessage
->
{
elements
.
add
(
ImMsgBody
.
Elem
(
extraInfo
=
ImMsgBody
.
ExtraInfo
(
flags
=
16
,
groupMask
=
1
)
)
)
elements
.
add
(
ImMsgBody
.
Elem
(
elemFlags2
=
ImMsgBody
.
ElemFlags2
(
vipStatus
=
1
)
)
)
}
is
ForwardMessage
,
is
MessageSource
,
// mirai metadata only
is
RichMessage
// already transformed above
...
...
@@ -218,10 +233,11 @@ internal fun MsgComm.Msg.toMessageChain(
val
ptt
=
this
.
msgBody
.
richText
.
ptt
val
pptMsg
=
ptt
?.
run
{
when
(
fileType
)
{
4
->
Voice
(
String
(
fileName
),
fileMd5
,
String
(
downPara
))
else
->
null
}
// when (fileType) {
// 4 -> Voice(String(fileName), fileMd5, fileSize.toLong(),String(downPara))
// else -> null
// }
Voice
(
String
(
fileName
),
fileMd5
,
fileSize
.
toLong
(),
String
(
downPara
))
}
return
buildMessageChain
(
elements
.
size
+
1
+
if
(
pptMsg
==
null
)
0
else
1
)
{
...
...
@@ -274,13 +290,13 @@ private fun MessageChain.cleanupRubbishMessageElements(): MessageChain {
return
@
forEach
}
}
if
(
last
is
FlashImage
&&
element
is
PlainText
)
{
if
(
element
==
UNSUPPORTED_FLASH_MESSAGE_PLAIN
)
{
// 解决tim发送的语音无法正常识别
if
(
element
is
PlainText
)
{
if
(
element
==
UNSUPPORTED_VOICE_MESSAGE_PLAIN
)
{
last
=
element
return
@
forEach
}
}
add
(
element
)
last
=
element
}
...
...
@@ -431,7 +447,8 @@ internal fun List<ImMsgBody.Elem>.joinToMessageChain(groupIdOrZero: Long, bot: B
.
orEmpty
(),
proto
.
pokeType
,
proto
.
vaspokeId
))
)
)
}
3
->
{
val
proto
=
element
.
commonElem
.
pbElem
.
loadAs
(
HummerCommelem
.
MsgElemInfoServtype3
.
serializer
())
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt
View file @
522bcba3
...
...
@@ -12,7 +12,10 @@
package
net.mamoe.mirai.qqandroid.network.highway
import
io.ktor.client.HttpClient
import
io.ktor.client.request.parameter
import
io.ktor.client.request.port
import
io.ktor.client.request.post
import
io.ktor.client.request.url
import
io.ktor.http.ContentType
import
io.ktor.http.HttpStatusCode
import
io.ktor.http.URLProtocol
...
...
@@ -29,8 +32,9 @@ import kotlinx.io.core.use
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.network.QQAndroidClient
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead
import
net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x388
import
net.mamoe.mirai.qqandroid.utils.*
import
net.mamoe.mirai.qqandroid.utils.PlatformSocket
import
net.mamoe.mirai.qqandroid.utils.SocketException
import
net.mamoe.mirai.qqandroid.utils.addSuppressedMirai
import
net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.utils.io.withUse
...
...
@@ -180,6 +184,50 @@ internal object HighwayHelper {
}
}
}
suspend
fun
uploadPttToServers
(
bot
:
QQAndroidBot
,
servers
:
List
<
Pair
<
Int
,
Int
>>,
content
:
ByteArray
,
md5
:
ByteArray
,
uKey
:
ByteArray
,
fileKey
:
ByteArray
)
{
servers
.
retryWithServers
(
10
*
1000
,
{
throw
IllegalStateException
(
"cannot upload ptt, failed on all servers."
,
it
)
},
{
s
:
String
,
i
:
Int
->
bot
.
network
.
logger
.
verbose
{
"[Highway] Uploading ptt to ${s}:$i, size=${content.size.toLong().sizeToString()}"
}
val
time
=
measureTime
{
uploadPttToServer
(
s
,
i
,
content
,
md5
,
uKey
,
fileKey
)
}
bot
.
network
.
logger
.
verbose
{
"[Highway] Uploading ptt: succeed at ${(content.size.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
}
})
}
private
suspend
fun
uploadPttToServer
(
serverIp
:
String
,
serverPort
:
Int
,
content
:
ByteArray
,
md5
:
ByteArray
,
uKey
:
ByteArray
,
fileKey
:
ByteArray
)
{
MiraiPlatformUtils
.
Http
.
post
<
String
>
{
url
(
"http://$serverIp:$serverPort"
)
parameter
(
"ver"
,
4679
)
parameter
(
"ukey"
,
uKey
.
toUHexString
(
""
))
parameter
(
"filekey"
,
fileKey
.
toUHexString
(
""
))
parameter
(
"filesize"
,
content
.
size
)
parameter
(
"bmd5"
,
md5
.
toUHexString
(
""
))
parameter
(
"mType"
,
"pttDu"
)
parameter
(
"voice_encodec"
,
0
)
body
=
content
}
}
}
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Cmd0x388.kt
View file @
522bcba3
...
...
@@ -273,7 +273,7 @@ internal class TryUpPttReq(
internal
class
TryUpPttRsp
(
@ProtoId
(
1
)
@JvmField
val
fileId
:
Long
=
0L
,
@ProtoId
(
2
)
@JvmField
val
result
:
Int
=
0
,
@ProtoId
(
3
)
@JvmField
val
failMsg
:
ByteArray
=
EMPTY_BYTE_ARRAY
,
@ProtoId
(
3
)
@JvmField
val
failMsg
:
ByteArray
?
=
null
,
@ProtoId
(
4
)
@JvmField
val
boolFileExit
:
Boolean
=
false
,
@ProtoId
(
5
)
@JvmField
val
uint32UpIp
:
List
<
Int
>?
=
null
,
@ProtoId
(
6
)
@JvmField
val
uint32UpPort
:
List
<
Int
>?
=
null
,
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
View file @
522bcba3
...
...
@@ -20,6 +20,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
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.*
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.voice.PttStore
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import
net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
import
net.mamoe.mirai.qqandroid.network.protocol.packet.login.ConfigPushSvc
...
...
@@ -139,6 +140,8 @@ internal object KnownPacketFactories {
FriendList
.
GetTroopListSimplify
,
FriendList
.
GetTroopMemberList
,
ImgStore
.
GroupPicUp
,
PttStore
.
GroupPttUp
,
PttStore
.
GroupPttDown
,
LongConn
.
OffPicUp
,
LongConn
.
OffPicDown
,
TroopManagement
.
EditSpecialTitle
,
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt
View file @
522bcba3
...
...
@@ -30,6 +30,7 @@ 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.OutgoingPacketFactory
import
net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
import
net.mamoe.mirai.qqandroid.utils.hexToBytes
import
net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
import
net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
...
...
@@ -138,7 +139,14 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
richText
=
ImMsgBody
.
RichText
(
elems
=
message
.
toRichTextElems
(
forGroup
=
true
,
withGeneralFlags
=
true
),
ptt
=
message
.
firstOrNull
(
PttMessage
)
?.
run
{
ImMsgBody
.
Ptt
(
fileName
=
fileName
.
toByteArray
(),
fileMd5
=
md5
)
ImMsgBody
.
Ptt
(
fileName
=
fileName
.
toByteArray
(),
fileMd5
=
md5
,
boolValid
=
true
,
fileSize
=
fileSize
.
toInt
(),
fileType
=
4
,
pbReserve
=
byteArrayOf
(
0
)
)
}
)
),
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt
View file @
522bcba3
...
...
@@ -53,6 +53,7 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory<Packet?>("Onlin
// 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
if
(!
bot
.
firstLoginSucceed
)
return
null
val
pbPushMsg
=
readProtoBuf
(
MsgOnlinePush
.
PbPushMsg
.
serializer
())
// bot.logger.debug(pbPushMsg._miraiContentToString())
if
(
pbPushMsg
.
msg
.
msgHead
.
fromUin
==
bot
.
id
)
{
return
SendGroupMessageReceipt
(
...
...
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/voice/PttStore.kt
0 → 100644
View file @
522bcba3
package
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.voice
import
kotlinx.io.core.ByteReadPacket
import
net.mamoe.mirai.qqandroid.EMPTY_BYTE_ARRAY
import
net.mamoe.mirai.qqandroid.QQAndroidBot
import
net.mamoe.mirai.qqandroid.network.Packet
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
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
import
net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.getRandomString
import
net.mamoe.mirai.qqandroid.utils._miraiContentToString
import
net.mamoe.mirai.qqandroid.utils.encodeToString
import
net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
import
net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
import
net.mamoe.mirai.qqandroid.utils.toUHexString
internal
class
PttStore
{
object
GroupPttUp
:
OutgoingPacketFactory
<
GroupPttUp
.
Response
>(
"PttStore.GroupPttUp"
)
{
sealed
class
Response
:
Packet
{
class
RequireUpload
(
val
fileId
:
Long
,
val
uKey
:
ByteArray
,
val
uploadIpList
:
List
<
Int
>,
val
uploadPortList
:
List
<
Int
>,
val
fileKey
:
ByteArray
)
:
GroupPttUp
.
Response
()
{
override
fun
toString
():
String
{
return
"RequireUpload(fileId=$fileId, uKey=${uKey.contentToString()})"
}
}
}
@ExperimentalStdlibApi
operator
fun
invoke
(
client
:
QQAndroidClient
,
uin
:
Long
,
groupCode
:
Long
,
md5
:
ByteArray
,
size
:
Long
,
voiceLength
:
Int
,
fileId
:
Long
=
0
):
OutgoingPacket
{
val
pack
=
Cmd0x388
.
ReqBody
(
netType
=
3
,
// wifi
subcmd
=
3
,
msgTryupPttReq
=
listOf
(
Cmd0x388
.
TryUpPttReq
(
srcUin
=
uin
,
groupCode
=
groupCode
,
fileId
=
fileId
,
fileSize
=
size
,
fileMd5
=
md5
,
fileName
=
md5
,
srcTerm
=
5
,
platformType
=
9
,
buType
=
4
,
innerIp
=
0
,
buildVer
=
"6.5.5.663"
.
encodeToByteArray
(),
voiceLength
=
voiceLength
,
codec
=
0
,
voiceType
=
1
,
boolNewUpChan
=
true
)
)
)
return
buildOutgoingUniPacket
(
client
)
{
writeProtoBuf
(
Cmd0x388
.
ReqBody
.
serializer
(),
pack
)
}
}
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
Response
{
val
resp0
=
readProtoBuf
(
Cmd0x388
.
RspBody
.
serializer
())
resp0
.
msgTryupPttRsp
?:
error
(
"cannot find `msgTryupPttRsp` from `Cmd0x388.RspBody`"
)
val
resp
=
resp0
.
msgTryupPttRsp
.
first
()
if
(
resp
.
failMsg
!=
null
)
{
throw
IllegalStateException
(
resp
.
failMsg
.
encodeToString
())
}
return
Response
.
RequireUpload
(
fileId
=
resp
.
fileid
,
uKey
=
resp
.
upUkey
,
uploadIpList
=
resp
.
uint32UpIp
!!
,
uploadPortList
=
resp
.
uint32UpPort
!!
,
fileKey
=
resp
.
fileKey
)
}
}
object
GroupPttDown
:
OutgoingPacketFactory
<
GroupPttDown
.
Response
>(
"PttStore.GroupPttDown"
)
{
sealed
class
Response
()
:
Packet
{
class
DownLoadInfo
(
val
downDomain
:
ByteArray
,
val
downPara
:
ByteArray
,
val
strDomain
:
String
,
val
uint32DownIp
:
List
<
Int
>,
val
uint32DownPort
:
List
<
Int
>
)
:
GroupPttDown
.
Response
()
{
override
fun
toString
():
String
{
return
"GroupPttDown(downPara=${downPara.encodeToString()},strDomain=$strDomain})"
}
}
}
@ExperimentalStdlibApi
operator
fun
invoke
(
client
:
QQAndroidClient
,
groupCode
:
Long
,
dstUin
:
Long
,
md5
:
ByteArray
):
OutgoingPacket
=
buildOutgoingUniPacket
(
client
)
{
writeProtoBuf
(
Cmd0x388
.
ReqBody
.
serializer
(),
Cmd0x388
.
ReqBody
(
netType
=
3
,
// wifi
subcmd
=
4
,
msgGetpttUrlReq
=
listOf
(
Cmd0x388
.
GetPttUrlReq
(
groupCode
=
groupCode
,
fileMd5
=
md5
,
dstUin
=
dstUin
,
buType
=
4
,
innerIp
=
0
,
buildVer
=
"6.5.5.663"
.
encodeToByteArray
(),
codec
=
0
,
reqTerm
=
5
,
reqPlatformType
=
9
)
)
)
)
}
override
suspend
fun
ByteReadPacket
.
decode
(
bot
:
QQAndroidBot
):
Response
{
val
resp0
=
readProtoBuf
(
Cmd0x388
.
RspBody
.
serializer
())
resp0
.
msgGetpttUrlRsp
?:
error
(
"cannot find `msgGetpttUrlRsp` from `Cmd0x388.RspBody`"
)
val
resp
=
resp0
.
msgGetpttUrlRsp
.
first
()
if
(!
resp
.
failMsg
.
contentEquals
(
EMPTY_BYTE_ARRAY
)){
throw
IllegalStateException
(
resp
.
failMsg
.
encodeToString
())
}
return
Response
.
DownLoadInfo
(
downDomain
=
resp
.
downDomain
,
downPara
=
resp
.
downPara
,
uint32DownIp
=
resp
.
uint32DownIp
!!
,
uint32DownPort
=
resp
.
uint32DownPort
!!
,
strDomain
=
resp
.
strDomain
)
}
}
}
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/lowLevelApi.kt
View file @
522bcba3
...
...
@@ -16,6 +16,7 @@ import net.mamoe.mirai.data.*
import
net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
import
net.mamoe.mirai.event.events.MemberJoinRequestEvent
import
net.mamoe.mirai.event.events.NewFriendRequestEvent
import
net.mamoe.mirai.message.data.Voice
import
net.mamoe.mirai.utils.MiraiExperimentalAPI
import
net.mamoe.mirai.utils.WeakRef
...
...
@@ -159,4 +160,13 @@ interface LowLevelBotAPIAccessor {
blackList
:
Boolean
,
message
:
String
=
""
)
/**
* 查询语音的下载连接
*
* */
@LowLevelAPI
@MiraiExperimentalAPI
suspend
fun
_lowLevelQueryGroupVoiceDownloadUrl
(
md5
:
ByteArray
,
groupId
:
Long
,
dstUin
:
Long
):
String
}
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Voice.kt
View file @
522bcba3
...
...
@@ -15,6 +15,7 @@ abstract class PttMessage : MessageContent {
abstract
val
fileName
:
String
abstract
val
md5
:
ByteArray
abstract
val
fileSize
:
Long
}
...
...
@@ -25,6 +26,7 @@ abstract class PttMessage : MessageContent {
class
Voice
(
override
val
fileName
:
String
,
override
val
md5
:
ByteArray
,
override
val
fileSize
:
Long
,
private
val
_url
:
String
)
:
PttMessage
()
{
...
...
@@ -33,9 +35,9 @@ class Voice(
get
()
=
"Voice"
}
val
url
:
String
val
url
:
String
?
get
()
=
if
(
_url
.
startsWith
(
"http"
))
_url
else
"http://grouptalk.c2c.qq.com$_url"
else
null
private
var
_stringValue
:
String
?
=
null
get
()
=
field
?:
kotlin
.
run
{
...
...
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