From fba483feba729d3267f741e36d35a1f6da2a2fa4 Mon Sep 17 00:00:00 2001 From: takayama Date: Sat, 20 Feb 2021 22:25:36 +0900 Subject: [PATCH] fix big pic --- client.d.ts | 11 ++++--- client.js | 16 +++++++++ lib/core.js | 3 +- lib/message/chat.js | 20 ++---------- lib/online-push.js | 2 +- lib/ref.d.ts | 1 + lib/service.js | 80 +++++++++++++++++++++++++++------------------ 7 files changed, 76 insertions(+), 57 deletions(-) diff --git a/client.d.ts b/client.d.ts index d6919332..7ad0e68d 100644 --- a/client.d.ts +++ b/client.d.ts @@ -533,11 +533,12 @@ export class Client extends events.EventEmitter { setPortrait(file: Buffer | string): Promise; //图片CQ码中file相同格式 setGroupPortrait(group_id: number, file: Buffer | string): Promise; - getFile(fileid: string, busid?: string): Promise>; //用于下载链接失效后重新获取 - getHistoryMsgs(message_id: string, num?: number): Promise>; //获取msgid往前的num条消息 - uploadC2CImages(user_id: number, images: ImgPttElem["data"][]): Promise>; //上传好友图以备发送 - uploadGroupImages(group_id: number, images: ImgPttElem["data"][]): Promise>; //上传群图以备发送 - getSummaryCard(user_id): Promise>; //查看用户资料 + // getFile(fileid: string, busid?: string): Promise>; //用于下载链接失效后重新获取 + // getHistoryMsgs(message_id: string, num?: number): Promise>; //获取msgid往前的num条消息 + // uploadC2CImages(user_id: number, images: ImgPttElem["data"][]): Promise>; //上传好友图以备发送 + // uploadGroupImages(group_id: number, images: ImgPttElem["data"][]): Promise>; //上传群图以备发送 + // getSummaryCard(user_id: number): Promise>; //查看用户资料 + // getForwardMsg(resid: string): Promise>; getCookies(domain?: string): Promise>; getCsrfToken(): Promise>; diff --git a/client.js b/client.js index 0ebf63d8..9984ca18 100644 --- a/client.js +++ b/client.js @@ -10,6 +10,7 @@ const os = require("os"); const { exec } = require("child_process"); const { randomBytes } = require("crypto"); const log4js = require("log4js"); +const pb = require("./lib/pb"); const { getApkInfo, getDeviceInfo } = require("./device"); const { checkUin, timestamp, md5 } = require("./lib/common"); const core = require("./lib/core"); @@ -413,6 +414,21 @@ class AndroidClient extends Client { } return cnt; } + buildSyncCookie() { + const time = timestamp(); + return pb.encode({ + 1: time, + 2: time, + 3: this.const1, + 4: this.const2, + 5: randomBytes(4).readUInt32BE(), + 9: randomBytes(4).readUInt32BE(), + 11: randomBytes(4).readUInt32BE(), + 12: this.const3, + 13: time, + 14: 0, + }); + } // 以下是public方法 ---------------------------------------------------------------------------------------------------- diff --git a/lib/core.js b/lib/core.js index c2436a82..2ede6d3f 100644 --- a/lib/core.js +++ b/lib/core.js @@ -7,7 +7,6 @@ const Readable = require("stream").Readable; const common = require("./common"); const pb = require("./pb"); const jce = require("./jce"); -const { buildSyncCookie } = require("./message/chat"); const { parsePrivateMsg } = require("./message/recv"); const push = require("./online-push"); const sysmsg = require("./sysmsg"); @@ -70,7 +69,7 @@ function onPushNotify(blob) { */ async function getMsg(sync_flag = 0) { if (!this.sync_cookie) - this.sync_cookie = buildSyncCookie.call(this); + this.sync_cookie = this.buildSyncCookie(); let body = pb.encode({ 1: sync_flag, 2: this.sync_cookie, diff --git a/lib/message/chat.js b/lib/message/chat.js index 8eca0c61..e8d7217d 100644 --- a/lib/message/chat.js +++ b/lib/message/chat.js @@ -87,22 +87,6 @@ async function sendMsg(target, message, escape, type) { return rsp; } -function buildSyncCookie() { - const time = common.timestamp(); - return pb.encode({ - 1: time, - 2: time, - 3: this.const1, - 4: this.const2, - 5: crypto.randomBytes(4).readUInt32BE(), - 9: crypto.randomBytes(4).readUInt32BE(), - 11: crypto.randomBytes(4).readUInt32BE(), - 12: this.const3, - 13: time, - 14: 0, - }); -} - /** * @this {import("../ref").Client} * @returns {import("../ref").ProtocolResponse} @@ -141,7 +125,7 @@ async function sendPrivateMsg(user_id, rich) { 3: { 1: rich }, 4: seq, 5: random, - 6: buildSyncCookie.call(this), + 6: this.buildSyncCookie(), 8: 1, }); const blob = await this.sendUNI("MessageSvc.PbSendMsg", body); @@ -486,5 +470,5 @@ async function getHistoryMsg(message_id) { } module.exports = { - sendMsg, recallMsg, buildSyncCookie, getHistoryMsg + sendMsg, recallMsg, getHistoryMsg }; diff --git a/lib/online-push.js b/lib/online-push.js index cc98da45..8898a31d 100644 --- a/lib/online-push.js +++ b/lib/online-push.js @@ -500,7 +500,7 @@ const FRAG = new Map; * Fuck Tencent * 1.是最后一个分片,返回组装好的消息 * 2.不是最后一个分片,返回空 - * @param {import("../ref").Msg} msg + * @param {import("./ref").Msg} msg */ async function rebuildFragments(msg) { const head = msg[1], content = msg[2], body = msg[3]; diff --git a/lib/ref.d.ts b/lib/ref.d.ts index 28731597..2ace2fab 100644 --- a/lib/ref.d.ts +++ b/lib/ref.d.ts @@ -168,4 +168,5 @@ export class Client extends oicq.Client { useProtocol(fn: Function, params: any[]): oicq.RetCommon; em(name: string, data: object): void; msgExists(from: number, type: number, seq: number, time: number): boolean; + buildSyncCookie(): Buffer; } diff --git a/lib/service.js b/lib/service.js index af9bc631..a28b6e80 100644 --- a/lib/service.js +++ b/lib/service.js @@ -8,6 +8,7 @@ const { randomBytes } = require("crypto"); const fs = require("fs"); const pb = require("./pb"); const jce = require("./jce"); +const common = require("./common"); const MAX_UPLOAD_SIZE = 31457280; function int32ip2str(ip) { @@ -26,35 +27,43 @@ function int32ip2str(ip) { * @this {import("./ref").Client} * @param {import("./ref").HighwayUploadObject} o * @param {Number} cmd - * @returns {Buffer} + * @returns {Buffer[]} */ -function buildHighwayUploadRequestPacket(o, cmd) { - const head = pb.encode({ - 1: { - 1: 1, - 2: String(this.uin), - 3: "PicUp.DataUp", - 4: randomBytes(2).readUInt16BE(), - 6: this.apk.subid, - 7: 4096, - 8: cmd, - 10: 2052, - }, - 2: { - 2: o.buf.length, - 3: 0, - 4: o.buf.length, - 6: o.key, - 8: o.md5, - 9: o.md5, - } - }); - const _ = Buffer.allocUnsafe(9); - _.writeUInt8(40); - _.writeUInt32BE(head.length, 1); - _.writeUInt32BE(o.buf.length, 5); - const __ = Buffer.from([41]); - return Buffer.concat([_, head, o.buf, __]); +function buildHighwayUploadRequestPackets(o, cmd, seq = randomBytes(2).readUInt16BE()) { + const packets = [], limit = 3000000, size = o.buf.length; + let chunk, offset = 0; + while (1) { + chunk = o.buf.slice(offset, offset + limit); + if (!chunk.length) break; + const head = pb.encode({ + 1: { + 1: 1, + 2: String(this.uin), + 3: "PicUp.DataUp", + 4: seq++, + 6: this.apk.subid, + 7: 4096, + 8: cmd, + 10: 2052, + }, + 2: { + 2: size, + 3: offset, + 4: chunk.length, + 6: o.key, + 8: common.md5(chunk), + 9: o.md5, + } + }); + offset += limit; + const _ = Buffer.allocUnsafe(9); + _.writeUInt8(40); + _.writeUInt32BE(head.length, 1); + _.writeUInt32BE(chunk.length, 5); + const __ = Buffer.from([41]); + packets.push(Buffer.concat([_, head, chunk, __])); + } + return packets; } /** @@ -70,12 +79,21 @@ async function highwayUpload(ip, port, o, cmd) { this.logger.trace(`highway ip:${ip} port:${port}`); return new Promise((resolve) => { const client = net.connect(port, ip, () => { - client.write(packet, client.end.bind(client)); + const pkt = packets.shift(); + client.write(pkt); + }); + client.on("data", () => { + if (!packets.length) { + resolve(); + client.destroy(); + } else { + const pkt = packets.shift(); + client.write(pkt); + } }); - client.on("end", resolve); client.on("close", resolve); client.on("error", resolve); - var packet = buildHighwayUploadRequestPacket.call(this, o, cmd); + var packets = buildHighwayUploadRequestPackets.call(this, o, cmd); }); }