From c32db4a8811ada0237cc9c9f8e9af39209bfde1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 2 Oct 2024 10:03:48 +0800 Subject: [PATCH] fix: rkey v2 --- src/core/apis/file.ts | 39 ++++++++++++++++++++++++++--------- src/core/helper/rkey.ts | 14 +++++++++++-- src/core/proto/ImageFileId.ts | 21 +++++++++++++++++++ 3 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 src/core/proto/ImageFileId.ts diff --git a/src/core/apis/file.ts b/src/core/apis/file.ts index 27f5ebafa..c47050711 100644 --- a/src/core/apis/file.ts +++ b/src/core/apis/file.ts @@ -365,22 +365,41 @@ export class NTQQFileApi { if (url) { const parsedUrl = new URL(IMAGE_HTTP_HOST + url); + const urlRkey = parsedUrl.searchParams.get('rkey'); const imageAppid = parsedUrl.searchParams.get('appid'); const isNTV2 = imageAppid && ['1406', '1407'].includes(imageAppid); - if (isNTV2) { - let rkey = parsedUrl.searchParams.get('rkey'); - if (rkey) { - return IMAGE_HTTP_HOST_NT + url; - } - const rkeyData = await this.rkeyManager.getRkey(); - rkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey; - return IMAGE_HTTP_HOST_NT + url + `${rkey}`; - } else { - return IMAGE_HTTP_HOST + url; + const imageFileId = parsedUrl.searchParams.get('fileid'); + + let rkeyData = { + private_rkey: 'CAQSKAB6JWENi5LM_xp9vumLbuThJSaYf-yzMrbZsuq7Uz2qEc3Rbib9LP4', + group_rkey: 'CAQSKAB6JWENi5LM_xp9vumLbuThJSaYf-yzMrbZsuq7Uz2qffcqm614gds', + online_rkey: false + }; + + try { + let tempRkeyData = await this.rkeyManager.getRkey(); + rkeyData.group_rkey = tempRkeyData.group_rkey; + rkeyData.private_rkey = tempRkeyData.private_rkey; + rkeyData.online_rkey = tempRkeyData.expired_time > Date.now() / 1000; + } catch (e) { + this.context.logger.logError.bind(this.context.logger)('获取rkey失败 Fallback Old Mode', e); } + + + if (isNTV2 && urlRkey) { + return IMAGE_HTTP_HOST_NT + urlRkey; + } else if (isNTV2 && rkeyData.online_rkey) { + let rkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey; + return IMAGE_HTTP_HOST_NT + url + `&rkey=${rkey}`; + } else if (isNTV2 && imageFileId) { + let rkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey; + return IMAGE_HTTP_HOST + `/download?appid=${imageAppid}&fileid=${imageFileId}&rkey=${rkey}`; + } + } else if (fileMd5 || md5HexStr) { return `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${(fileMd5 ?? md5HexStr)!.toUpperCase()}/0`; } + this.context.logger.logDebug('图片url获取失败', element); return ''; } diff --git a/src/core/helper/rkey.ts b/src/core/helper/rkey.ts index 0c74f45c7..852cafede 100644 --- a/src/core/helper/rkey.ts +++ b/src/core/helper/rkey.ts @@ -26,7 +26,8 @@ export class RkeyManager { try { await this.refreshRkey(); } catch (e) { - this.logger.logError.bind(this.logger)('获取rkey失败', e); + throw new Error(`获取rkey失败: ${e}`);//外抛 + //this.logger.logError.bind(this.logger)('获取rkey失败', e); } } return this.rkeyData; @@ -42,9 +43,18 @@ export class RkeyManager { //刷新rkey for (const url of this.serverUrl) { try { - this.rkeyData = await RequestUtil.HttpGetJson(url, 'GET'); + let temp = await RequestUtil.HttpGetJson(url, 'GET'); + this.rkeyData = { + group_rkey: temp.group_rkey.slice(6), + private_rkey: temp.private_rkey.slice(6), + expired_time: temp.expired_time + }; } catch (e) { this.logger.logError.bind(this.logger)(`[Rkey] Get Rkey ${url} Error `, e); + //是否为最后一个url + if (url === this.serverUrl[this.serverUrl.length - 1]) { + throw new Error(`获取rkey失败: ${e}`);//外抛 + } } } diff --git a/src/core/proto/ImageFileId.ts b/src/core/proto/ImageFileId.ts new file mode 100644 index 000000000..25ad0ee7a --- /dev/null +++ b/src/core/proto/ImageFileId.ts @@ -0,0 +1,21 @@ +import { MessageType, BinaryReader, ScalarType, BinaryWriter } from '@protobuf-ts/runtime'; + +export const FileId = new MessageType("FileId", [ + { no: 2, name: "sha1", kind: "scalar", T: ScalarType.BYTES }, + { no: 4, name: "appid", kind: "scalar", T: ScalarType.UINT32 }, +]); + +export function encodePBFileId(message: any) { + return FileId.internalBinaryWrite(message, new BinaryWriter(), { + writerFactory: () => new BinaryWriter(), + writeUnknownFields: false + }).finish(); +} + +export function decodePBFileId(buffer: Uint8Array): any { + const reader = new BinaryReader(buffer); + return FileId.internalBinaryRead(reader, reader.len, { + readUnknownField: true, + readerFactory: () => new BinaryReader(buffer) + }); +} \ No newline at end of file