mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-18 09:07:04 +08:00
Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt
This commit is contained in:
commit
6c21971ce0
@ -453,7 +453,7 @@ internal class GroupImpl(
|
||||
* 上传一个语音消息以备发送.
|
||||
* 请注意,这是一个实验性api且随时会被删除
|
||||
* @throws EventCancelledException 当发送消息事件被取消
|
||||
* @throws OverFileSizeMaxException 当图片文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
|
||||
* @throws OverFileSizeMaxException 当语音文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@MiraiExperimentalAPI
|
||||
@ -465,16 +465,24 @@ internal class GroupImpl(
|
||||
throw OverFileSizeMaxException()
|
||||
}
|
||||
val md5 = MiraiPlatformUtils.md5(content)
|
||||
val codec = with(content.copyOfRange(0, 10).toUHexString("")) {
|
||||
when {
|
||||
startsWith("2321414D52") -> 0 // amr
|
||||
startsWith("02232153494C4B5F5633") -> 1 // silk V3
|
||||
else -> 0 // use amr by default
|
||||
}
|
||||
}
|
||||
return bot.network.run {
|
||||
val response: PttStore.GroupPttUp.Response.RequireUpload =
|
||||
PttStore.GroupPttUp(bot.client, bot.id, 0L, md5, content.size.toLong()).sendAndExpect()
|
||||
PttStore.GroupPttUp(bot.client, bot.id, id, md5, content.size.toLong(), codec).sendAndExpect()
|
||||
HighwayHelper.uploadPttToServers(
|
||||
bot,
|
||||
response.uploadIpList.zip(response.uploadPortList),
|
||||
content,
|
||||
md5,
|
||||
response.uKey,
|
||||
response.fileKey
|
||||
response.fileKey,
|
||||
codec
|
||||
)
|
||||
Voice("${md5.toUHexString("")}.amr", md5, content.size.toLong(), "")
|
||||
}
|
||||
|
@ -413,9 +413,8 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
logger.info { "Syncing friend message history..." }
|
||||
withTimeoutOrNull(30000) {
|
||||
launch(CoroutineName("Syncing friend message history")) { syncFromEvent<MessageSvcPbGetMsg.GetMsgSuccess, Unit> { Unit } }
|
||||
// 别问我为什么要发两个 我也不知道 反正它能用
|
||||
MessageSvcPbGetMsg(bot.client, MsgSvc.SyncFlag.START, null, firstSync = true).sendAndExpect<Packet>()
|
||||
MessageSvcPbGetMsg(bot.client, MsgSvc.SyncFlag.START, null, firstSync = true).sendAndExpect<Packet>()
|
||||
MessageSvcPbGetMsg(bot.client, MsgSvc.SyncFlag.START, null).sendAndExpect<Packet>()
|
||||
|
||||
} ?: error("timeout syncing friend message history")
|
||||
logger.info { "Syncing friend message history: Success" }
|
||||
}
|
||||
|
@ -128,8 +128,6 @@ internal open class QQAndroidClient(
|
||||
|
||||
lateinit var fileStoragePushFSSvcList: FileStoragePushFSSvcListFuckKotlin
|
||||
|
||||
internal val firstSyncPackets: AtomicInt = atomic(0) // 启动时候仅将所有好友信息设为已读的包
|
||||
|
||||
internal suspend inline fun useNextServers(crossinline block: suspend (host: String, port: Int) -> Unit) {
|
||||
if (bot.client.serverList.isEmpty()) {
|
||||
throw NoServerAvailableException(null)
|
||||
|
@ -190,7 +190,9 @@ internal object HighwayHelper {
|
||||
servers: List<Pair<Int, Int>>,
|
||||
content: ByteArray,
|
||||
md5: ByteArray,
|
||||
uKey: ByteArray, fileKey: ByteArray
|
||||
uKey: ByteArray,
|
||||
fileKey: ByteArray,
|
||||
codec: Int
|
||||
) {
|
||||
servers.retryWithServers(10 * 1000, {
|
||||
throw IllegalStateException("cannot upload ptt, failed on all servers.", it)
|
||||
@ -199,7 +201,7 @@ internal object HighwayHelper {
|
||||
"[Highway] Uploading ptt to ${s}:$i, size=${content.size.toLong().sizeToString()}"
|
||||
}
|
||||
val time = measureTime {
|
||||
uploadPttToServer(s, i, content, md5, uKey, fileKey)
|
||||
uploadPttToServer(s, i, content, md5, uKey, fileKey, codec)
|
||||
}
|
||||
bot.network.logger.verbose {
|
||||
"[Highway] Uploading ptt: succeed at ${(content.size.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
|
||||
@ -214,7 +216,9 @@ internal object HighwayHelper {
|
||||
serverPort: Int,
|
||||
content: ByteArray,
|
||||
md5: ByteArray,
|
||||
uKey: ByteArray, fileKey: ByteArray
|
||||
uKey: ByteArray,
|
||||
fileKey: ByteArray,
|
||||
codec: Int
|
||||
) {
|
||||
MiraiPlatformUtils.Http.post<String> {
|
||||
url("http://$serverIp:$serverPort")
|
||||
@ -224,7 +228,7 @@ internal object HighwayHelper {
|
||||
parameter("filesize", content.size)
|
||||
parameter("bmd5", md5.toUHexString(""))
|
||||
parameter("mType", "pttDu")
|
||||
parameter("voice_encodec", 0)
|
||||
parameter("voice_encodec", codec)
|
||||
body = content
|
||||
}
|
||||
}
|
||||
|
@ -61,14 +61,10 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
||||
client: QQAndroidClient,
|
||||
syncFlag: MsgSvc.SyncFlag = MsgSvc.SyncFlag.START,
|
||||
syncCookie: ByteArray?, //PbPushMsg.msg.msgHead.msgTime
|
||||
firstSync: Boolean = false
|
||||
): OutgoingPacket = buildOutgoingUniPacket(
|
||||
client
|
||||
) {
|
||||
//println("syncCookie=${client.c2cMessageSync.syncCookie?.toUHexString()}")
|
||||
if (firstSync) {
|
||||
client.firstSyncPackets.getAndAdd(1)
|
||||
}
|
||||
writeProtoBuf(
|
||||
MsgSvc.PbGetMsgReq.serializer(),
|
||||
MsgSvc.PbGetMsgReq(
|
||||
@ -150,10 +146,13 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
||||
|
||||
val messages = resp.uinPairMsgs.asFlow()
|
||||
.filterNot { it.msg == null }
|
||||
.flatMapConcat { it.msg!!.asFlow() }
|
||||
.also {
|
||||
MessageSvcPbDeleteMsg.delete(bot, it)
|
||||
} // 删除消息
|
||||
.flatMapConcat {
|
||||
it.msg!!.asFlow()
|
||||
.filter { msg: MsgComm.Msg -> msg.msgHead.msgTime > it.lastReadTime.toLong() and 4294967295L }
|
||||
}.also {
|
||||
MessageSvcPbDeleteMsg.delete(bot, it) // 删除消息
|
||||
// todo 实现一个锁来防止重复收到消息
|
||||
}
|
||||
.mapNotNull<MsgComm.Msg, Packet> { msg ->
|
||||
|
||||
suspend fun createGroupForBot(groupUin: Long): Group? {
|
||||
@ -277,9 +276,6 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
||||
*/
|
||||
|
||||
166 -> {
|
||||
if (bot.client.firstSyncPackets.value != 0) {
|
||||
return@mapNotNull null
|
||||
}
|
||||
if (msg.msgHead.fromUin == bot.id) {
|
||||
loop@ while (true) {
|
||||
val instance = bot.client.getFriendSeq()
|
||||
@ -383,9 +379,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
||||
override suspend fun QQAndroidBot.handle(packet: Response) {
|
||||
when (packet.syncFlagFromServer) {
|
||||
MsgSvc.SyncFlag.STOP -> {
|
||||
if (client.firstSyncPackets.value != 0) {
|
||||
client.firstSyncPackets.getAndDecrement()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MsgSvc.SyncFlag.START -> {
|
||||
|
@ -175,15 +175,15 @@ public abstract class Group : Contact(), CoroutineScope {
|
||||
/**
|
||||
* 上传一个语音消息以备发送.
|
||||
* 请手动关闭输入流
|
||||
* 请使用mar格式
|
||||
* 请使用amr或silk格式
|
||||
* 请注意,这是一个实验性api且随时会被删除
|
||||
* @throws EventCancelledException 当发送消息事件被取消
|
||||
* @throws OverFileSizeMaxException 当图片文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
|
||||
* @throws OverFileSizeMaxException 当语音文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@MiraiExperimentalAPI
|
||||
@SinceMirai("1.2.0")
|
||||
public abstract suspend fun uploadVoice(input: InputStream): Voice
|
||||
public abstract suspend fun uploadGroupVoice(input: InputStream): Voice
|
||||
|
||||
|
||||
public companion object {
|
||||
|
@ -119,14 +119,15 @@ public suspend fun File.uploadAsImage(contact: Contact): Image {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 [Dispatchers.IO] 中将文件作为语音上传后构造 [Image]
|
||||
* 在 [Dispatchers.IO] 中将文件作为语音上传后构造 [Voice]
|
||||
* 请手动关闭输入流
|
||||
* 请使用mar格式
|
||||
* 请使用amr或silk格式
|
||||
* 注意,这只是个实验性功能且随时可能会删除
|
||||
* @throws OverFileSizeMaxException
|
||||
*/
|
||||
@Throws(OverFileSizeMaxException::class)
|
||||
@MiraiExperimentalAPI
|
||||
@SinceMirai("1.2.0")
|
||||
public suspend fun InputStream.uploadAsGroupVoice(group: Group): Voice {
|
||||
return group.uploadGroupVoice(this)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user