mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
refactor: 获取rkey后进行检查rkey是否正确
This commit is contained in:
parent
297c495df9
commit
de4d901412
@ -82,12 +82,9 @@ export class ConfigUtil {
|
|||||||
fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), 'utf-8')
|
fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), 'utf-8')
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkOldConfig(
|
private checkOldConfig(currentConfig: Config | OB11Config,
|
||||||
currentConfig: Config | OB11Config,
|
|
||||||
oldConfig: Config | OB11Config,
|
oldConfig: Config | OB11Config,
|
||||||
currentKey: string,
|
currentKey: string, oldKey: string) {
|
||||||
oldKey: string,
|
|
||||||
) {
|
|
||||||
// 迁移旧的配置到新配置,避免用户重新填写配置
|
// 迁移旧的配置到新配置,避免用户重新填写配置
|
||||||
const oldValue = oldConfig[oldKey]
|
const oldValue = oldConfig[oldKey]
|
||||||
if (oldValue) {
|
if (oldValue) {
|
||||||
|
@ -12,11 +12,10 @@ export interface OB11Config {
|
|||||||
enableHttpHeart?: boolean
|
enableHttpHeart?: boolean
|
||||||
}
|
}
|
||||||
export interface CheckVersion {
|
export interface CheckVersion {
|
||||||
result: boolean
|
result: boolean,
|
||||||
version: string
|
version: string
|
||||||
}
|
}
|
||||||
export interface Config {
|
export interface Config {
|
||||||
imageRKey?: string
|
|
||||||
ob11: OB11Config
|
ob11: OB11Config
|
||||||
token?: string
|
token?: string
|
||||||
heartInterval?: number // ms
|
heartInterval?: number // ms
|
||||||
@ -29,6 +28,7 @@ export interface Config {
|
|||||||
ffmpeg?: string // ffmpeg路径
|
ffmpeg?: string // ffmpeg路径
|
||||||
enablePoke?: boolean
|
enablePoke?: boolean
|
||||||
musicSignUrl?: string
|
musicSignUrl?: string
|
||||||
|
ignoreBeforeLoginMsg?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LLOneBotError {
|
export interface LLOneBotError {
|
||||||
|
@ -7,30 +7,26 @@ import {
|
|||||||
ChatCacheList,
|
ChatCacheList,
|
||||||
ChatCacheListItemBasic,
|
ChatCacheListItemBasic,
|
||||||
ChatType,
|
ChatType,
|
||||||
ElementType,
|
ElementType, IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, RawMessage,
|
||||||
IMAGE_HTTP_HOST,
|
|
||||||
IMAGE_HTTP_HOST_NT,
|
|
||||||
RawMessage,
|
|
||||||
} from '../types'
|
} from '../types'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { ReceiveCmdS } from '../hook'
|
import { ReceiveCmdS } from '../hook'
|
||||||
import { log } from '../../common/utils'
|
import { log } from '../../common/utils'
|
||||||
import http from 'http'
|
import https from 'https'
|
||||||
import { sleep } from '../../common/utils'
|
import { sleep } from '../../common/utils'
|
||||||
import { hookApi } from '../external/moehook/hook'
|
import { hookApi } from '../external/moehook/hook'
|
||||||
|
|
||||||
let privateImageRKey = ''
|
let privateImageRKey = ''
|
||||||
let groupImageRKey = ''
|
let groupImageRKey = ''
|
||||||
let lastGetRKeyTime = 0
|
let lastGetPrivateRKeyTime = 0
|
||||||
|
let lastGetGroupRKeyTime = 0
|
||||||
const rkeyExpireTime = 1000 * 60 * 30
|
const rkeyExpireTime = 1000 * 60 * 30
|
||||||
|
|
||||||
export class NTQQFileApi {
|
export class NTQQFileApi {
|
||||||
static async getFileType(filePath: string) {
|
static async getFileType(filePath: string) {
|
||||||
return await callNTQQApi<{ ext: string }>({
|
return await callNTQQApi<{ ext: string }>({
|
||||||
className: NTQQApiClass.FS_API,
|
className: NTQQApiClass.FS_API, methodName: NTQQApiMethod.FILE_TYPE, args: [filePath],
|
||||||
methodName: NTQQApiMethod.FILE_TYPE,
|
|
||||||
args: [filePath],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,20 +42,16 @@ export class NTQQFileApi {
|
|||||||
return await callNTQQApi<string>({
|
return await callNTQQApi<string>({
|
||||||
className: NTQQApiClass.FS_API,
|
className: NTQQApiClass.FS_API,
|
||||||
methodName: NTQQApiMethod.FILE_COPY,
|
methodName: NTQQApiMethod.FILE_COPY,
|
||||||
args: [
|
args: [{
|
||||||
{
|
|
||||||
fromPath: filePath,
|
fromPath: filePath,
|
||||||
toPath: destPath,
|
toPath: destPath,
|
||||||
},
|
}],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getFileSize(filePath: string) {
|
static async getFileSize(filePath: string) {
|
||||||
return await callNTQQApi<number>({
|
return await callNTQQApi<number>({
|
||||||
className: NTQQApiClass.FS_API,
|
className: NTQQApiClass.FS_API, methodName: NTQQApiMethod.FILE_SIZE, args: [filePath],
|
||||||
methodName: NTQQApiMethod.FILE_SIZE,
|
|
||||||
args: [filePath],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,8 +70,7 @@ export class NTQQFileApi {
|
|||||||
}
|
}
|
||||||
const mediaPath = await callNTQQApi<string>({
|
const mediaPath = await callNTQQApi<string>({
|
||||||
methodName: NTQQApiMethod.MEDIA_FILE_PATH,
|
methodName: NTQQApiMethod.MEDIA_FILE_PATH,
|
||||||
args: [
|
args: [{
|
||||||
{
|
|
||||||
path_info: {
|
path_info: {
|
||||||
md5HexStr: md5,
|
md5HexStr: md5,
|
||||||
fileName: fileName,
|
fileName: fileName,
|
||||||
@ -90,8 +81,7 @@ export class NTQQFileApi {
|
|||||||
downloadType: 1,
|
downloadType: 1,
|
||||||
file_uuid: '',
|
file_uuid: '',
|
||||||
},
|
},
|
||||||
},
|
}],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
log('media path', mediaPath)
|
log('media path', mediaPath)
|
||||||
await NTQQFileApi.copyFile(filePath, mediaPath)
|
await NTQQFileApi.copyFile(filePath, mediaPath)
|
||||||
@ -105,15 +95,7 @@ export class NTQQFileApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async downloadMedia(
|
static async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, force: boolean = false) {
|
||||||
msgId: string,
|
|
||||||
chatType: ChatType,
|
|
||||||
peerUid: string,
|
|
||||||
elementId: string,
|
|
||||||
thumbPath: string,
|
|
||||||
sourcePath: string,
|
|
||||||
force: boolean = false,
|
|
||||||
) {
|
|
||||||
// 用于下载收到的消息中的图片等
|
// 用于下载收到的消息中的图片等
|
||||||
if (sourcePath && fs.existsSync(sourcePath)) {
|
if (sourcePath && fs.existsSync(sourcePath)) {
|
||||||
if (force) {
|
if (force) {
|
||||||
@ -144,7 +126,7 @@ export class NTQQFileApi {
|
|||||||
methodName: NTQQApiMethod.DOWNLOAD_MEDIA,
|
methodName: NTQQApiMethod.DOWNLOAD_MEDIA,
|
||||||
args: apiParams,
|
args: apiParams,
|
||||||
cbCmd: ReceiveCmdS.MEDIA_DOWNLOAD_COMPLETE,
|
cbCmd: ReceiveCmdS.MEDIA_DOWNLOAD_COMPLETE,
|
||||||
cmdCB: (payload: { notifyInfo: { filePath: string; msgId: string } }) => {
|
cmdCB: (payload: { notifyInfo: { filePath: string, msgId: string } }) => {
|
||||||
log('media 下载完成判断', payload.notifyInfo.msgId, msgId)
|
log('media 下载完成判断', payload.notifyInfo.msgId, msgId)
|
||||||
return payload.notifyInfo.msgId == msgId
|
return payload.notifyInfo.msgId == msgId
|
||||||
},
|
},
|
||||||
@ -153,16 +135,14 @@ export class NTQQFileApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async getImageSize(filePath: string) {
|
static async getImageSize(filePath: string) {
|
||||||
return await callNTQQApi<{ width: number; height: number }>({
|
return await callNTQQApi<{ width: number, height: number }>({
|
||||||
className: NTQQApiClass.FS_API,
|
className: NTQQApiClass.FS_API, methodName: NTQQApiMethod.IMAGE_SIZE, args: [filePath],
|
||||||
methodName: NTQQApiMethod.IMAGE_SIZE,
|
|
||||||
args: [filePath],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getImageUrl(msg: RawMessage) {
|
static async getImageUrl(msg: RawMessage) {
|
||||||
const isPrivateImage = msg.chatType !== ChatType.group
|
const isPrivateImage = msg.chatType !== ChatType.group
|
||||||
const msgElement = msg.elements.find((e) => !!e.picElement)
|
const msgElement = msg.elements.find(e => !!e.picElement)
|
||||||
if (!msgElement) {
|
if (!msgElement) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
@ -185,42 +165,55 @@ export class NTQQFileApi {
|
|||||||
const saveRKey = (rkey: string) => {
|
const saveRKey = (rkey: string) => {
|
||||||
if (isPrivateImage) {
|
if (isPrivateImage) {
|
||||||
privateImageRKey = rkey
|
privateImageRKey = rkey
|
||||||
|
lastGetPrivateRKeyTime = Date.now()
|
||||||
} else {
|
} else {
|
||||||
groupImageRKey = rkey
|
groupImageRKey = rkey
|
||||||
|
lastGetGroupRKeyTime = Date.now()
|
||||||
}
|
}
|
||||||
lastGetRKeyTime = Date.now()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const refreshRKey = async () => {
|
const refreshRKey = async () => {
|
||||||
log('获取图片rkey...')
|
log('获取图片rkey...')
|
||||||
NTQQFileApi.downloadMedia(
|
NTQQFileApi.downloadMedia(msg.msgId, msg.chatType, msg.peerUid, msgElement.elementId, '', msgElement.picElement.sourcePath, false).then().catch(() => {
|
||||||
msg.msgId,
|
})
|
||||||
msg.chatType,
|
|
||||||
msg.peerUid,
|
|
||||||
msgElement.elementId,
|
|
||||||
'',
|
|
||||||
msgElement.picElement.sourcePath,
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
.then()
|
|
||||||
.catch(() => {})
|
|
||||||
await sleep(1000)
|
await sleep(1000)
|
||||||
const _rkey = hookApi.getRKey()
|
const _rkey = hookApi.getRKey()
|
||||||
if (_rkey) {
|
if (_rkey) {
|
||||||
|
const imageUrl = IMAGE_HTTP_HOST_NT + url + _rkey
|
||||||
|
// 验证_rkey是否有效
|
||||||
|
try {
|
||||||
|
await new Promise((res, rej) => {
|
||||||
|
https.get(imageUrl, response => {
|
||||||
|
if (response.statusCode !== 200) {
|
||||||
|
rej('图片rkey获取失败')
|
||||||
|
} else {
|
||||||
|
res(response)
|
||||||
|
}
|
||||||
|
}).on('error', e => {
|
||||||
|
rej(e)
|
||||||
|
})
|
||||||
|
})
|
||||||
log('图片rkey获取成功', _rkey)
|
log('图片rkey获取成功', _rkey)
|
||||||
saveRKey(_rkey)
|
saveRKey(_rkey)
|
||||||
return _rkey
|
return _rkey
|
||||||
|
}catch (e) {
|
||||||
|
log('图片rkey有误', imageUrl)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const existsRKey = isPrivateImage ? privateImageRKey : groupImageRKey
|
const existsRKey = isPrivateImage ? privateImageRKey : groupImageRKey
|
||||||
if (Date.now() - lastGetRKeyTime > rkeyExpireTime || !existsRKey) {
|
const lastGetRKeyTime = isPrivateImage ? lastGetPrivateRKeyTime : lastGetGroupRKeyTime
|
||||||
|
if ((Date.now() - lastGetRKeyTime > rkeyExpireTime)) {
|
||||||
// rkey过期
|
// rkey过期
|
||||||
const newRKey = await refreshRKey()
|
const newRKey = await refreshRKey()
|
||||||
if (newRKey) {
|
if (newRKey) {
|
||||||
return IMAGE_HTTP_HOST_NT + url + `${newRKey}`
|
return IMAGE_HTTP_HOST_NT + url + `${newRKey}`
|
||||||
} else {
|
} else {
|
||||||
log('图片rkey获取失败', url)
|
log('图片rkey获取失败', url)
|
||||||
|
if(existsRKey){
|
||||||
|
return IMAGE_HTTP_HOST_NT + url + `${existsRKey}`
|
||||||
|
}
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,55 +232,44 @@ export class NTQQFileApi {
|
|||||||
log('图片url获取失败', msg)
|
log('图片url获取失败', msg)
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NTQQFileCacheApi {
|
export class NTQQFileCacheApi {
|
||||||
static async setCacheSilentScan(isSilent: boolean = true) {
|
static async setCacheSilentScan(isSilent: boolean = true) {
|
||||||
return await callNTQQApi<GeneralCallResult>({
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
methodName: NTQQApiMethod.CACHE_SET_SILENCE,
|
methodName: NTQQApiMethod.CACHE_SET_SILENCE,
|
||||||
args: [
|
args: [{
|
||||||
{
|
|
||||||
isSilent,
|
isSilent,
|
||||||
},
|
}, null],
|
||||||
null,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static getCacheSessionPathList() {
|
static getCacheSessionPathList() {
|
||||||
return callNTQQApi<
|
return callNTQQApi<{
|
||||||
{
|
key: string,
|
||||||
key: string
|
|
||||||
value: string
|
value: string
|
||||||
}[]
|
}[]>({
|
||||||
>({
|
|
||||||
className: NTQQApiClass.OS_API,
|
className: NTQQApiClass.OS_API,
|
||||||
methodName: NTQQApiMethod.CACHE_PATH_SESSION,
|
methodName: NTQQApiMethod.CACHE_PATH_SESSION,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static clearCache(cacheKeys: Array<string> = ['tmp', 'hotUpdate']) {
|
static clearCache(cacheKeys: Array<string> = ['tmp', 'hotUpdate']) {
|
||||||
return callNTQQApi<any>({
|
return callNTQQApi<any>({ // TODO: 目前还不知道真正的返回值是什么
|
||||||
// TODO: 目前还不知道真正的返回值是什么
|
|
||||||
methodName: NTQQApiMethod.CACHE_CLEAR,
|
methodName: NTQQApiMethod.CACHE_CLEAR,
|
||||||
args: [
|
args: [{
|
||||||
{
|
|
||||||
keys: cacheKeys,
|
keys: cacheKeys,
|
||||||
},
|
}, null],
|
||||||
null,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static addCacheScannedPaths(pathMap: object = {}) {
|
static addCacheScannedPaths(pathMap: object = {}) {
|
||||||
return callNTQQApi<GeneralCallResult>({
|
return callNTQQApi<GeneralCallResult>({
|
||||||
methodName: NTQQApiMethod.CACHE_ADD_SCANNED_PATH,
|
methodName: NTQQApiMethod.CACHE_ADD_SCANNED_PATH,
|
||||||
args: [
|
args: [{
|
||||||
{
|
|
||||||
pathMap: { ...pathMap },
|
pathMap: { ...pathMap },
|
||||||
},
|
}, null],
|
||||||
null,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,18 +303,14 @@ export class NTQQFileCacheApi {
|
|||||||
return new Promise<ChatCacheList>((res, rej) => {
|
return new Promise<ChatCacheList>((res, rej) => {
|
||||||
callNTQQApi<ChatCacheList>({
|
callNTQQApi<ChatCacheList>({
|
||||||
methodName: NTQQApiMethod.CACHE_CHAT_GET,
|
methodName: NTQQApiMethod.CACHE_CHAT_GET,
|
||||||
args: [
|
args: [{
|
||||||
{
|
|
||||||
chatType: type,
|
chatType: type,
|
||||||
pageSize,
|
pageSize,
|
||||||
order: 1,
|
order: 1,
|
||||||
pageIndex,
|
pageIndex,
|
||||||
},
|
}, null],
|
||||||
null,
|
}).then(list => res(list))
|
||||||
],
|
.catch(e => rej(e))
|
||||||
})
|
|
||||||
.then((list) => res(list))
|
|
||||||
.catch((e) => rej(e))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,29 +319,24 @@ export class NTQQFileCacheApi {
|
|||||||
|
|
||||||
return callNTQQApi<CacheFileList>({
|
return callNTQQApi<CacheFileList>({
|
||||||
methodName: NTQQApiMethod.CACHE_FILE_GET,
|
methodName: NTQQApiMethod.CACHE_FILE_GET,
|
||||||
args: [
|
args: [{
|
||||||
{
|
|
||||||
fileType: fileType,
|
fileType: fileType,
|
||||||
restart: true,
|
restart: true,
|
||||||
pageSize: pageSize,
|
pageSize: pageSize,
|
||||||
order: 1,
|
order: 1,
|
||||||
lastRecord: _lastRecord,
|
lastRecord: _lastRecord,
|
||||||
},
|
}, null],
|
||||||
null,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) {
|
static async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) {
|
||||||
return await callNTQQApi<GeneralCallResult>({
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
methodName: NTQQApiMethod.CACHE_CHAT_CLEAR,
|
methodName: NTQQApiMethod.CACHE_CHAT_CLEAR,
|
||||||
args: [
|
args: [{
|
||||||
{
|
|
||||||
chats,
|
chats,
|
||||||
fileKeys,
|
fileKeys,
|
||||||
},
|
}, null],
|
||||||
null,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
12
test/check_image_url.js
Normal file
12
test/check_image_url.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import http from 'https'
|
||||||
|
|
||||||
|
function checkUrl(imageUrl) {
|
||||||
|
http.get(imageUrl, response => {
|
||||||
|
console.log(response.statusCode)
|
||||||
|
}).on('error', e => {
|
||||||
|
console.log(e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
checkUrl('https://gchat.qpic.cn/download?appid=1407&fileid=CgoxMzMyNTI0MjIxEhRrdaUgQP5MjweWa4uR8pviUDaGQhjcxQUg_wooiYTj39fphQNQgL2jAQ&spec=0&rkey=CAQSKAB6JWENi5LMk0kc62l8Pm3Jn1dsLZHyRLAnNmHGoZ3y_gDZPqZt-64')
|
||||||
|
checkUrl('https://multimedia.nt.qq.com.cn/download?appid=1407&fileid=CgoxMzMyNTI0MjIxEhRrdaUgQP5MjweWa4uR8pviUDaGQhjcxQUg_wooiYTj39fphQNQgL2jAQ&spec=0&rkey=CAQSKAB6JWENi5LMk0kc62l8Pm3Jn1dsLZHyRLAnNmHGoZ3y_gDZPqZt-64')
|
Loading…
x
Reference in New Issue
Block a user