mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-12-19 13:10:16 +08:00
feat: new napcat-4.9.0-beta
This commit is contained in:
parent
f9c9b3a852
commit
6778bd69de
@ -64,7 +64,7 @@ export class NTQQFileApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFileUrl(chatType: ChatType, peer: string, fileUUID?: string, file10MMd5?: string | undefined,timeout: number = 20000) {
|
async getFileUrl(chatType: ChatType, peer: string, fileUUID?: string, file10MMd5?: string | undefined,timeout: number = 5000) {
|
||||||
if (this.core.apis.PacketApi.packetStatus) {
|
if (this.core.apis.PacketApi.packetStatus) {
|
||||||
try {
|
try {
|
||||||
if (chatType === ChatType.KCHATTYPEGROUP && fileUUID) {
|
if (chatType === ChatType.KCHATTYPEGROUP && fileUUID) {
|
||||||
@ -79,7 +79,7 @@ export class NTQQFileApi {
|
|||||||
throw new Error('fileUUID or file10MMd5 is undefined');
|
throw new Error('fileUUID or file10MMd5 is undefined');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPttUrl(peer: string, fileUUID?: string,timeout: number = 20000) {
|
async getPttUrl(peer: string, fileUUID?: string,timeout: number = 5000) {
|
||||||
if (this.core.apis.PacketApi.packetStatus && fileUUID) {
|
if (this.core.apis.PacketApi.packetStatus && fileUUID) {
|
||||||
let appid = new NapProtoMsg(FileId).decode(Buffer.from(fileUUID.replaceAll('-', '+').replaceAll('_', '/'), 'base64')).appid;
|
let appid = new NapProtoMsg(FileId).decode(Buffer.from(fileUUID.replaceAll('-', '+').replaceAll('_', '/'), 'base64')).appid;
|
||||||
try {
|
try {
|
||||||
@ -107,7 +107,7 @@ export class NTQQFileApi {
|
|||||||
throw new Error('packet cant get ptt url');
|
throw new Error('packet cant get ptt url');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getVideoUrlPacket(peer: string, fileUUID?: string,timeout: number = 20000) {
|
async getVideoUrlPacket(peer: string, fileUUID?: string,timeout: number = 5000) {
|
||||||
if (this.core.apis.PacketApi.packetStatus && fileUUID) {
|
if (this.core.apis.PacketApi.packetStatus && fileUUID) {
|
||||||
let appid = new NapProtoMsg(FileId).decode(Buffer.from(fileUUID.replaceAll('-', '+').replaceAll('_', '/'), 'base64')).appid;
|
let appid = new NapProtoMsg(FileId).decode(Buffer.from(fileUUID.replaceAll('-', '+').replaceAll('_', '/'), 'base64')).appid;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -13,12 +13,11 @@ import {
|
|||||||
Peer,
|
Peer,
|
||||||
ChatType,
|
ChatType,
|
||||||
} from '@/core';
|
} from '@/core';
|
||||||
import { isNumeric, sleep, solveAsyncProblem } from '@/common/helper';
|
import { isNumeric, solveAsyncProblem } from '@/common/helper';
|
||||||
import { LimitedHashTable } from '@/common/message-unique';
|
import { LimitedHashTable } from '@/common/message-unique';
|
||||||
import { NTEventWrapper } from '@/common/event';
|
import { NTEventWrapper } from '@/common/event';
|
||||||
import { CancelableTask, TaskExecutor } from '@/common/cancel-task';
|
import { CancelableTask, TaskExecutor } from '@/common/cancel-task';
|
||||||
import { createGroupDetailInfoV2Param, createGroupExtFilter, createGroupExtInfo } from '../data';
|
import { createGroupDetailInfoV2Param, createGroupExtFilter, createGroupExtInfo } from '../data';
|
||||||
import { dlopen } from 'node:process';
|
|
||||||
|
|
||||||
export class NTQQGroupApi {
|
export class NTQQGroupApi {
|
||||||
context: InstanceContext;
|
context: InstanceContext;
|
||||||
@ -49,12 +48,7 @@ export class NTQQGroupApi {
|
|||||||
|
|
||||||
async initApi() {
|
async initApi() {
|
||||||
this.initCache().then().catch(e => this.context.logger.logError(e));
|
this.initCache().then().catch(e => this.context.logger.logError(e));
|
||||||
let napcatNativeModule = { exports: {} };
|
|
||||||
dlopen(napcatNativeModule, "E:\\NewDevelop\\Napi2Native\\build\\Release\\napi2native.node");
|
|
||||||
console.log(await this.context.session.getMsgService().sendSsoCmdReqByContend('OidbSvcTrpcTcp.0xed3_1', '0aed030100000000000000000000000000000000000000000000000000000000'));
|
|
||||||
console.log(await this.context.session.getMsgService().sendSsoCmdReqByContend('OidbSvcTrpcTcp.0xed3_1', Buffer.from('0aed030100000000000000000000000000000000000000000000000000000000', 'hex')));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createGrayTip(groupCode: string, tip: string) {
|
async createGrayTip(groupCode: string, tip: string) {
|
||||||
return this.context.session.getMsgService().addLocalJsonGrayTipMsg(
|
return this.context.session.getMsgService().addLocalJsonGrayTipMsg(
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import offset from '@/core/external/offset.json';
|
import offset from '@/core/external/napi2native.json';
|
||||||
import { InstanceContext, NapCatCore } from '@/core';
|
import { InstanceContext, NapCatCore } from '@/core';
|
||||||
import { LogWrapper } from '@/common/log';
|
import { LogWrapper } from '@/common/log';
|
||||||
import { PacketClientSession } from '@/core/packet/clientSession';
|
import { PacketClientSession } from '@/core/packet/clientSession';
|
||||||
|
|||||||
2
src/core/external/appid.json
vendored
2
src/core/external/appid.json
vendored
@ -419,7 +419,7 @@
|
|||||||
"appid": 537319880,
|
"appid": 537319880,
|
||||||
"qua": "V1_MAC_NQ_6.9.82_40990_GW_B"
|
"qua": "V1_MAC_NQ_6.9.82_40990_GW_B"
|
||||||
},
|
},
|
||||||
"9.9.22.40990": {
|
"9.9.22-40990": {
|
||||||
"appid": 537319855,
|
"appid": 537319855,
|
||||||
"qua": "V1_WIN_NQ_9.9.22.40990_GW_B"
|
"qua": "V1_WIN_NQ_9.9.22.40990_GW_B"
|
||||||
},
|
},
|
||||||
|
|||||||
6
src/core/external/napi2native.json
vendored
Normal file
6
src/core/external/napi2native.json
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"9.9.22-40990-x64": {
|
||||||
|
"send": "1B5699C",
|
||||||
|
"recv": "1D8CA9D"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
import crypto, { createHash } from 'crypto';
|
|
||||||
import { OidbPacket, PacketHexStr } from '@/core/packet/transformer/base';
|
import { OidbPacket, PacketHexStr } from '@/core/packet/transformer/base';
|
||||||
import { LogStack } from '@/core/packet/context/clientContext';
|
import { LogStack } from '@/core/packet/context/clientContext';
|
||||||
import { NapCoreContext } from '@/core/packet/context/napCoreContext';
|
import { NapCoreContext } from '@/core/packet/context/napCoreContext';
|
||||||
import { PacketLogger } from '@/core/packet/context/loggerContext';
|
import { PacketLogger } from '@/core/packet/context/loggerContext';
|
||||||
|
import { CancelableTask } from '@/common/cancel-task';
|
||||||
|
|
||||||
export interface RecvPacket {
|
export interface RecvPacket {
|
||||||
type: string, // 仅recv
|
type: string, // 仅recv
|
||||||
@ -12,16 +12,7 @@ export interface RecvPacket {
|
|||||||
export interface RecvPacketData {
|
export interface RecvPacketData {
|
||||||
seq: number
|
seq: number
|
||||||
cmd: string
|
cmd: string
|
||||||
hex_data: string
|
data: Buffer
|
||||||
}
|
|
||||||
|
|
||||||
function randText(len: number): string {
|
|
||||||
let text = '';
|
|
||||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -42,47 +33,43 @@ export abstract class IPacketClient {
|
|||||||
|
|
||||||
abstract init(pid: number, recv: string, send: string): Promise<void>;
|
abstract init(pid: number, recv: string, send: string): Promise<void>;
|
||||||
|
|
||||||
abstract sendCommandImpl(cmd: string, data: string, hash: string, timeout: number): void;
|
async sendPacket(cmd: string, data: PacketHexStr, rsp = false, timeout = 5000): Promise<RecvPacketData> {
|
||||||
|
if (!rsp) {
|
||||||
|
this.napcore.sendSsoCmdReqByContend(cmd, Buffer.from(data, 'hex')).catch(err => {
|
||||||
|
this.logger.error(`[PacketClient] sendPacket 无响应命令发送失败 cmd=${cmd} err=${err}`);
|
||||||
|
});
|
||||||
|
return { seq: 0, cmd: cmd, data: Buffer.alloc(0) };
|
||||||
|
}
|
||||||
|
|
||||||
private async sendCommand(cmd: string, data: string, trace_data: string, rsp: boolean = false, timeout: number = 20000, sendcb: (json: RecvPacketData) => void = () => {
|
const task = new CancelableTask<RecvPacketData>((resolve, reject, onCancel) => {
|
||||||
}): Promise<RecvPacketData> {
|
const timeoutId = setTimeout(() => {
|
||||||
return new Promise<RecvPacketData>((resolve, reject) => {
|
reject(new Error(`[PacketClient] sendPacket 超时 cmd=${cmd} timeout=${timeout}ms`));
|
||||||
if (!this.available) {
|
|
||||||
reject(new Error('packetBackend 当前不可用!'));
|
|
||||||
}
|
|
||||||
let hash = createHash('md5').update(trace_data).digest('hex');
|
|
||||||
const timeoutHandle = setTimeout(() => {
|
|
||||||
this.cb.delete(hash + 'send');
|
|
||||||
this.cb.delete(hash + 'recv');
|
|
||||||
reject(new Error(`sendCommand timed out after ${timeout} ms for ${cmd} with hash ${hash}`));
|
|
||||||
}, timeout);
|
}, timeout);
|
||||||
this.cb.set(hash + 'send', async (json: RecvPacketData) => {
|
|
||||||
sendcb(json);
|
onCancel(() => {
|
||||||
if (!rsp) {
|
clearTimeout(timeoutId);
|
||||||
clearTimeout(timeoutHandle);
|
|
||||||
resolve(json);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (rsp) {
|
this.napcore.sendSsoCmdReqByContend(cmd, Buffer.from(data, 'hex'))
|
||||||
this.cb.set(hash + 'recv', async (json: RecvPacketData) => {
|
.then(ret => {
|
||||||
clearTimeout(timeoutHandle);
|
clearTimeout(timeoutId);
|
||||||
resolve(json);
|
const result = ret as { rspbuffer: Buffer };
|
||||||
|
resolve({
|
||||||
|
seq: 0,
|
||||||
|
cmd: cmd,
|
||||||
|
data: result.rspbuffer
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
reject(err);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
this.sendCommandImpl(cmd, data, hash, timeout);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return await task;
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendPacket(cmd: string, data: PacketHexStr, rsp = false, timeout = 20000): Promise<RecvPacketData> {
|
async sendOidbPacket(pkt: OidbPacket, rsp = false, timeout = 5000): Promise<RecvPacketData> {
|
||||||
const md5 = crypto.createHash('md5').update(data).digest('hex');
|
return await this.sendPacket(pkt.cmd, pkt.data, rsp, timeout);
|
||||||
const trace_data = (randText(4) + md5 + data).slice(0, data.length / 2);// trace_data
|
|
||||||
return this.sendCommand(cmd, data, trace_data, rsp, timeout, async () => {
|
|
||||||
await this.napcore.sendSsoCmdReqByContend(cmd, trace_data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async sendOidbPacket(pkt: OidbPacket, rsp = false, timeout = 20000): Promise<RecvPacketData> {
|
|
||||||
return this.sendPacket(pkt.cmd, pkt.data, rsp, timeout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { createHash } from 'crypto';
|
|
||||||
import path, { dirname } from 'path';
|
import path, { dirname } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
@ -10,16 +9,12 @@ import { PacketLogger } from '@/core/packet/context/loggerContext';
|
|||||||
|
|
||||||
// 0 send 1 recv
|
// 0 send 1 recv
|
||||||
export interface NativePacketExportType {
|
export interface NativePacketExportType {
|
||||||
InitHook?: (send: string, recv: string, callback: (type: number, uin: string, cmd: string, seq: number, hex_data: string) => void, o3_hook: boolean) => boolean;
|
initHook?: (send: string, recv: string) => boolean;
|
||||||
SendPacket?: (cmd: string, data: string, trace_id: string) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NativePacketClient extends IPacketClient {
|
export class NativePacketClient extends IPacketClient {
|
||||||
private readonly supportedPlatforms = ['win32.x64', 'linux.x64', 'linux.arm64', 'darwin.x64', 'darwin.arm64'];
|
private readonly supportedPlatforms = ['win32.x64', 'linux.x64', 'linux.arm64', 'darwin.x64', 'darwin.arm64'];
|
||||||
private readonly MoeHooExport: { exports: NativePacketExportType } = { exports: {} };
|
private readonly MoeHooExport: { exports: NativePacketExportType } = { exports: {} };
|
||||||
private readonly sendEvent = new Map<number, string>(); // seq - hash
|
|
||||||
private readonly timeEvent = new Map<string, NodeJS.Timeout>(); // hash - timeout
|
|
||||||
|
|
||||||
constructor(napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) {
|
constructor(napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) {
|
||||||
super(napCore, logger, logStack);
|
super(napCore, logger, logStack);
|
||||||
}
|
}
|
||||||
@ -30,7 +25,7 @@ export class NativePacketClient extends IPacketClient {
|
|||||||
this.logStack.pushLogWarn(`NativePacketClient: 不支持的平台: ${platform}`);
|
this.logStack.pushLogWarn(`NativePacketClient: 不支持的平台: ${platform}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const moehoo_path = path.join(dirname(fileURLToPath(import.meta.url)), './moehoo/MoeHoo.' + platform + '.node');
|
const moehoo_path = path.join(dirname(fileURLToPath(import.meta.url)), './moehoo/napi2native.' + platform + '.node');
|
||||||
if (!fs.existsSync(moehoo_path)) {
|
if (!fs.existsSync(moehoo_path)) {
|
||||||
this.logStack.pushLogWarn(`NativePacketClient: 缺失运行时文件: ${moehoo_path}`);
|
this.logStack.pushLogWarn(`NativePacketClient: 缺失运行时文件: ${moehoo_path}`);
|
||||||
return false;
|
return false;
|
||||||
@ -40,37 +35,12 @@ export class NativePacketClient extends IPacketClient {
|
|||||||
|
|
||||||
async init(_pid: number, recv: string, send: string): Promise<void> {
|
async init(_pid: number, recv: string, send: string): Promise<void> {
|
||||||
const platform = process.platform + '.' + process.arch;
|
const platform = process.platform + '.' + process.arch;
|
||||||
const isNewQQ = this.napcore.basicInfo.requireMinNTQQBuild("36580");
|
const isNewQQ = this.napcore.basicInfo.requireMinNTQQBuild("40824");
|
||||||
const moehoo_path = path.join(dirname(fileURLToPath(import.meta.url)), './moehoo/MoeHoo.' + platform + (isNewQQ ? '.new' : '') + '.node');
|
if (isNewQQ) {
|
||||||
process.dlopen(this.MoeHooExport, moehoo_path, constants.dlopen.RTLD_LAZY);
|
const moehoo_path = path.join(dirname(fileURLToPath(import.meta.url)), './moehoo/napi2native.' + platform + '.node');
|
||||||
|
process.dlopen(this.MoeHooExport, moehoo_path, constants.dlopen.RTLD_LAZY);
|
||||||
this.MoeHooExport.exports.InitHook?.(send, recv, (type: number, _uin: string, cmd: string, seq: number, hex_data: string) => {
|
this.MoeHooExport?.exports.initHook?.(send, recv);
|
||||||
const hash = createHash('md5').update(Buffer.from(hex_data, 'hex')).digest('hex');
|
this.available = true;
|
||||||
if (type === 0 && this.cb.get(hash + 'recv')) {
|
}
|
||||||
//此时为send 提取seq
|
|
||||||
this.sendEvent.set(seq, hash);
|
|
||||||
setTimeout(() => {
|
|
||||||
this.sendEvent.delete(seq);
|
|
||||||
this.timeEvent.delete(hash);
|
|
||||||
}, +(this.timeEvent.get(hash) ?? 20000));
|
|
||||||
//正式send完成 无recv v
|
|
||||||
//均无异常 v
|
|
||||||
}
|
|
||||||
if (type === 1 && this.sendEvent.get(seq)) {
|
|
||||||
const hash = this.sendEvent.get(seq);
|
|
||||||
const callback = this.cb.get(hash + 'recv');
|
|
||||||
callback?.({ seq, cmd, hex_data });
|
|
||||||
}
|
|
||||||
this.logger.info(`[NativePacketClient] ${type === 0 ? 'Send' : 'Recv'} - CMD: ${cmd} SEQ: ${seq} DATA: ${hex_data}`);//TODO log
|
|
||||||
}, this.napcore.config.o3HookMode == 1);
|
|
||||||
this.available = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendCommandImpl(cmd: string, data: string, hash: string, timeout: number): void {
|
|
||||||
this.timeEvent.set(hash, setTimeout(() => {
|
|
||||||
this.timeEvent.delete(hash);//考虑情况为正式send都没进
|
|
||||||
}, timeout));
|
|
||||||
this.MoeHooExport.exports.SendPacket?.(cmd, data, hash);
|
|
||||||
this.cb.get(hash + 'send')?.({ seq: 0, cmd, hex_data: '' });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,24 +75,24 @@ export class PacketClientContext {
|
|||||||
|
|
||||||
async sendOidbPacket<T extends boolean = false>(pkt: OidbPacket, rsp?: T, timeout?: number): Promise<T extends true ? Buffer : void> {
|
async sendOidbPacket<T extends boolean = false>(pkt: OidbPacket, rsp?: T, timeout?: number): Promise<T extends true ? Buffer : void> {
|
||||||
const raw = await this._client.sendOidbPacket(pkt, rsp, timeout);
|
const raw = await this._client.sendOidbPacket(pkt, rsp, timeout);
|
||||||
return (rsp ? Buffer.from(raw.hex_data, 'hex') : undefined) as T extends true ? Buffer : void;
|
return raw.data as T extends true ? Buffer : void;
|
||||||
}
|
}
|
||||||
|
|
||||||
private newClient(): IPacketClient {
|
private newClient(): IPacketClient {
|
||||||
const prefer = this.napCore.config.packetBackend;
|
const prefer = this.napCore.config.packetBackend;
|
||||||
let client: IPacketClient | null;
|
let client: IPacketClient | null;
|
||||||
switch (prefer) {
|
switch (prefer) {
|
||||||
case 'native':
|
case 'native':
|
||||||
this.logger.info('使用指定的 NativePacketClient 作为后端');
|
this.logger.info('使用指定的 NativePacketClient 作为后端');
|
||||||
client = new NativePacketClient(this.napCore, this.logger, this.logStack);
|
client = new NativePacketClient(this.napCore, this.logger, this.logStack);
|
||||||
break;
|
break;
|
||||||
case 'auto':
|
case 'auto':
|
||||||
case undefined:
|
case undefined:
|
||||||
client = this.judgeClient();
|
client = this.judgeClient();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.logger.error(`未知的PacketBackend ${prefer},请检查配置文件!`);
|
this.logger.error(`未知的PacketBackend ${prefer},请检查配置文件!`);
|
||||||
client = null;
|
client = null;
|
||||||
}
|
}
|
||||||
if (!client?.check()) {
|
if (!client?.check()) {
|
||||||
throw new Error('[Core] [Packet] 无可用的后端,NapCat.Packet将不会加载!');
|
throw new Error('[Core] [Packet] 无可用的后端,NapCat.Packet将不会加载!');
|
||||||
|
|||||||
@ -34,5 +34,5 @@ export class NapCoreContext {
|
|||||||
return this.core.configLoader.configData;
|
return this.core.configLoader.configData;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendSsoCmdReqByContend = (cmd: string, trace_id: string) => this.core.context.session.getMsgService().sendSsoCmdReqByContend(cmd, trace_id);
|
sendSsoCmdReqByContend = (cmd: string, data: Buffer) => this.core.context.session.getMsgService().sendSsoCmdReqByContend(cmd, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -122,28 +122,28 @@ export class PacketOperationContext {
|
|||||||
return `https://${res.download.info.domain}${res.download.info.urlPath}${res.download.rKeyParam}`;
|
return `https://${res.download.info.domain}${res.download.info.urlPath}${res.download.rKeyParam}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetPttUrl(selfUid: string, node: NapProtoEncodeStructType<typeof IndexNode>,timeout: number = 20000) {
|
async GetPttUrl(selfUid: string, node: NapProtoEncodeStructType<typeof IndexNode>, timeout?: number) {
|
||||||
const req = trans.DownloadPtt.build(selfUid, node);
|
const req = trans.DownloadPtt.build(selfUid, node);
|
||||||
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
||||||
const res = trans.DownloadPtt.parse(resp);
|
const res = trans.DownloadPtt.parse(resp);
|
||||||
return `https://${res.download.info.domain}${res.download.info.urlPath}${res.download.rKeyParam}`;
|
return `https://${res.download.info.domain}${res.download.info.urlPath}${res.download.rKeyParam}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetVideoUrl(selfUid: string, node: NapProtoEncodeStructType<typeof IndexNode>, timeout: number = 20000) {
|
async GetVideoUrl(selfUid: string, node: NapProtoEncodeStructType<typeof IndexNode>, timeout?: number) {
|
||||||
const req = trans.DownloadVideo.build(selfUid, node);
|
const req = trans.DownloadVideo.build(selfUid, node);
|
||||||
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
||||||
const res = trans.DownloadVideo.parse(resp);
|
const res = trans.DownloadVideo.parse(resp);
|
||||||
return `https://${res.download.info.domain}${res.download.info.urlPath}${res.download.rKeyParam}`;
|
return `https://${res.download.info.domain}${res.download.info.urlPath}${res.download.rKeyParam}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetGroupImageUrl(groupUin: number, node: NapProtoEncodeStructType<typeof IndexNode>, timeout: number = 20000) {
|
async GetGroupImageUrl(groupUin: number, node: NapProtoEncodeStructType<typeof IndexNode>, timeout?: number) {
|
||||||
const req = trans.DownloadGroupImage.build(groupUin, node);
|
const req = trans.DownloadGroupImage.build(groupUin, node);
|
||||||
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
||||||
const res = trans.DownloadImage.parse(resp);
|
const res = trans.DownloadImage.parse(resp);
|
||||||
return `https://${res.download.info.domain}${res.download.info.urlPath}${res.download.rKeyParam}`;
|
return `https://${res.download.info.domain}${res.download.info.urlPath}${res.download.rKeyParam}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetGroupPttUrl(groupUin: number, node: NapProtoEncodeStructType<typeof IndexNode>, timeout: number = 20000) {
|
async GetGroupPttUrl(groupUin: number, node: NapProtoEncodeStructType<typeof IndexNode>, timeout?: number) {
|
||||||
const req = trans.DownloadGroupPtt.build(groupUin, node);
|
const req = trans.DownloadGroupPtt.build(groupUin, node);
|
||||||
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
||||||
const res = trans.DownloadImage.parse(resp);
|
const res = trans.DownloadImage.parse(resp);
|
||||||
@ -243,14 +243,14 @@ export class PacketOperationContext {
|
|||||||
return res.rename.retCode;
|
return res.rename.retCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetGroupFileUrl(groupUin: number, fileUUID: string,timeout: number = 20000) {
|
async GetGroupFileUrl(groupUin: number, fileUUID: string, timeout?: number) {
|
||||||
const req = trans.DownloadGroupFile.build(groupUin, fileUUID);
|
const req = trans.DownloadGroupFile.build(groupUin, fileUUID);
|
||||||
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
||||||
const res = trans.DownloadGroupFile.parse(resp);
|
const res = trans.DownloadGroupFile.parse(resp);
|
||||||
return `https://${res.download.downloadDns}/ftn_handler/${Buffer.from(res.download.downloadUrl).toString('hex')}/?fname=`;
|
return `https://${res.download.downloadDns}/ftn_handler/${Buffer.from(res.download.downloadUrl).toString('hex')}/?fname=`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async GetPrivateFileUrl(self_id: string, fileUUID: string, md5: string, timeout: number = 20000) {
|
async GetPrivateFileUrl(self_id: string, fileUUID: string, md5: string, timeout?: number) {
|
||||||
const req = trans.DownloadPrivateFile.build(self_id, fileUUID, md5);
|
const req = trans.DownloadPrivateFile.build(self_id, fileUUID, md5);
|
||||||
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
const resp = await this.context.client.sendOidbPacket(req, true, timeout);
|
||||||
const res = trans.DownloadPrivateFile.parse(resp);
|
const res = trans.DownloadPrivateFile.parse(resp);
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/native/packet/napi2native.win32.x64.node
Normal file
BIN
src/native/packet/napi2native.win32.x64.node
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user