Merge pull request #224 from LLOneBot/dev

Fix: #219,发送视频图片进行文件大小判断,超时时间根据文件大小(512kb/s)动态调整
This commit is contained in:
linyuchen 2024-05-18 12:53:42 +08:00 committed by GitHub
commit 627042fd25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 207 additions and 172 deletions

View File

@ -76,8 +76,9 @@ export class SendMsgElementConstructor {
if (fileSize === 0) { if (fileSize === 0) {
throw '文件异常大小为0' throw '文件异常大小为0'
} }
if (fileSize > 1000 * 1000 * 7){ // todo: 没有采用1024计算因为具体上限数值未知大概是7MB const maxMB = 30;
throw `图片过大最大支持7MB当前文件大小${fileSize}B` if (fileSize > 1024 * 1024 * 30){
throw `图片过大,最大支持${maxMB}MB当前文件大小${fileSize}B`
} }
const imageSize = await NTQQFileApi.getImageSize(picPath) const imageSize = await NTQQFileApi.getImageSize(picPath)
const picElement = { const picElement = {
@ -134,8 +135,9 @@ export class SendMsgElementConstructor {
if (fileSize === 0) { if (fileSize === 0) {
throw '文件异常大小为0' throw '文件异常大小为0'
} }
if (fileSize > 1000 * 1000 * 100) { // todo: 没有采用1024计算因为具体上限数值未知大概是100MB const maxMB = 100;
throw `视频过大最大支持100MB当前文件大小${fileSize}B` if (fileSize > 1024 * 1024 * maxMB) {
throw `视频过大,最大支持${maxMB}MB当前文件大小${fileSize}B`
} }
const pathLib = require('path') const pathLib = require('path')
let thumbDir = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`) let thumbDir = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`)

View File

@ -50,22 +50,28 @@ function checkSendMessage(sendMsgList: OB11MessageData[]) {
let data = msg['data'] let data = msg['data']
if (type === 'text' && !data['text']) { if (type === 'text' && !data['text']) {
return 400 return 400
} else if (['image', 'voice', 'record'].includes(type)) { }
else if (['image', 'voice', 'record'].includes(type)) {
if (!data['file']) { if (!data['file']) {
return 400 return 400
} else { }
else {
if (checkUri(data['file'])) { if (checkUri(data['file'])) {
return 200 return 200
} else { }
else {
return 400 return 400
} }
} }
} else if (type === 'at' && !data['qq']) { }
return 400 else if (type === 'at' && !data['qq']) {
} else if (type === 'reply' && !data['id']) {
return 400 return 400
} }
} else { else if (type === 'reply' && !data['id']) {
return 400
}
}
else {
return 400 return 400
} }
} }
@ -87,10 +93,12 @@ export function convertMessage2List(message: OB11MessageMixType, autoEscape = fa
}, },
}, },
] ]
} else { }
else {
message = decodeCQCode(message.toString()) message = decodeCQCode(message.toString())
} }
} else if (!Array.isArray(message)) { }
else if (!Array.isArray(message)) {
message = [message] message = [message]
} }
return message return message
@ -108,16 +116,14 @@ export async function createSendElements(
continue continue
} }
switch (sendMsg.type) { switch (sendMsg.type) {
case OB11MessageDataType.text: case OB11MessageDataType.text: {
{
const text = sendMsg.data?.text const text = sendMsg.data?.text
if (text) { if (text) {
sendElements.push(SendMsgElementConstructor.text(sendMsg.data!.text)) sendElements.push(SendMsgElementConstructor.text(sendMsg.data!.text))
} }
} }
break break
case OB11MessageDataType.at: case OB11MessageDataType.at: {
{
if (!target) { if (!target) {
continue continue
} }
@ -136,12 +142,14 @@ export async function createSendElements(
log(`${groupCode}剩余at全体次数`, remainAtAllCount) log(`${groupCode}剩余at全体次数`, remainAtAllCount)
const self = await getGroupMember((target as Group)?.groupCode, selfInfo.uin) const self = await getGroupMember((target as Group)?.groupCode, selfInfo.uin)
isAdmin = self.role === GroupMemberRole.admin || self.role === GroupMemberRole.owner isAdmin = self.role === GroupMemberRole.admin || self.role === GroupMemberRole.owner
} catch (e) {} } catch (e) {
}
} }
if (isAdmin && remainAtAllCount > 0) { if (isAdmin && remainAtAllCount > 0) {
sendElements.push(SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, '全体成员')) sendElements.push(SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, '全体成员'))
} }
} else { }
else {
// const atMember = group?.members.find(m => m.uin == atQQ) // const atMember = group?.members.find(m => m.uin == atQQ)
const atMember = await getGroupMember((target as Group)?.groupCode, atQQ) const atMember = await getGroupMember((target as Group)?.groupCode, atQQ)
if (atMember) { if (atMember) {
@ -153,8 +161,7 @@ export async function createSendElements(
} }
} }
break break
case OB11MessageDataType.reply: case OB11MessageDataType.reply: {
{
let replyMsgId = sendMsg.data.id let replyMsgId = sendMsg.data.id
if (replyMsgId) { if (replyMsgId) {
const replyMsg = await dbUtil.getMsgByShortId(parseInt(replyMsgId)) const replyMsg = await dbUtil.getMsgByShortId(parseInt(replyMsgId))
@ -171,16 +178,14 @@ export async function createSendElements(
} }
} }
break break
case OB11MessageDataType.face: case OB11MessageDataType.face: {
{
const faceId = sendMsg.data?.id const faceId = sendMsg.data?.id
if (faceId) { if (faceId) {
sendElements.push(SendMsgElementConstructor.face(parseInt(faceId))) sendElements.push(SendMsgElementConstructor.face(parseInt(faceId)))
} }
} }
break break
case OB11MessageDataType.mface: case OB11MessageDataType.mface: {
{
sendElements.push( sendElements.push(
SendMsgElementConstructor.mface( SendMsgElementConstructor.mface(
sendMsg.data.emoji_package_id, sendMsg.data.emoji_package_id,
@ -194,8 +199,7 @@ export async function createSendElements(
case OB11MessageDataType.image: case OB11MessageDataType.image:
case OB11MessageDataType.file: case OB11MessageDataType.file:
case OB11MessageDataType.video: case OB11MessageDataType.video:
case OB11MessageDataType.voice: case OB11MessageDataType.voice: {
{
const data = (sendMsg as OB11MessageFile).data const data = (sendMsg as OB11MessageFile).data
let file = data.file let file = data.file
const payloadFileName = data?.name const payloadFileName = data?.name
@ -204,10 +208,12 @@ export async function createSendElements(
if (cache) { if (cache) {
if (fs.existsSync(cache.filePath)) { if (fs.existsSync(cache.filePath)) {
file = 'file://' + cache.filePath file = 'file://' + cache.filePath
} else if (cache.downloadFunc) { }
else if (cache.downloadFunc) {
await cache.downloadFunc() await cache.downloadFunc()
file = cache.filePath file = cache.filePath
} else if (cache.url) { }
else if (cache.url) {
file = cache.url file = cache.url
} }
log('找到文件缓存', file) log('找到文件缓存', file)
@ -224,7 +230,8 @@ export async function createSendElements(
if (sendMsg.type === OB11MessageDataType.file) { if (sendMsg.type === OB11MessageDataType.file) {
log('发送文件', path, payloadFileName || fileName) log('发送文件', path, payloadFileName || fileName)
sendElements.push(await SendMsgElementConstructor.file(path, payloadFileName || fileName)) sendElements.push(await SendMsgElementConstructor.file(path, payloadFileName || fileName))
} else if (sendMsg.type === OB11MessageDataType.video) { }
else if (sendMsg.type === OB11MessageDataType.video) {
log('发送视频', path, payloadFileName || fileName) log('发送视频', path, payloadFileName || fileName)
let thumb = sendMsg.data?.thumb let thumb = sendMsg.data?.thumb
if (thumb) { if (thumb) {
@ -234,9 +241,11 @@ export async function createSendElements(
} }
} }
sendElements.push(await SendMsgElementConstructor.video(path, payloadFileName || fileName, thumb)) sendElements.push(await SendMsgElementConstructor.video(path, payloadFileName || fileName, thumb))
} else if (sendMsg.type === OB11MessageDataType.voice) { }
else if (sendMsg.type === OB11MessageDataType.voice) {
sendElements.push(await SendMsgElementConstructor.ptt(path)) sendElements.push(await SendMsgElementConstructor.ptt(path))
} else if (sendMsg.type === OB11MessageDataType.image) { }
else if (sendMsg.type === OB11MessageDataType.image) {
sendElements.push( sendElements.push(
await SendMsgElementConstructor.pic( await SendMsgElementConstructor.pic(
path, path,
@ -249,18 +258,17 @@ export async function createSendElements(
} }
} }
break break
case OB11MessageDataType.json: case OB11MessageDataType.json: {
{
sendElements.push(SendMsgElementConstructor.ark(sendMsg.data.data)) sendElements.push(SendMsgElementConstructor.ark(sendMsg.data.data))
} }
break break
case OB11MessageDataType.poke: case OB11MessageDataType.poke: {
{
let qq = sendMsg.data?.qq || sendMsg.data?.id let qq = sendMsg.data?.qq || sendMsg.data?.id
if (qq) { if (qq) {
if ('groupCode' in target) { if ('groupCode' in target) {
crychic.sendGroupPoke(target.groupCode, qq.toString()) crychic.sendGroupPoke(target.groupCode, qq.toString())
} else { }
else {
if (!qq) { if (!qq) {
qq = parseInt(target.uin) qq = parseInt(target.uin)
} }
@ -270,14 +278,12 @@ export async function createSendElements(
} }
} }
break break
case OB11MessageDataType.dice: case OB11MessageDataType.dice: {
{
const resultId = sendMsg.data?.result const resultId = sendMsg.data?.result
sendElements.push(SendMsgElementConstructor.dice(resultId)) sendElements.push(SendMsgElementConstructor.dice(resultId))
} }
break break
case OB11MessageDataType.RPS: case OB11MessageDataType.RPS: {
{
const resultId = sendMsg.data?.result const resultId = sendMsg.data?.result
sendElements.push(SendMsgElementConstructor.rps(resultId)) sendElements.push(SendMsgElementConstructor.rps(resultId))
} }
@ -300,10 +306,34 @@ export async function sendMsg(
if (!sendElements.length) { if (!sendElements.length) {
throw '消息体无法解析,请检查是否发送了不支持的消息类型' throw '消息体无法解析,请检查是否发送了不支持的消息类型'
} }
const returnMsg = await NTQQMsgApi.sendMsg(peer, sendElements, waitComplete, 20000) // 计算发送的文件大小
let totalSize = 0
for (const fileElement of sendElements) {
try {
if (fileElement.elementType === ElementType.PTT) {
totalSize += fs.statSync(fileElement.pttElement.filePath).size
}
if (fileElement.elementType === ElementType.FILE) {
totalSize += fs.statSync(fileElement.fileElement.filePath).size
}
if (fileElement.elementType === ElementType.VIDEO) {
totalSize += fs.statSync(fileElement.videoElement.filePath).size
}
if (fileElement.elementType === ElementType.PIC) {
totalSize += fs.statSync(fileElement.picElement.sourcePath).size
}
} catch (e) {
log('文件大小计算失败', e, fileElement)
}
}
log('发送消息总大小', totalSize, 'bytes')
let timeout = ((totalSize / 1024 / 512) * 1000) || 5000 // 512kb/s
log('设置消息超时时间', timeout)
const returnMsg = await NTQQMsgApi.sendMsg(peer, sendElements, waitComplete, timeout)
log('消息发送结果', returnMsg) log('消息发送结果', returnMsg)
returnMsg.msgShortId = await dbUtil.addMsg(returnMsg) returnMsg.msgShortId = await dbUtil.addMsg(returnMsg)
deleteAfterSentFiles.map((f) => fs.unlink(f, () => {})) deleteAfterSentFiles.map((f) => fs.unlink(f, () => {
}))
return returnMsg return returnMsg
} }
@ -402,7 +432,8 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
} catch (e) { } catch (e) {
throw '发送转发消息失败 ' + e.toString() throw '发送转发消息失败 ' + e.toString()
} }
} else if (this.getSpecialMsgNum(messages, OB11MessageDataType.music)) { }
else if (this.getSpecialMsgNum(messages, OB11MessageDataType.music)) {
const music = messages[0] as OB11MessageMusic const music = messages[0] as OB11MessageMusic
if (music) { if (music) {
const { musicSignUrl } = getConfigUtil().getConfig() const { musicSignUrl } = getConfigUtil().getConfig()
@ -459,7 +490,8 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
} }
} }
const returnMsg = await sendMsg(peer, sendElements, deleteAfterSentFiles) const returnMsg = await sendMsg(peer, sendElements, deleteAfterSentFiles)
deleteAfterSentFiles.map((f) => fs.unlink(f, () => {})) deleteAfterSentFiles.map((f) => fs.unlink(f, () => {
}))
return { message_id: returnMsg.msgShortId } return { message_id: returnMsg.msgShortId }
} }
@ -562,7 +594,8 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
await sleep(500) await sleep(500)
log('转发节点生成成功', nodeMsg.msgId) log('转发节点生成成功', nodeMsg.msgId)
} }
deleteAfterSentFiles.map((f) => fs.unlink(f, () => {})) deleteAfterSentFiles.map((f) => fs.unlink(f, () => {
}))
} catch (e) { } catch (e) {
log('生成转发消息节点失败', e) log('生成转发消息节点失败', e)
} }