From bf8eaa6dcb5c8ca365049a9d9d1b4de5eaace751 Mon Sep 17 00:00:00 2001 From: takayama Date: Sat, 5 Dec 2020 13:06:57 +0900 Subject: [PATCH 1/2] Delete long msg. Add fragments. --- client.d.ts | 2 +- lib/message/builder.js | 52 +++++++-------- lib/message/chat.js | 142 ++++++++++++++++++++--------------------- 3 files changed, 92 insertions(+), 104 deletions(-) diff --git a/client.d.ts b/client.d.ts index 12f1f4ef..509757da 100644 --- a/client.d.ts +++ b/client.d.ts @@ -13,7 +13,7 @@ export interface ConfBot { platform?: number, //1手机 2平板(默认) 3手表(不支持部分群事件) kickoff?: boolean, //被挤下线是否在3秒后反挤对方,默认false ignore_self?: boolean,//群聊是否无视自己的发言,默认true - resend?: boolean, //被风控时是否尝试用另一种方式强行发送,默认true + resend?: boolean, //被风控时是否尝试用分片发送,默认true data_dir?: string, //数据存储文件夹,需要可写权限,默认主目录下的data文件夹 //网络原因导致的断线重连间隔秒数,默认5秒,不建议设置低于3秒 diff --git a/lib/message/builder.js b/lib/message/builder.js index f4625858..f98f6099 100644 --- a/lib/message/builder.js +++ b/lib/message/builder.js @@ -13,15 +13,6 @@ const common = require("../common"); const {parseC2CMessageId, parseGroupMessageId, genMessageUuid} = common; const pb = require("../pb"); -const PB_RESERVER = pb.encode({ - 17: 0, - 19: { - 15: 0, - 31: 0, - 41: 0 - }, -}); - function unescapeCQ(s) { if (s === "[") return "["; if (s === "]") return "]"; @@ -75,13 +66,17 @@ class Builder { buildTextElem(text, attr6 = null) { if (text || attr6) { text = String(text); - this.elems.push({ - 1: { - 1: text, - 3: attr6 - } - }); - this.stat.length += Buffer.byteLength(text); + let n = 0; + while (n <= text.length) { + this.elems.push({ + 1: { + 1: text.slice(n, n + 100), + 3: attr6 + } + }); + this.stat.length += Buffer.byteLength(text); + n += 100; + } } } buildAtElem(cq) { @@ -143,6 +138,17 @@ class Builder { ++this.stat.sface_cnt; } } + buildSFaceElem(cq) { + let {id, text} = cq; + id = parseInt(id); + this.elems.push({ + 34: { + 1: id, + 2: 1, + } + }); + this.buildTextElem(text); + } buildBFaceElem(cq) { try { let {file, text} = cq; @@ -512,12 +518,6 @@ class Builder { this.reply = true; } - buildGeneralFlagsElem() { - this.elems.push({ - 37: PB_RESERVER - }); - } - buildShakeElem() { this.elems.push({ 17: { @@ -680,18 +680,12 @@ class Builder { } await Promise.all(this.tasks); await uploadImages.call(this.c, this.target, this.imgs, this.type); - this.buildGeneralFlagsElem(); this.length = this.stat.length + this.stat.at_cnt * 22 + this.stat.face_cnt * 23 + this.stat.sface_cnt * 42 + this.stat.bface_cnt * 135 + this.stat.img_cnt * (this.type?90:295); - this.length *= 1.05; - } - - isLong() { - return this.type ? (this.length>790) : (this.length>935); } } @@ -747,5 +741,5 @@ async function audioTrans(cache_filepath, file) { } module.exports = { - Builder, PB_RESERVER + Builder }; diff --git a/lib/message/chat.js b/lib/message/chat.js index 8955e356..3686371f 100644 --- a/lib/message/chat.js +++ b/lib/message/chat.js @@ -1,7 +1,7 @@ "use strict"; const zlib = require("zlib"); const crypto = require("crypto"); -const {Builder, PB_RESERVER} = require("./builder"); +const {Builder} = require("./builder"); const {uploadMultiMsg} = require("./storage"); const {getC2CMsg, getGroupMsg} = require("./history"); const {handleGroupMsg, handlePrivateMsg} = require("./recv"); @@ -10,6 +10,14 @@ const pb = require("../pb"); const {genC2CMessageId, parseC2CMessageId, parseGroupMessageId, genMessageUuid} = common; const BUF1 = Buffer.from([1]); const PB_CONTENT = pb.encode({1:1, 2:0, 3:0}); +const PB_RESERVER = pb.encode({ + 17: 0, + 19: { + 15: 0, + 31: 0, + 41: 0 + }, +}); //send msg---------------------------------------------------------------------------------------------------- @@ -26,16 +34,24 @@ async function sendMsg(target, message, escape, type) { const builder = new Builder(this, target, type); await builder.exec(message, escape); - const _sendMsg = async(rich, long = false)=>{ - if (long) - rich[2] = await toLongMessageElems.call(this, target, rich, type); + const _sendMsg = async(rich, frag = false)=>{ if (builder.anon) { if (!rich[2]) rich[2] = []; rich[2].push(builder.anon); } ++this.stat.sent_msg_cnt; - return await (type?sendGroupMsg:sendPrivateMsg).call(this, target, rich, type); + if (frag && rich[2] && type === 1) { + rich[2].pop(); + return await sendGroupMsgByFrag.call(this, target, toFragments(rich[2])); + } else { + if (rich[2]) { + rich[2].push({ + 37: PB_RESERVER + }); + } + return await (type?sendGroupMsg:sendPrivateMsg).call(this, target, rich, type); + } } let rsp; @@ -62,9 +78,9 @@ async function sendMsg(target, message, escape, type) { if (rsp) return rsp; throw new Error("empty message"); } - rsp = await _sendMsg({2: builder.elems}, builder.isLong()); - if (this.config.resend && !builder.isLong() && rsp.data && rsp.data.message_id === "" && !builder.anon) { - this.logger.warn(`此消息将尝试以另一种方式再发送一次。`); + rsp = await _sendMsg({2: builder.elems}); + if (this.config.resend && rsp.data && rsp.data.message_id === "") { + this.logger.warn(`此消息将尝试使用分片发送。`); return await _sendMsg({2: builder.elems}, true); } return rsp; @@ -189,75 +205,53 @@ async function sendGroupMsg(target, rich, type) { /** * @this {import("../ref").Client} - * @returns {Array} + * @returns {import("../ref").ProtocolResponse} */ -async function toLongMessageElems(uin, rich, is_group) { - const compressed = zlib.gzipSync(pb.encode({ - 1: { - 1: { - 1: this.uin, - 3: is_group?82:9, - 4: 11, - 5: crypto.randomBytes(2).readUInt16BE(), - 6: common.timestamp(), - 9: { - 1: uin, - 4: this.nickname, - }, - 14: this.nickname, - 20: { - 1:0, - 2:1 - }, - }, - 3: { - 1: rich, +async function sendGroupMsgByFrag(group_id, fragments) { + const routing = {2: {1: group_id}}; + let n = 0; + const random = crypto.randomBytes(4).readUInt32BE(); + const div = crypto.randomBytes(2).readUInt16BE(); + for (let fragment of fragments) { + const body = pb.encode({ + 1: routing, + 2: { + 1: fragments.length, + 2: n, + 3: div }, - }, - })); - try { - var resid = await uploadMultiMsg.call(this, uin, compressed); - } catch (e) { - throw new Error("fail to upload multi msg"); + 3: {1: {2: fragment}}, + 4: this.seq_id + 1, + 5: random, + 8: 0, + }); + ++n; + this.writeUNI("MessageSvc.PbSendMsg", body); } - const templete = ` - - - [图文消息] - - 点击查看完整消息 - - -`; - return [ - { - 12: { - 1: Buffer.concat([BUF1, zlib.deflateSync(templete)]), - 2: 35, - } - }, - { - 1: { - 1: "你的QQ暂不支持查看[转发多条消息],请期待后续版本。", - } - }, - { - 37: { - 6: 1, - 7: resid, - 17: 0, - 19: { - 15: 0, - 31: 0, - 41: 0 - }, - } - }, - ]; + this.logger.info(`send to: [Group: ${group_id} / fragments]`); + return {result: 0, data: {message_id: ""}}; +} + +function toFragments(elems) { + const fragments = []; + let fragment = []; + for (let elem of elems) { + fragment.push(elem); + if (elem[1] && !elem[1][3]) { //1:text 1[3]:at + fragment.push({ + 37: PB_RESERVER + }); + fragments.push(fragment); + fragment = []; + } + } + if (fragment.length > 0) { + fragment.push({ + 37: PB_RESERVER + }); + fragments.push(fragment); + } + return fragments; } /** From 24f61acbac23a83ffae62749cf25134903960357 Mon Sep 17 00:00:00 2001 From: takayama Date: Sat, 5 Dec 2020 13:09:36 +0900 Subject: [PATCH 2/2] up ver to 1.11.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index c059bd50..47fd638f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "oicq", - "version": "1.11.0", + "version": "1.11.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9fd4417c..f99cc27d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oicq", - "version": "1.11.0", + "version": "1.11.1", "upday": "2020/12/01", "description": "QQ protocol!", "main": "client.js",