mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
refactor: simplify oidb packet pack & send
This commit is contained in:
@@ -3,7 +3,7 @@ import { ChatType, InstanceContext, NapCatCore } from '..';
|
|||||||
import offset from '@/core/external/offset.json';
|
import offset from '@/core/external/offset.json';
|
||||||
import { PacketClient, RecvPacketData } from '@/core/packet/client';
|
import { PacketClient, RecvPacketData } from '@/core/packet/client';
|
||||||
import { PacketSession } from "@/core/packet/session";
|
import { PacketSession } from "@/core/packet/session";
|
||||||
import { PacketHexStr } from "@/core/packet/packer";
|
import {OidbPacket, PacketHexStr} from "@/core/packet/packer";
|
||||||
import { NapProtoMsg } from '@/core/packet/proto/NapProto';
|
import { NapProtoMsg } from '@/core/packet/proto/NapProto';
|
||||||
import { OidbSvcTrpcTcp0X9067_202_Rsp_Body } from '@/core/packet/proto/oidb/Oidb.0x9067_202';
|
import { OidbSvcTrpcTcp0X9067_202_Rsp_Body } from '@/core/packet/proto/oidb/Oidb.0x9067_202';
|
||||||
import { OidbSvcTrpcTcpBase, OidbSvcTrpcTcpBaseRsp } from '@/core/packet/proto/oidb/OidbBase';
|
import { OidbSvcTrpcTcpBase, OidbSvcTrpcTcpBaseRsp } from '@/core/packet/proto/oidb/OidbBase';
|
||||||
@@ -78,14 +78,18 @@ export class NTQQPacketApi {
|
|||||||
return this.packetSession!.client.sendPacket(cmd, data, rsp);
|
return this.packetSession!.client.sendPacket(cmd, data, rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendOidbPacket(pkt: OidbPacket, rsp = false): Promise<RecvPacketData> {
|
||||||
|
return this.sendPacket(pkt.cmd, pkt.data, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
async sendPokePacket(peer: number, group?: number) {
|
async sendPokePacket(peer: number, group?: number) {
|
||||||
const data = this.packetSession?.packer.packPokePacket(peer, group);
|
const data = this.packetSession?.packer.packPokePacket(peer, group);
|
||||||
await this.sendPacket('OidbSvcTrpcTcp.0xed3_1', data!, false);
|
await this.sendOidbPacket(data!, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendRkeyPacket() {
|
async sendRkeyPacket() {
|
||||||
const packet = this.packetSession?.packer.packRkeyPacket();
|
const packet = this.packetSession?.packer.packRkeyPacket();
|
||||||
const ret = await this.sendPacket('OidbSvcTrpcTcp.0x9067_202', packet!, true);
|
const ret = await this.sendOidbPacket(packet!, true);
|
||||||
if (!ret?.hex_data) return [];
|
if (!ret?.hex_data) return [];
|
||||||
const body = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(ret.hex_data, 'hex')).body;
|
const body = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(ret.hex_data, 'hex')).body;
|
||||||
const retData = new NapProtoMsg(OidbSvcTrpcTcp0X9067_202_Rsp_Body).decode(body);
|
const retData = new NapProtoMsg(OidbSvcTrpcTcp0X9067_202_Rsp_Body).decode(body);
|
||||||
@@ -93,13 +97,13 @@ export class NTQQPacketApi {
|
|||||||
}
|
}
|
||||||
async sendGroupSignPacket(groupCode: string) {
|
async sendGroupSignPacket(groupCode: string) {
|
||||||
const packet = this.packetSession?.packer.packGroupSignReq(this.core.selfInfo.uin, groupCode);
|
const packet = this.packetSession?.packer.packGroupSignReq(this.core.selfInfo.uin, groupCode);
|
||||||
await this.sendPacket('OidbSvcTrpcTcp.0xeb7', packet!, true);
|
await this.sendOidbPacket(packet!, true);
|
||||||
}
|
}
|
||||||
async sendStatusPacket(uin: number): Promise<{ status: number; ext_status: number; } | undefined> {
|
async sendStatusPacket(uin: number): Promise<{ status: number; ext_status: number; } | undefined> {
|
||||||
let status = 0;
|
let status = 0;
|
||||||
try {
|
try {
|
||||||
const packet = this.packetSession?.packer.packStatusPacket(uin);
|
const packet = this.packetSession?.packer.packStatusPacket(uin);
|
||||||
const ret = await this.sendPacket('OidbSvcTrpcTcp.0xfe1_2', packet!, true);
|
const ret = await this.sendOidbPacket( packet!, true);
|
||||||
const data = Buffer.from(ret.hex_data, 'hex');
|
const data = Buffer.from(ret.hex_data, 'hex');
|
||||||
const ext = new NapProtoMsg(OidbSvcTrpcTcp0XFE1_2RSP).decode(new NapProtoMsg(OidbSvcTrpcTcpBase).decode(data).body).data.status.value;
|
const ext = new NapProtoMsg(OidbSvcTrpcTcp0XFE1_2RSP).decode(new NapProtoMsg(OidbSvcTrpcTcpBase).decode(data).body).data.status.value;
|
||||||
// ext & 0xff00 + ext >> 16 & 0xff
|
// ext & 0xff00 + ext >> 16 & 0xff
|
||||||
@@ -116,7 +120,7 @@ export class NTQQPacketApi {
|
|||||||
|
|
||||||
async sendSetSpecialTittlePacket(groupCode: string, uid: string, tittle: string) {
|
async sendSetSpecialTittlePacket(groupCode: string, uid: string, tittle: string) {
|
||||||
const data = this.packetSession?.packer.packSetSpecialTittlePacket(groupCode, uid, tittle);
|
const data = this.packetSession?.packer.packSetSpecialTittlePacket(groupCode, uid, tittle);
|
||||||
await this.sendPacket('OidbSvcTrpcTcp.0x8fc_2', data!, true);
|
await this.sendOidbPacket(data!, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: can simplify this
|
// TODO: can simplify this
|
||||||
@@ -164,7 +168,7 @@ export class NTQQPacketApi {
|
|||||||
|
|
||||||
async sendGroupFileDownloadReq(groupUin: number, fileUUID: string) {
|
async sendGroupFileDownloadReq(groupUin: number, fileUUID: string) {
|
||||||
const data = this.packetSession?.packer.packGroupFileDownloadReq(groupUin, fileUUID);
|
const data = this.packetSession?.packer.packGroupFileDownloadReq(groupUin, fileUUID);
|
||||||
const ret = await this.sendPacket('OidbSvcTrpcTcp.0x6d6_2', data!, true);
|
const ret = await this.sendOidbPacket(data!, true);
|
||||||
const body = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(ret.hex_data, 'hex')).body;
|
const body = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(ret.hex_data, 'hex')).body;
|
||||||
const resp = new NapProtoMsg(OidbSvcTrpcTcp0x6D6Response).decode(body);
|
const resp = new NapProtoMsg(OidbSvcTrpcTcp0x6D6Response).decode(body);
|
||||||
if (resp.download.retCode !== 0) {
|
if (resp.download.retCode !== 0) {
|
||||||
|
@@ -3,8 +3,7 @@ import { LRUCache } from "@/common/lru-cache";
|
|||||||
import WebSocket, { Data } from "ws";
|
import WebSocket, { Data } from "ws";
|
||||||
import crypto, { createHash } from "crypto";
|
import crypto, { createHash } from "crypto";
|
||||||
import { NapCatCore } from "@/core";
|
import { NapCatCore } from "@/core";
|
||||||
import { PacketHexStr } from "@/core/packet/packer";
|
import { OidbPacket, PacketHexStr } from "@/core/packet/packer";
|
||||||
import { sleep } from "@/common/helper";
|
|
||||||
|
|
||||||
export interface RecvPacket {
|
export interface RecvPacket {
|
||||||
type: string, // 仅recv
|
type: string, // 仅recv
|
||||||
@@ -177,4 +176,8 @@ export class PacketClient {
|
|||||||
}).then((res) => resolve(res)).catch((e: Error) => reject(e));
|
}).then((res) => resolve(res)).catch((e: Error) => reject(e));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendOidbPacket(pkt: OidbPacket, rsp = false): Promise<RecvPacketData> {
|
||||||
|
return this.sendPacket(pkt.cmd, pkt.data, rsp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -139,7 +139,7 @@ export class PacketHighwaySession {
|
|||||||
private async uploadGroupImageReq(groupUin: number, img: PacketMsgPicElement): Promise<void> {
|
private async uploadGroupImageReq(groupUin: number, img: PacketMsgPicElement): Promise<void> {
|
||||||
img.sha1 = Buffer.from(await calculateSha1(img.path)).toString('hex');
|
img.sha1 = Buffer.from(await calculateSha1(img.path)).toString('hex');
|
||||||
const preReq = await this.packer.packUploadGroupImgReq(groupUin, img);
|
const preReq = await this.packer.packUploadGroupImgReq(groupUin, img);
|
||||||
const preRespRaw = await this.packetClient.sendPacket('OidbSvcTrpcTcp.0x11c4_100', preReq, true);
|
const preRespRaw = await this.packetClient.sendOidbPacket(preReq, true);
|
||||||
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
||||||
Buffer.from(preRespRaw.hex_data, 'hex')
|
Buffer.from(preRespRaw.hex_data, 'hex')
|
||||||
);
|
);
|
||||||
@@ -179,7 +179,7 @@ export class PacketHighwaySession {
|
|||||||
private async uploadC2CImageReq(peerUid: string, img: PacketMsgPicElement): Promise<void> {
|
private async uploadC2CImageReq(peerUid: string, img: PacketMsgPicElement): Promise<void> {
|
||||||
img.sha1 = Buffer.from(await calculateSha1(img.path)).toString('hex');
|
img.sha1 = Buffer.from(await calculateSha1(img.path)).toString('hex');
|
||||||
const preReq = await this.packer.packUploadC2CImgReq(peerUid, img);
|
const preReq = await this.packer.packUploadC2CImgReq(peerUid, img);
|
||||||
const preRespRaw = await this.packetClient.sendPacket('OidbSvcTrpcTcp.0x11c5_100', preReq, true);
|
const preRespRaw = await this.packetClient.sendOidbPacket(preReq, true);
|
||||||
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
||||||
Buffer.from(preRespRaw.hex_data, 'hex')
|
Buffer.from(preRespRaw.hex_data, 'hex')
|
||||||
);
|
);
|
||||||
@@ -220,7 +220,7 @@ export class PacketHighwaySession {
|
|||||||
video.fileSha1 = Buffer.from(await calculateSha1(video.filePath)).toString('hex');
|
video.fileSha1 = Buffer.from(await calculateSha1(video.filePath)).toString('hex');
|
||||||
video.thumbSha1 = Buffer.from(await calculateSha1(video.thumbPath)).toString('hex');
|
video.thumbSha1 = Buffer.from(await calculateSha1(video.thumbPath)).toString('hex');
|
||||||
const preReq = await this.packer.packUploadGroupVideoReq(groupUin, video);
|
const preReq = await this.packer.packUploadGroupVideoReq(groupUin, video);
|
||||||
const preRespRaw = await this.packetClient.sendPacket('OidbSvcTrpcTcp.0x11ea_100', preReq, true);
|
const preRespRaw = await this.packetClient.sendOidbPacket(preReq, true);
|
||||||
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
||||||
Buffer.from(preRespRaw.hex_data, 'hex')
|
Buffer.from(preRespRaw.hex_data, 'hex')
|
||||||
);
|
);
|
||||||
@@ -288,7 +288,7 @@ export class PacketHighwaySession {
|
|||||||
video.fileSha1 = Buffer.from(await calculateSha1(video.filePath)).toString('hex');
|
video.fileSha1 = Buffer.from(await calculateSha1(video.filePath)).toString('hex');
|
||||||
video.thumbSha1 = Buffer.from(await calculateSha1(video.thumbPath)).toString('hex');
|
video.thumbSha1 = Buffer.from(await calculateSha1(video.thumbPath)).toString('hex');
|
||||||
const preReq = await this.packer.packUploadC2CVideoReq(peerUid, video);
|
const preReq = await this.packer.packUploadC2CVideoReq(peerUid, video);
|
||||||
const preRespRaw = await this.packetClient.sendPacket('OidbSvcTrpcTcp.0x11e9_100', preReq, true);
|
const preRespRaw = await this.packetClient.sendOidbPacket(preReq, true);
|
||||||
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
||||||
Buffer.from(preRespRaw.hex_data, 'hex')
|
Buffer.from(preRespRaw.hex_data, 'hex')
|
||||||
);
|
);
|
||||||
@@ -354,7 +354,7 @@ export class PacketHighwaySession {
|
|||||||
private async uploadGroupPttReq(groupUin: number, ptt: PacketMsgPttElement): Promise<void> {
|
private async uploadGroupPttReq(groupUin: number, ptt: PacketMsgPttElement): Promise<void> {
|
||||||
ptt.fileSha1 = Buffer.from(await calculateSha1(ptt.filePath)).toString('hex');
|
ptt.fileSha1 = Buffer.from(await calculateSha1(ptt.filePath)).toString('hex');
|
||||||
const preReq = await this.packer.packUploadGroupPttReq(groupUin, ptt);
|
const preReq = await this.packer.packUploadGroupPttReq(groupUin, ptt);
|
||||||
const preRespRaw = await this.packetClient.sendPacket('OidbSvcTrpcTcp.0x126e_100', preReq, true);
|
const preRespRaw = await this.packetClient.sendOidbPacket(preReq, true);
|
||||||
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
||||||
Buffer.from(preRespRaw.hex_data, 'hex')
|
Buffer.from(preRespRaw.hex_data, 'hex')
|
||||||
);
|
);
|
||||||
@@ -393,7 +393,7 @@ export class PacketHighwaySession {
|
|||||||
private async uploadC2CPttReq(peerUid: string, ptt: PacketMsgPttElement): Promise<void> {
|
private async uploadC2CPttReq(peerUid: string, ptt: PacketMsgPttElement): Promise<void> {
|
||||||
ptt.fileSha1 = Buffer.from(await calculateSha1(ptt.filePath)).toString('hex');
|
ptt.fileSha1 = Buffer.from(await calculateSha1(ptt.filePath)).toString('hex');
|
||||||
const preReq = await this.packer.packUploadC2CPttReq(peerUid, ptt);
|
const preReq = await this.packer.packUploadC2CPttReq(peerUid, ptt);
|
||||||
const preRespRaw = await this.packetClient.sendPacket('OidbSvcTrpcTcp.0x126d_100', preReq, true);
|
const preRespRaw = await this.packetClient.sendOidbPacket(preReq, true);
|
||||||
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
||||||
Buffer.from(preRespRaw.hex_data, 'hex')
|
Buffer.from(preRespRaw.hex_data, 'hex')
|
||||||
);
|
);
|
||||||
@@ -434,7 +434,7 @@ export class PacketHighwaySession {
|
|||||||
file.fileMd5 = await computeMd5AndLengthWithLimit(file.filePath);
|
file.fileMd5 = await computeMd5AndLengthWithLimit(file.filePath);
|
||||||
file.fileSha1 = await calculateSha1(file.filePath);
|
file.fileSha1 = await calculateSha1(file.filePath);
|
||||||
const preReq = await this.packer.packUploadGroupFileReq(groupUin, file);
|
const preReq = await this.packer.packUploadGroupFileReq(groupUin, file);
|
||||||
const preRespRaw = await this.packetClient.sendPacket('OidbSvcTrpcTcp.0x6d6_0', preReq, true);
|
const preRespRaw = await this.packetClient.sendOidbPacket(preReq, true);
|
||||||
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
||||||
Buffer.from(preRespRaw.hex_data, 'hex')
|
Buffer.from(preRespRaw.hex_data, 'hex')
|
||||||
);
|
);
|
||||||
@@ -500,7 +500,7 @@ export class PacketHighwaySession {
|
|||||||
file.fileMd5 = await computeMd5AndLengthWithLimit(file.filePath);
|
file.fileMd5 = await computeMd5AndLengthWithLimit(file.filePath);
|
||||||
file.fileSha1 = await calculateSha1(file.filePath);
|
file.fileSha1 = await calculateSha1(file.filePath);
|
||||||
const preReq = await this.packer.packUploadC2CFileReq(this.sig.uid, peerUid, file);
|
const preReq = await this.packer.packUploadC2CFileReq(this.sig.uid, peerUid, file);
|
||||||
const preRespRaw = await this.packetClient.sendPacket('OidbSvcTrpcTcp.0xe37_1700', preReq, true);
|
const preRespRaw = await this.packetClient.sendOidbPacket( preReq, true);
|
||||||
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
const preResp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(
|
||||||
Buffer.from(preRespRaw.hex_data, 'hex')
|
Buffer.from(preRespRaw.hex_data, 'hex')
|
||||||
);
|
);
|
||||||
@@ -558,7 +558,7 @@ export class PacketHighwaySession {
|
|||||||
file.fileUuid = preRespData.upload?.uuid;
|
file.fileUuid = preRespData.upload?.uuid;
|
||||||
file.fileHash = preRespData.upload?.fileAddon;
|
file.fileHash = preRespData.upload?.fileAddon;
|
||||||
const FetchExistFileReq = this.packer.packOfflineFileDownloadReq(file.fileUuid!, file.fileHash!, this.sig.uid, peerUid);
|
const FetchExistFileReq = this.packer.packOfflineFileDownloadReq(file.fileUuid!, file.fileHash!, this.sig.uid, peerUid);
|
||||||
const resp = await this.packetClient.sendPacket('OidbSvcTrpcTcp.0xe37_800', FetchExistFileReq, true);
|
const resp = await this.packetClient.sendOidbPacket(FetchExistFileReq, true);
|
||||||
const oidb_resp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(resp.hex_data, 'hex'));
|
const oidb_resp = new NapProtoMsg(OidbSvcTrpcTcpBaseRsp).decode(Buffer.from(resp.hex_data, 'hex'));
|
||||||
file._e37_800_rsp = new NapProtoMsg(OidbSvcTrpcTcp0XE37_800Response).decode(oidb_resp.body);
|
file._e37_800_rsp = new NapProtoMsg(OidbSvcTrpcTcp0XE37_800Response).decode(oidb_resp.body);
|
||||||
file._private_send_uid = this.sig.uid;
|
file._private_send_uid = this.sig.uid;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import * as zlib from "node:zlib";
|
import * as zlib from "node:zlib";
|
||||||
import * as crypto from "node:crypto";
|
import * as crypto from "node:crypto";
|
||||||
import { calculateSha1, computeMd5AndLengthWithLimit } from "@/core/packet/utils/crypto/hash";
|
import { computeMd5AndLengthWithLimit } from "@/core/packet/utils/crypto/hash";
|
||||||
import { NapProtoMsg } from "@/core/packet/proto/NapProto";
|
import { NapProtoMsg } from "@/core/packet/proto/NapProto";
|
||||||
import { OidbSvcTrpcTcpBase } from "@/core/packet/proto/oidb/OidbBase";
|
import { OidbSvcTrpcTcpBase } from "@/core/packet/proto/oidb/OidbBase";
|
||||||
import { OidbSvcTrpcTcp0X9067_202 } from "@/core/packet/proto/oidb/Oidb.0x9067_202";
|
import { OidbSvcTrpcTcp0X9067_202 } from "@/core/packet/proto/oidb/Oidb.0x9067_202";
|
||||||
@@ -29,6 +29,11 @@ import { OidbSvcTrpcTcp0XEB7 } from "./proto/oidb/Oidb.0xEB7";
|
|||||||
|
|
||||||
export type PacketHexStr = string & { readonly hexNya: unique symbol };
|
export type PacketHexStr = string & { readonly hexNya: unique symbol };
|
||||||
|
|
||||||
|
export interface OidbPacket {
|
||||||
|
cmd: string;
|
||||||
|
data: PacketHexStr
|
||||||
|
}
|
||||||
|
|
||||||
export class PacketPacker {
|
export class PacketPacker {
|
||||||
readonly logger: LogWrapper;
|
readonly logger: LogWrapper;
|
||||||
readonly client: PacketClient;
|
readonly client: PacketClient;
|
||||||
@@ -42,31 +47,34 @@ export class PacketPacker {
|
|||||||
this.packetConverter = new PacketMsgConverter(logger);
|
this.packetConverter = new PacketMsgConverter(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 一步到位多好ww
|
private packetPacket(byteArray: Uint8Array): PacketHexStr {
|
||||||
private toHexStr(byteArray: Uint8Array): PacketHexStr {
|
|
||||||
return Buffer.from(byteArray).toString('hex') as PacketHexStr;
|
return Buffer.from(byteArray).toString('hex') as PacketHexStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
packOidbPacket(cmd: number, subCmd: number, body: Uint8Array, isUid: boolean = true, isLafter: boolean = false): Uint8Array {
|
packOidbPacket(cmd: number, subCmd: number, body: Uint8Array, isUid: boolean = true, isLafter: boolean = false): OidbPacket {
|
||||||
return new NapProtoMsg(OidbSvcTrpcTcpBase).encode({
|
const data = new NapProtoMsg(OidbSvcTrpcTcpBase).encode({
|
||||||
command: cmd,
|
command: cmd,
|
||||||
subCommand: subCmd,
|
subCommand: subCmd,
|
||||||
body: body,
|
body: body,
|
||||||
isReserved: isUid ? 1 : 0
|
isReserved: isUid ? 1 : 0
|
||||||
});
|
});
|
||||||
|
return {
|
||||||
|
cmd: `OidbSvcTrpcTcp.0x${cmd.toString(16).toUpperCase()}_${subCmd}`,
|
||||||
|
data: this.packetPacket(data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packPokePacket(peer: number, group?: number): PacketHexStr {
|
packPokePacket(peer: number, group?: number): OidbPacket {
|
||||||
const oidb_0xed3 = new NapProtoMsg(OidbSvcTrpcTcp0XED3_1).encode({
|
const oidb_0xed3 = new NapProtoMsg(OidbSvcTrpcTcp0XED3_1).encode({
|
||||||
uin: peer,
|
uin: peer,
|
||||||
groupUin: group,
|
groupUin: group,
|
||||||
friendUin: group ?? peer,
|
friendUin: group ?? peer,
|
||||||
ext: 0
|
ext: 0
|
||||||
});
|
});
|
||||||
return this.toHexStr(this.packOidbPacket(0xed3, 1, oidb_0xed3));
|
return this.packOidbPacket(0xed3, 1, oidb_0xed3);
|
||||||
}
|
}
|
||||||
|
|
||||||
packRkeyPacket(): PacketHexStr {
|
packRkeyPacket(): OidbPacket {
|
||||||
const oidb_0x9067_202 = new NapProtoMsg(OidbSvcTrpcTcp0X9067_202).encode({
|
const oidb_0x9067_202 = new NapProtoMsg(OidbSvcTrpcTcp0X9067_202).encode({
|
||||||
reqHead: {
|
reqHead: {
|
||||||
common: {
|
common: {
|
||||||
@@ -86,10 +94,10 @@ export class PacketPacker {
|
|||||||
key: [10, 20, 2]
|
key: [10, 20, 2]
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return this.toHexStr(this.packOidbPacket(0x9067, 202, oidb_0x9067_202));
|
return this.packOidbPacket(0x9067, 202, oidb_0x9067_202);
|
||||||
}
|
}
|
||||||
|
|
||||||
packSetSpecialTittlePacket(groupCode: string, uid: string, tittle: string): PacketHexStr {
|
packSetSpecialTittlePacket(groupCode: string, uid: string, tittle: string): OidbPacket {
|
||||||
const oidb_0x8FC_2_body = new NapProtoMsg(OidbSvcTrpcTcp0X8FC_2_Body).encode({
|
const oidb_0x8FC_2_body = new NapProtoMsg(OidbSvcTrpcTcp0X8FC_2_Body).encode({
|
||||||
targetUid: uid,
|
targetUid: uid,
|
||||||
specialTitle: tittle,
|
specialTitle: tittle,
|
||||||
@@ -100,15 +108,15 @@ export class PacketPacker {
|
|||||||
groupUin: +groupCode,
|
groupUin: +groupCode,
|
||||||
body: oidb_0x8FC_2_body
|
body: oidb_0x8FC_2_body
|
||||||
});
|
});
|
||||||
return this.toHexStr(this.packOidbPacket(0x8FC, 2, oidb_0x8FC_2, false, false));
|
return this.packOidbPacket(0x8FC, 2, oidb_0x8FC_2, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
packStatusPacket(uin: number): PacketHexStr {
|
packStatusPacket(uin: number): OidbPacket {
|
||||||
const oidb_0xfe1_2 = new NapProtoMsg(OidbSvcTrpcTcp0XFE1_2).encode({
|
const oidb_0xfe1_2 = new NapProtoMsg(OidbSvcTrpcTcp0XFE1_2).encode({
|
||||||
uin: uin,
|
uin: uin,
|
||||||
key: [{key: 27372}]
|
key: [{key: 27372}]
|
||||||
});
|
});
|
||||||
return this.toHexStr(this.packOidbPacket(0xfe1, 2, oidb_0xfe1_2));
|
return this.packOidbPacket(0xfe1, 2, oidb_0xfe1_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
async packUploadForwardMsg(selfUid: string, msg: PacketMsg[], groupUin: number = 0): Promise<PacketHexStr> {
|
async packUploadForwardMsg(selfUid: string, msg: PacketMsg[], groupUin: number = 0): Promise<PacketHexStr> {
|
||||||
@@ -140,12 +148,12 @@ export class PacketPacker {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
// this.logger.logDebug("packUploadForwardMsg REQ!!!", req);
|
// this.logger.logDebug("packUploadForwardMsg REQ!!!", req);
|
||||||
return this.toHexStr(req);
|
return this.packetPacket(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
// highway part
|
// highway part
|
||||||
packHttp0x6ff_501(): PacketHexStr {
|
packHttp0x6ff_501(): PacketHexStr {
|
||||||
return this.toHexStr(new NapProtoMsg(HttpConn0x6ff_501).encode({
|
return this.packetPacket(new NapProtoMsg(HttpConn0x6ff_501).encode({
|
||||||
httpConn: {
|
httpConn: {
|
||||||
field1: 0,
|
field1: 0,
|
||||||
field2: 0,
|
field2: 0,
|
||||||
@@ -162,7 +170,7 @@ export class PacketPacker {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
async packUploadGroupImgReq(groupUin: number, img: PacketMsgPicElement): Promise<PacketHexStr> {
|
async packUploadGroupImgReq(groupUin: number, img: PacketMsgPicElement): Promise<OidbPacket> {
|
||||||
const req = new NapProtoMsg(NTV2RichMediaReq).encode(
|
const req = new NapProtoMsg(NTV2RichMediaReq).encode(
|
||||||
{
|
{
|
||||||
reqHead: {
|
reqHead: {
|
||||||
@@ -227,78 +235,78 @@ export class PacketPacker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return this.toHexStr(this.packOidbPacket(0x11c4, 100, req, true, false));
|
return this.packOidbPacket(0x11c4, 100, req, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async packUploadC2CImgReq(peerUin: string, img: PacketMsgPicElement): Promise<PacketHexStr> {
|
async packUploadC2CImgReq(peerUin: string, img: PacketMsgPicElement): Promise<OidbPacket> {
|
||||||
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
||||||
reqHead: {
|
reqHead: {
|
||||||
common: {
|
common: {
|
||||||
requestId: 1,
|
requestId: 1,
|
||||||
command: 100
|
command: 100
|
||||||
},
|
|
||||||
scene: {
|
|
||||||
requestType: 2,
|
|
||||||
businessType: 1,
|
|
||||||
sceneType: 1,
|
|
||||||
c2C: {
|
|
||||||
accountType: 2,
|
|
||||||
targetUid: peerUin
|
|
||||||
},
|
},
|
||||||
},
|
scene: {
|
||||||
client: {
|
requestType: 2,
|
||||||
agentType: 2,
|
businessType: 1,
|
||||||
}
|
sceneType: 1,
|
||||||
},
|
c2C: {
|
||||||
upload: {
|
accountType: 2,
|
||||||
uploadInfo: [
|
targetUid: peerUin
|
||||||
{
|
|
||||||
fileInfo: {
|
|
||||||
fileSize: +img.size,
|
|
||||||
fileHash: img.md5,
|
|
||||||
fileSha1: img.sha1!,
|
|
||||||
fileName: img.name,
|
|
||||||
type: {
|
|
||||||
type: 1,
|
|
||||||
picFormat: img.picType, //TODO: extend NapCat imgType /cc @MliKiowa
|
|
||||||
videoFormat: 0,
|
|
||||||
voiceFormat: 0,
|
|
||||||
},
|
|
||||||
width: img.width,
|
|
||||||
height: img.height,
|
|
||||||
time: 0,
|
|
||||||
original: 1
|
|
||||||
},
|
},
|
||||||
subFileType: 0,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
tryFastUploadCompleted: true,
|
|
||||||
srvSendMsg: false,
|
|
||||||
clientRandomId: crypto.randomBytes(8).readBigUInt64BE() & BigInt('0x7FFFFFFFFFFFFFFF'),
|
|
||||||
compatQMsgSceneType: 1,
|
|
||||||
extBizInfo: {
|
|
||||||
pic: {
|
|
||||||
bytesPbReserveTroop: Buffer.from("0800180020004200500062009201009a0100a2010c080012001800200028003a00", 'hex'),
|
|
||||||
textSummary: "Nya~", // TODO:
|
|
||||||
},
|
},
|
||||||
video: {
|
client: {
|
||||||
bytesPbReserve: Buffer.alloc(0),
|
agentType: 2,
|
||||||
},
|
|
||||||
ptt: {
|
|
||||||
bytesPbReserve: Buffer.alloc(0),
|
|
||||||
bytesReserve: Buffer.alloc(0),
|
|
||||||
bytesGeneralFlags: Buffer.alloc(0),
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clientSeq: 0,
|
upload: {
|
||||||
noNeedCompatMsg: false,
|
uploadInfo: [
|
||||||
|
{
|
||||||
|
fileInfo: {
|
||||||
|
fileSize: +img.size,
|
||||||
|
fileHash: img.md5,
|
||||||
|
fileSha1: img.sha1!,
|
||||||
|
fileName: img.name,
|
||||||
|
type: {
|
||||||
|
type: 1,
|
||||||
|
picFormat: img.picType, //TODO: extend NapCat imgType /cc @MliKiowa
|
||||||
|
videoFormat: 0,
|
||||||
|
voiceFormat: 0,
|
||||||
|
},
|
||||||
|
width: img.width,
|
||||||
|
height: img.height,
|
||||||
|
time: 0,
|
||||||
|
original: 1
|
||||||
|
},
|
||||||
|
subFileType: 0,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tryFastUploadCompleted: true,
|
||||||
|
srvSendMsg: false,
|
||||||
|
clientRandomId: crypto.randomBytes(8).readBigUInt64BE() & BigInt('0x7FFFFFFFFFFFFFFF'),
|
||||||
|
compatQMsgSceneType: 1,
|
||||||
|
extBizInfo: {
|
||||||
|
pic: {
|
||||||
|
bytesPbReserveTroop: Buffer.from("0800180020004200500062009201009a0100a2010c080012001800200028003a00", 'hex'),
|
||||||
|
textSummary: "Nya~", // TODO:
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
bytesPbReserve: Buffer.alloc(0),
|
||||||
|
},
|
||||||
|
ptt: {
|
||||||
|
bytesPbReserve: Buffer.alloc(0),
|
||||||
|
bytesReserve: Buffer.alloc(0),
|
||||||
|
bytesGeneralFlags: Buffer.alloc(0),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clientSeq: 0,
|
||||||
|
noNeedCompatMsg: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
);
|
);
|
||||||
return this.toHexStr(this.packOidbPacket(0x11c5, 100, req, true, false));
|
return this.packOidbPacket(0x11c5, 100, req, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async packUploadGroupVideoReq(groupUin: number, video: PacketMsgVideoElement): Promise<PacketHexStr> {
|
async packUploadGroupVideoReq(groupUin: number, video: PacketMsgVideoElement): Promise<OidbPacket> {
|
||||||
if (!video.fileSize || !video.thumbSize) throw new Error("video.fileSize or video.thumbSize is empty");
|
if (!video.fileSize || !video.thumbSize) throw new Error("video.fileSize or video.thumbSize is empty");
|
||||||
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
||||||
reqHead: {
|
reqHead: {
|
||||||
@@ -380,10 +388,10 @@ export class PacketPacker {
|
|||||||
noNeedCompatMsg: false
|
noNeedCompatMsg: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return this.toHexStr(this.packOidbPacket(0x11EA, 100, req, true, false));
|
return this.packOidbPacket(0x11EA, 100, req, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async packUploadC2CVideoReq(peerUin: string, video: PacketMsgVideoElement): Promise<PacketHexStr> {
|
async packUploadC2CVideoReq(peerUin: string, video: PacketMsgVideoElement): Promise<OidbPacket> {
|
||||||
if (!video.fileSize || !video.thumbSize) throw new Error("video.fileSize or video.thumbSize is empty");
|
if (!video.fileSize || !video.thumbSize) throw new Error("video.fileSize or video.thumbSize is empty");
|
||||||
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
||||||
reqHead: {
|
reqHead: {
|
||||||
@@ -466,10 +474,10 @@ export class PacketPacker {
|
|||||||
noNeedCompatMsg: false
|
noNeedCompatMsg: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return this.toHexStr(this.packOidbPacket(0x11E9, 100, req, true, false));
|
return this.packOidbPacket(0x11E9, 100, req, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async packUploadGroupPttReq(groupUin: number, ptt: PacketMsgPttElement): Promise<PacketHexStr> {
|
async packUploadGroupPttReq(groupUin: number, ptt: PacketMsgPttElement): Promise<OidbPacket> {
|
||||||
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
||||||
reqHead: {
|
reqHead: {
|
||||||
common: {
|
common: {
|
||||||
@@ -531,10 +539,10 @@ export class PacketPacker {
|
|||||||
noNeedCompatMsg: false
|
noNeedCompatMsg: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return this.toHexStr(this.packOidbPacket(0x126E, 100, req, true, false));
|
return this.packOidbPacket(0x126E, 100, req, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async packUploadC2CPttReq(peerUin: string, ptt: PacketMsgPttElement): Promise<PacketHexStr> {
|
async packUploadC2CPttReq(peerUin: string, ptt: PacketMsgPttElement): Promise<OidbPacket> {
|
||||||
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
const req = new NapProtoMsg(NTV2RichMediaReq).encode({
|
||||||
reqHead: {
|
reqHead: {
|
||||||
common: {
|
common: {
|
||||||
@@ -593,10 +601,10 @@ export class PacketPacker {
|
|||||||
noNeedCompatMsg: false
|
noNeedCompatMsg: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return this.toHexStr(this.packOidbPacket(0x126D, 100, req, true, false));
|
return this.packOidbPacket(0x126D, 100, req, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async packUploadGroupFileReq(groupUin: number, file: PacketMsgFileElement): Promise<PacketHexStr> {
|
async packUploadGroupFileReq(groupUin: number, file: PacketMsgFileElement): Promise<OidbPacket> {
|
||||||
const body = new NapProtoMsg(OidbSvcTrpcTcp0x6D6).encode({
|
const body = new NapProtoMsg(OidbSvcTrpcTcp0x6D6).encode({
|
||||||
file: {
|
file: {
|
||||||
groupUin: groupUin,
|
groupUin: groupUin,
|
||||||
@@ -613,10 +621,10 @@ export class PacketPacker {
|
|||||||
field15: true
|
field15: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return this.toHexStr(this.packOidbPacket(0x6D6, 0, body, true, false));
|
return this.packOidbPacket(0x6D6, 0, body, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async packUploadC2CFileReq(selfUid: string, peerUid: string, file: PacketMsgFileElement): Promise<PacketHexStr> {
|
async packUploadC2CFileReq(selfUid: string, peerUid: string, file: PacketMsgFileElement): Promise<OidbPacket> {
|
||||||
const body = new NapProtoMsg(OidbSvcTrpcTcp0XE37_1700).encode({
|
const body = new NapProtoMsg(OidbSvcTrpcTcp0XE37_1700).encode({
|
||||||
command: 1700,
|
command: 1700,
|
||||||
seq: 0,
|
seq: 0,
|
||||||
@@ -625,7 +633,7 @@ export class PacketPacker {
|
|||||||
receiverUid: peerUid,
|
receiverUid: peerUid,
|
||||||
fileSize: file.fileSize,
|
fileSize: file.fileSize,
|
||||||
fileName: file.fileName,
|
fileName: file.fileName,
|
||||||
md510MCheckSum: await computeMd5AndLengthWithLimit(file.filePath, 10*1024*1024),
|
md510MCheckSum: await computeMd5AndLengthWithLimit(file.filePath, 10 * 1024 * 1024),
|
||||||
sha1CheckSum: file.fileSha1,
|
sha1CheckSum: file.fileSha1,
|
||||||
localPath: "/",
|
localPath: "/",
|
||||||
md5CheckSum: file.fileMd5,
|
md5CheckSum: file.fileMd5,
|
||||||
@@ -635,11 +643,11 @@ export class PacketPacker {
|
|||||||
clientType: 1,
|
clientType: 1,
|
||||||
flagSupportMediaPlatform: 1
|
flagSupportMediaPlatform: 1
|
||||||
})
|
})
|
||||||
return this.toHexStr(this.packOidbPacket(0xE37, 1700, body, false, false));
|
return this.packOidbPacket(0xE37, 1700, body, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
packOfflineFileDownloadReq(fileUUID: string, fileHash: string, senderUid: string, receiverUid: string): PacketHexStr {
|
packOfflineFileDownloadReq(fileUUID: string, fileHash: string, senderUid: string, receiverUid: string): OidbPacket {
|
||||||
const req = this.packOidbPacket(0xE37, 800, new NapProtoMsg(OidbSvcTrpcTcp0XE37_800).encode({
|
return this.packOidbPacket(0xE37, 800, new NapProtoMsg(OidbSvcTrpcTcp0XE37_800).encode({
|
||||||
subCommand: 800,
|
subCommand: 800,
|
||||||
field2: 0,
|
field2: 0,
|
||||||
body: {
|
body: {
|
||||||
@@ -652,24 +660,22 @@ export class PacketPacker {
|
|||||||
field102: 1,
|
field102: 1,
|
||||||
field200: 1,
|
field200: 1,
|
||||||
}), false, false);
|
}), false, false);
|
||||||
return this.toHexStr(req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
packGroupFileDownloadReq(groupUin: number, fileUUID: string): PacketHexStr {
|
packGroupFileDownloadReq(groupUin: number, fileUUID: string): OidbPacket {
|
||||||
return this.toHexStr(
|
return this.packOidbPacket(0x6D6, 2, new NapProtoMsg(OidbSvcTrpcTcp0x6D6).encode({
|
||||||
this.packOidbPacket(0x6D6, 2, new NapProtoMsg(OidbSvcTrpcTcp0x6D6).encode({
|
|
||||||
download: {
|
download: {
|
||||||
groupUin: groupUin,
|
groupUin: groupUin,
|
||||||
appId: 7,
|
appId: 7,
|
||||||
busId: 102,
|
busId: 102,
|
||||||
fileId: fileUUID
|
fileId: fileUUID
|
||||||
}
|
}
|
||||||
}), true, false)
|
}), true, false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
packC2CFileDownloadReq(selfUid: string, fileUUID: string, fileHash: string): PacketHexStr {
|
packC2CFileDownloadReq(selfUid: string, fileUUID: string, fileHash: string): PacketHexStr {
|
||||||
return this.toHexStr(
|
return this.packetPacket(
|
||||||
new NapProtoMsg(OidbSvcTrpcTcp0XE37_1200).encode({
|
new NapProtoMsg(OidbSvcTrpcTcp0XE37_1200).encode({
|
||||||
subCommand: 1200,
|
subCommand: 1200,
|
||||||
field2: 1,
|
field2: 1,
|
||||||
@@ -687,17 +693,16 @@ export class PacketPacker {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
packGroupSignReq(uin: string, groupCode: string): PacketHexStr {
|
|
||||||
return this.toHexStr(
|
packGroupSignReq(uin: string, groupCode: string): OidbPacket {
|
||||||
this.packOidbPacket(0XEB7, 1, new NapProtoMsg(OidbSvcTrpcTcp0XEB7).encode(
|
return this.packOidbPacket(0XEB7, 1, new NapProtoMsg(OidbSvcTrpcTcp0XEB7).encode(
|
||||||
{
|
{
|
||||||
body: {
|
body: {
|
||||||
uin: uin,
|
uin: uin,
|
||||||
groupUin: groupCode,
|
groupUin: groupCode,
|
||||||
version: "9.0.90"
|
version: "9.0.90"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
), false, false)
|
}
|
||||||
);
|
), false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user