mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-05 00:10:13 +08:00
add: voice upload
This commit is contained in:
parent
07d9365d70
commit
038c9d1db1
@ -42,6 +42,7 @@ import net.mamoe.mirai.qqandroid.message.*
|
|||||||
import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler
|
import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler
|
||||||
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||||
import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
|
import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
|
||||||
|
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x388
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
|
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.LongMsg
|
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.*
|
||||||
|
@ -219,7 +219,7 @@ internal fun MsgComm.Msg.toMessageChain(
|
|||||||
|
|
||||||
val pptMsg = ptt?.run {
|
val pptMsg = ptt?.run {
|
||||||
when(fileType) {
|
when(fileType) {
|
||||||
4 -> Voice(String(fileName), fileMd5, String(downPara))
|
4 -> Voice(String(fileName), fileMd5, fileSize.toLong(),fileKey,String(downPara))
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import kotlinx.io.core.use
|
|||||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||||
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.CSDataHighwayHead
|
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.PlatformSocket
|
import net.mamoe.mirai.qqandroid.utils.PlatformSocket
|
||||||
import net.mamoe.mirai.qqandroid.utils.SocketException
|
import net.mamoe.mirai.qqandroid.utils.SocketException
|
||||||
import net.mamoe.mirai.qqandroid.utils.addSuppressedMirai
|
import net.mamoe.mirai.qqandroid.utils.addSuppressedMirai
|
||||||
|
@ -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.ImgStore
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
|
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.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.FriendList
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.ConfigPushSvc
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.ConfigPushSvc
|
||||||
@ -139,6 +140,7 @@ internal object KnownPacketFactories {
|
|||||||
FriendList.GetTroopListSimplify,
|
FriendList.GetTroopListSimplify,
|
||||||
FriendList.GetTroopMemberList,
|
FriendList.GetTroopMemberList,
|
||||||
ImgStore.GroupPicUp,
|
ImgStore.GroupPicUp,
|
||||||
|
PttStore.GroupPttUp,
|
||||||
LongConn.OffPicUp,
|
LongConn.OffPicUp,
|
||||||
LongConn.OffPicDown,
|
LongConn.OffPicDown,
|
||||||
TroopManagement.EditSpecialTitle,
|
TroopManagement.EditSpecialTitle,
|
||||||
|
@ -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.OutgoingPacket
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
|
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.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.readProtoBuf
|
||||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
|
import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
|
||||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
|
import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
|
||||||
@ -138,7 +139,17 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
|
|||||||
richText = ImMsgBody.RichText(
|
richText = ImMsgBody.RichText(
|
||||||
elems = message.toRichTextElems(forGroup = true, withGeneralFlags = true),
|
elems = message.toRichTextElems(forGroup = true, withGeneralFlags = true),
|
||||||
ptt = message.firstOrNull(PttMessage)?.run {
|
ptt = message.firstOrNull(PttMessage)?.run {
|
||||||
ImMsgBody.Ptt(fileName = fileName.toByteArray(), fileMd5 = md5)
|
ImMsgBody.Ptt(
|
||||||
|
fileName = fileName.toByteArray(),
|
||||||
|
fileMd5 = md5,
|
||||||
|
boolValid = true,
|
||||||
|
fileSize = fileSize.toInt(),
|
||||||
|
groupFileKey = fileKey,
|
||||||
|
fileType = 4,
|
||||||
|
// 不知道能不能解决tim无法收听的问题
|
||||||
|
reserve = "16 36 20 38 36 65 41 31 04 37 61 39 35 37 37 61 33 62 37 30 33 66 65 33 31 20 20 20 20 20 20 35 30 55 49 30 E3 3F 8F 9F FB CA 1D 79 60 6C F4 74 F2 35 35 34 39 33 30 45 33 33 46 38 46 39 46 46 42 43 41 31 44 37 39 36 30 36 43 46 34 37 34 46 32 2E 61 6D 72 41".hexToBytes(),
|
||||||
|
pbReserve = "08 00".hexToBytes()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -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
|
// 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
|
if (!bot.firstLoginSucceed) return null
|
||||||
val pbPushMsg = readProtoBuf(MsgOnlinePush.PbPushMsg.serializer())
|
val pbPushMsg = readProtoBuf(MsgOnlinePush.PbPushMsg.serializer())
|
||||||
|
bot.logger.debug(pbPushMsg._miraiContentToString())
|
||||||
|
|
||||||
if (pbPushMsg.msg.msgHead.fromUin == bot.id) {
|
if (pbPushMsg.msg.msgHead.fromUin == bot.id) {
|
||||||
return SendGroupMessageReceipt(
|
return SendGroupMessageReceipt(
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.voice
|
||||||
|
|
||||||
|
import kotlinx.io.core.ByteReadPacket
|
||||||
|
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.getRandomString
|
||||||
|
import net.mamoe.mirai.qqandroid.utils._miraiContentToString
|
||||||
|
import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
|
||||||
|
import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
|
||||||
|
|
||||||
|
internal class PttStore {
|
||||||
|
object GroupPttUp : OutgoingPacketFactory<GroupPttUp.Response>("PttStore.GroupPttUp") {
|
||||||
|
|
||||||
|
sealed class Response : Packet {
|
||||||
|
|
||||||
|
class Resp(
|
||||||
|
val resp: Cmd0x388.RspBody
|
||||||
|
) : Response() {
|
||||||
|
override fun toString(): String {
|
||||||
|
return resp._miraiContentToString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发语音
|
||||||
|
* 收到请求后可以通过下面的代码来上传到服务器
|
||||||
|
*
|
||||||
|
val up_rsp = response.resp.msgTryupPttRsp!![0]
|
||||||
|
if (!up_rsp.boolFileExit) {
|
||||||
|
val server = up_rsp.uint32UpIp!![0].toIpV4AddressString()
|
||||||
|
val port = up_rsp.uint32UpPort?.get(0)
|
||||||
|
val id = up_rsp.fileid
|
||||||
|
|
||||||
|
HttpClient().post<String> {
|
||||||
|
url("http://$server:$port")
|
||||||
|
parameter("ver", 4679)
|
||||||
|
parameter("ukey", up_rsp.upUkey.toUHexString(""))
|
||||||
|
parameter("filekey", up_rsp.fileKey.toUHexString(""))
|
||||||
|
parameter("filesize", size)
|
||||||
|
parameter("bmd5", md5)
|
||||||
|
parameter("mType", "pttDu")
|
||||||
|
parameter("voice_encodec", 0)
|
||||||
|
body = file.readBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
* */
|
||||||
|
|
||||||
|
@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 = getRandomString(16).encodeToByteArray(),
|
||||||
|
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())
|
||||||
|
return Response.Resp(resp0)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,6 +15,9 @@ abstract class PttMessage : MessageContent {
|
|||||||
|
|
||||||
abstract val fileName: String
|
abstract val fileName: String
|
||||||
abstract val md5: ByteArray
|
abstract val md5: ByteArray
|
||||||
|
abstract val fileSize: Long
|
||||||
|
abstract val fileKey:ByteArray
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -25,6 +28,8 @@ abstract class PttMessage : MessageContent {
|
|||||||
class Voice(
|
class Voice(
|
||||||
override val fileName: String,
|
override val fileName: String,
|
||||||
override val md5: ByteArray,
|
override val md5: ByteArray,
|
||||||
|
override val fileSize: Long,
|
||||||
|
override val fileKey: ByteArray,
|
||||||
private val _url: String
|
private val _url: String
|
||||||
) : PttMessage() {
|
) : PttMessage() {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user