simple api for send group voice message #423

This commit is contained in:
mzdluo123 2020-08-17 22:43:22 +08:00
parent 2161b67775
commit f96c20767d
No known key found for this signature in database
GPG Key ID: 9F7BC2C154107A1D
5 changed files with 110 additions and 52 deletions

View File

@ -12,9 +12,7 @@
package net.mamoe.mirai.qqandroid.contact
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.*
import kotlinx.io.core.Closeable
import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.*
@ -33,9 +31,13 @@ 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.receive.MessageSvcPbSendMsg
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToGroup
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.voice.PttStore
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils
import net.mamoe.mirai.qqandroid.utils.estimateLength
import net.mamoe.mirai.qqandroid.utils.toUHexString
import net.mamoe.mirai.utils.*
import java.io.InputStream
import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic
@ -130,18 +132,18 @@ internal class GroupImpl(
set(newValue) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
//if (_announcement != newValue) {
val oldValue = _announcement
_announcement = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.memo(
client = bot.client,
groupCode = id,
newMemo = newValue
).sendWithoutExpect()
}
GroupEntranceAnnouncementChangeEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
val oldValue = _announcement
_announcement = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.memo(
client = bot.client,
groupCode = id,
newMemo = newValue
).sendWithoutExpect()
}
GroupEntranceAnnouncementChangeEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
}
//}
}
@ -151,18 +153,18 @@ internal class GroupImpl(
set(newValue) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
//if (_allowMemberInvite != newValue) {
val oldValue = _allowMemberInvite
_allowMemberInvite = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.allowMemberInvite(
client = bot.client,
groupCode = id,
switch = newValue
).sendWithoutExpect()
}
GroupAllowMemberInviteEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
val oldValue = _allowMemberInvite
_allowMemberInvite = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.allowMemberInvite(
client = bot.client,
groupCode = id,
switch = newValue
).sendWithoutExpect()
}
GroupAllowMemberInviteEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
}
//}
}
@ -208,18 +210,18 @@ internal class GroupImpl(
set(newValue) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
//if (_muteAll != newValue) {
val oldValue = _muteAll
_muteAll = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.muteAll(
client = bot.client,
groupCode = id,
switch = newValue
).sendWithoutExpect()
}
GroupMuteAllEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
val oldValue = _muteAll
_muteAll = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.muteAll(
client = bot.client,
groupCode = id,
switch = newValue
).sendWithoutExpect()
}
GroupMuteAllEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
}
//}
}
}
@ -443,5 +445,37 @@ internal class GroupImpl(
(image.input as? Closeable)?.close()
}
/**
* 上传一个语音消息以备发送.
* 请注意这是一个实验性api且随时会被删除
* @throws EventCancelledException 当发送消息事件被取消
* @throws OverFileSizeMaxException 当图片文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
*/
@JvmSynthetic
@MiraiExperimentalAPI
override suspend fun uploadGroupVoice(input: InputStream): Voice {
val content = ByteArray(input.available())
input.read(content)
if (content.size > 1048576) {
throw OverFileSizeMaxException()
}
val md5 = MiraiPlatformUtils.md5(content)
return bot.network.run {
val response: PttStore.GroupPttUp.Response.RequireUpload =
PttStore.GroupPttUp(bot.client, bot.id, 0L, md5, content.size.toLong()).sendAndExpect()
HighwayHelper.uploadPttToServers(
bot,
response.uploadIpList.zip(response.uploadPortList),
content,
md5,
response.uKey,
response.fileKey
)
Voice("${md5.toUHexString("")}.amr", md5, content.size.toLong(), "")
}
}
override fun toString(): String = "Group($id)"
}

View File

@ -37,9 +37,8 @@ internal class PttStore {
uin: Long,
groupCode: Long,
md5: ByteArray,
size: Long = 0,
voiceLength: Int = 0,
fileId: Long = 0
size: Long,
codec: Int = 0
): OutgoingPacket {
val pack = Cmd0x388.ReqBody(
netType = 3, // wifi
@ -57,8 +56,8 @@ internal class PttStore {
buType = 4,
innerIp = 0,
buildVer = "6.5.5.663".encodeToByteArray(),
voiceLength = voiceLength,
codec = 0,
voiceLength = 1,
codec = codec,
voiceType = 1,
boolNewUpChan = true
)

View File

@ -18,13 +18,11 @@ import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.isContentEmpty
import net.mamoe.mirai.message.data.toMessage
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.recall
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.internal.runBlocking
import java.io.InputStream
import kotlin.jvm.JvmName
import kotlin.jvm.JvmStatic
import kotlin.jvm.JvmSynthetic
@ -174,6 +172,19 @@ public abstract class Group : Contact(), CoroutineScope {
@JvmSynthetic
public abstract override suspend fun uploadImage(image: ExternalImage): Image
/**
* 上传一个语音消息以备发送.
* 请手动关闭输入流
* 请使用mar格式
* 请注意这是一个实验性api且随时会被删除
* @throws EventCancelledException 当发送消息事件被取消
* @throws OverFileSizeMaxException 当图片文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
*/
@JvmSynthetic
@MiraiExperimentalAPI
public abstract suspend fun uploadGroupVoice(input: InputStream): Voice
public companion object {
/**
* 使用 groupCode 计算 groupUin. 这两个值仅在 mirai 内部协议区分, 一般人使用时无需在意.

View File

@ -159,8 +159,11 @@ public open class BotConfigurationBase internal constructor() {
@MiraiExperimentalAPI
public var json: Json = kotlin.runCatching {
@OptIn(UnstableDefault::class)
Json(JsonConfiguration(isLenient = true, ignoreUnknownKeys = true))
}.getOrElse { Json(JsonConfiguration.Stable) }
Json {
isLenient = true
ignoreUnknownKeys = true
}
}.getOrElse { Json {} }
/**
* 不显示网络日志. 不推荐.

View File

@ -12,14 +12,12 @@
package net.mamoe.mirai.message
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.io.core.Input
import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.utils.OverFileSizeMaxException
import net.mamoe.mirai.utils.sendTo
import net.mamoe.mirai.utils.toExternalImage
import net.mamoe.mirai.utils.upload
import net.mamoe.mirai.message.data.Voice
import net.mamoe.mirai.utils.*
import java.awt.image.BufferedImage
import java.io.File
import java.io.InputStream
@ -120,6 +118,19 @@ public suspend fun File.uploadAsImage(contact: Contact): Image {
return toExternalImage().upload(contact)
}
/**
* [Dispatchers.IO] 中将文件作为语音上传后构造 [Image]
* 请手动关闭输入流
* 请使用mar格式
* 注意这只是个实验性功能且随时可能会删除
* @throws OverFileSizeMaxException
*/
@Throws(OverFileSizeMaxException::class)
@MiraiExperimentalAPI
public suspend fun InputStream.uploadAsGroupVoice(group: Group): Voice {
return group.uploadGroupVoice(this)
}
// endregion
// region Contact.sendImage(IMAGE)