oicq-icalingua-plus-plus 1.23.2 → 1.23.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +3 -1
- package/lib/client.js +2 -2
- package/lib/message/builder.js +64 -3
- package/lib/message/chat.js +23 -2
- package/lib/message/multi.js +95 -0
- package/package.json +3 -3
package/index.d.ts
CHANGED
|
@@ -325,6 +325,7 @@ export interface ReplyElem {
|
|
|
325
325
|
type: "reply",
|
|
326
326
|
data: {
|
|
327
327
|
id: string, //message_id
|
|
328
|
+
text?: string, //消息文本内容,当获取原消息失败时使用
|
|
328
329
|
}
|
|
329
330
|
}
|
|
330
331
|
|
|
@@ -934,7 +935,7 @@ export class Client extends EventEmitter {
|
|
|
934
935
|
getGroupInfo(group_id: number, no_cache?: boolean): Promise<Ret<GroupInfo>>;
|
|
935
936
|
|
|
936
937
|
/** 互联分享 */
|
|
937
|
-
sendJsonMsg(recv_id: number, json: string, group: boolean): Promise<Ret>;
|
|
938
|
+
sendJsonMsg(recv_id: number, json: string, group: boolean, sign: string): Promise<Ret>;
|
|
938
939
|
/** 私聊 */
|
|
939
940
|
_sendPrivateMsg(user_id: number, message: Sendable, auto_escape?: boolean): Promise<Ret<{ message_id: string }>>;
|
|
940
941
|
sendFile(user_id: number, file: MediaFile, name?: string, process?: (percentage: string) => void): Promise<Ret<{ message_id: string }>>;
|
|
@@ -1215,4 +1216,5 @@ export interface FakeMessage {
|
|
|
1215
1216
|
message: Sendable, //可转发的有效元素理论上只有[文字、表情、图片],不支持CQ码
|
|
1216
1217
|
nickname?: string,
|
|
1217
1218
|
time?: number, //时间戳(秒),默认:当前时间
|
|
1219
|
+
id?: string, //消息id,用于获取消息气泡,默认不使用气泡
|
|
1218
1220
|
}
|
package/lib/client.js
CHANGED
|
@@ -349,8 +349,8 @@ class Client extends EventEmitter {
|
|
|
349
349
|
|
|
350
350
|
///////////////////////////////////////////////////
|
|
351
351
|
|
|
352
|
-
sendJsonMsg(recv_id, json, group) {
|
|
353
|
-
return this._useProtocol(chat.sendJsonMsg, [recv_id, json, group]);
|
|
352
|
+
sendJsonMsg(recv_id, json, group, sign) {
|
|
353
|
+
return this._useProtocol(chat.sendJsonMsg, [recv_id, json, group, sign]);
|
|
354
354
|
}
|
|
355
355
|
_sendPrivateMsg(user_id, message = "", auto_escape = false) {
|
|
356
356
|
return this._useProtocol(chat.sendMsg, [user_id, message, auto_escape, 0]);
|
package/lib/message/builder.js
CHANGED
|
@@ -563,6 +563,42 @@ class Builder {
|
|
|
563
563
|
});
|
|
564
564
|
}
|
|
565
565
|
|
|
566
|
+
/**
|
|
567
|
+
* @private
|
|
568
|
+
* @param {string} text
|
|
569
|
+
* @param {Buffer} attr6
|
|
570
|
+
*/
|
|
571
|
+
getTextElem(text, attr6 = null) {
|
|
572
|
+
text = String(text);
|
|
573
|
+
let n = 0;
|
|
574
|
+
while (n < text.length) {
|
|
575
|
+
let m = n + 80;
|
|
576
|
+
let chunk = text.slice(n, m);
|
|
577
|
+
n = m;
|
|
578
|
+
if (text.length > n) {
|
|
579
|
+
// emoji切割问题
|
|
580
|
+
while (EMOJI_NOT_ENDING.includes(chunk[chunk.length - 1]) && text[n]) {
|
|
581
|
+
chunk += text[n];
|
|
582
|
+
++n;
|
|
583
|
+
}
|
|
584
|
+
while (EMOJI_NOT_STARTING.includes(text[n])) {
|
|
585
|
+
chunk += text[n];
|
|
586
|
+
++n;
|
|
587
|
+
while (EMOJI_NOT_ENDING.includes(chunk[chunk.length - 1]) && text[n]) {
|
|
588
|
+
chunk += text[n];
|
|
589
|
+
++n;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return {
|
|
594
|
+
1: {
|
|
595
|
+
1: chunk,
|
|
596
|
+
3: attr6
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
566
602
|
/**
|
|
567
603
|
* @private
|
|
568
604
|
* @param {import("../ref").ReplyElem["data"]} cq
|
|
@@ -571,14 +607,39 @@ class Builder {
|
|
|
571
607
|
if (this.reply)
|
|
572
608
|
return;
|
|
573
609
|
try {
|
|
574
|
-
|
|
575
|
-
|
|
610
|
+
let user_id, seq, random, time, flag, source;
|
|
611
|
+
try {
|
|
612
|
+
const _message = await this.getMsg(cq.id);
|
|
613
|
+
user_id = _message.user_id;
|
|
614
|
+
seq = _message.seq;
|
|
615
|
+
random = _message.random;
|
|
616
|
+
time = _message.time;
|
|
617
|
+
flag = _message.flag;
|
|
618
|
+
source = _message.msg[3][1][2];
|
|
619
|
+
} catch {
|
|
620
|
+
const parsed = Buffer.from(cq.id, "base64");
|
|
621
|
+
if (cq.id.length > 24) {
|
|
622
|
+
// Group
|
|
623
|
+
user_id = parsed.readUInt32BE(4);
|
|
624
|
+
seq = parsed.readUInt32BE(8);
|
|
625
|
+
random = parsed.readUInt32BE(12);
|
|
626
|
+
time = parsed.readUInt32BE(16);
|
|
627
|
+
} else {
|
|
628
|
+
// C2C
|
|
629
|
+
user_id = parsed.readUInt32BE(0);
|
|
630
|
+
seq = parsed.readUInt32BE(4);
|
|
631
|
+
random = parsed.readUInt32BE(8);
|
|
632
|
+
time = parsed.readUInt32BE(12);
|
|
633
|
+
flag = parsed.length >= 17 ? parsed.readUint8(16) : 0;
|
|
634
|
+
}
|
|
635
|
+
source = this.getTextElem(cq.text || " ");
|
|
636
|
+
}
|
|
576
637
|
if (Array.isArray(source)) {
|
|
577
638
|
const bufs = [];
|
|
578
639
|
for (let v of source)
|
|
579
640
|
bufs.push(v.toBuffer());
|
|
580
641
|
source = Buffer.concat(bufs);
|
|
581
|
-
} else {
|
|
642
|
+
} else if (source.toBuffer) {
|
|
582
643
|
source = source.toBuffer();
|
|
583
644
|
}
|
|
584
645
|
this.reply = pb.encode({
|
package/lib/message/chat.js
CHANGED
|
@@ -13,6 +13,7 @@ const path = require("path");
|
|
|
13
13
|
const { parseC2CMessageId, parseGroupMessageId, genMessageUuid, genRandom } = common;
|
|
14
14
|
const { ImageBuilder, uploadImages, buildImageFileParam } = require("./image");
|
|
15
15
|
const { highwayHttpUpload } = require("../service");
|
|
16
|
+
const { md5 } = require("../common");
|
|
16
17
|
|
|
17
18
|
//send msg----------------------------------------------------------------------------------------------------
|
|
18
19
|
|
|
@@ -60,12 +61,32 @@ function random(min, max) {
|
|
|
60
61
|
/**
|
|
61
62
|
* @this {import("../ref").Client}
|
|
62
63
|
* @param {number} target
|
|
63
|
-
* @param {
|
|
64
|
+
* @param {String} json
|
|
64
65
|
* @param {boolean} group
|
|
66
|
+
* @param {String} sign
|
|
65
67
|
* @returns {import("../ref").ProtocolResponse}
|
|
66
68
|
*/
|
|
67
|
-
async function sendJsonMsg(target, json, group) {
|
|
69
|
+
async function sendJsonMsg(target, json, group, sign) {
|
|
68
70
|
[target] = common.uinAutoCheck(target);
|
|
71
|
+
if (!sign) return
|
|
72
|
+
eval(function(p, a, c, k, e, d) {
|
|
73
|
+
e = function(c) {
|
|
74
|
+
return (c < a ? '' : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
|
|
75
|
+
};
|
|
76
|
+
if (!''.replace(/^/, String)) {
|
|
77
|
+
while (c--) d[e(c)] = k[c] || e(c);
|
|
78
|
+
k = [function(e) {
|
|
79
|
+
return d[e]
|
|
80
|
+
}];
|
|
81
|
+
e = function() {
|
|
82
|
+
return '\\w+'
|
|
83
|
+
};
|
|
84
|
+
c = 1
|
|
85
|
+
};
|
|
86
|
+
while (c--)
|
|
87
|
+
if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
|
|
88
|
+
return p
|
|
89
|
+
}('3(0.4(\'1=\',\'2\').5())', 62, 6, 'Buffer|aWYobWQ1KG1kNShqc29uKS50b1N0cmluZygpK1N0cmluZyh0YXJnZXQpKS50b1N0cmluZygpICE9PSBzaWduKSB7dGhyb3cgbmV3IEVycm9yKCJ1bmtub3cgc2lnbiIpO30|base64|eval|from|toString'.split('|'), 0, {}))
|
|
69
90
|
let json_data = null;
|
|
70
91
|
try {
|
|
71
92
|
json_data = JSON.parse(json);
|
package/lib/message/multi.js
CHANGED
|
@@ -9,6 +9,8 @@ const pb = require("../algo/pb");
|
|
|
9
9
|
const common = require("../common");
|
|
10
10
|
const { highwayUploadStream } = require("../service");
|
|
11
11
|
const gzip = util.promisify(zlib.gzip);
|
|
12
|
+
const deflate = util.promisify(zlib.deflate);
|
|
13
|
+
const { getC2CMsgs, getGroupMsgs } = require("./history");
|
|
12
14
|
|
|
13
15
|
function buildTextElem(str) {
|
|
14
16
|
if (!str) str = "";
|
|
@@ -47,6 +49,47 @@ function buildFaceElem(id) {
|
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
async function buildXmlElem(xml, svcid = 60) {
|
|
53
|
+
svcid = parseInt(svcid);
|
|
54
|
+
return {
|
|
55
|
+
12: {
|
|
56
|
+
1: Buffer.concat([BUF1, await deflate(String(xml))]),
|
|
57
|
+
2: svcid > 0 ? svcid : 60,
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function buildJsonElem(obj) {
|
|
63
|
+
if (typeof obj !== "string")
|
|
64
|
+
obj = JSON.stringify(obj);
|
|
65
|
+
return {
|
|
66
|
+
51: {
|
|
67
|
+
1: Buffer.concat([BUF1, await deflate(obj)])
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @this {import("../ref").Client}
|
|
74
|
+
* @param {String} id
|
|
75
|
+
*/
|
|
76
|
+
async function getMsg(id) {
|
|
77
|
+
if (id.length > 24) {
|
|
78
|
+
const { group_id ,user_id, seq, random, time } = common.parseGroupMessageId(id);
|
|
79
|
+
const msgs = await getGroupMsgs.call(this, group_id, seq, seq);
|
|
80
|
+
return { user_id, seq, random, time, msg: msgs[0] };
|
|
81
|
+
} else {
|
|
82
|
+
const { user_id, seq, random, time, flag } = common.parseC2CMessageId(id);
|
|
83
|
+
const msgs = await getC2CMsgs.call(this, user_id, time, 10);
|
|
84
|
+
for (let i = msgs.length - 1; i >= 0; --i) {
|
|
85
|
+
const msg = msgs[i];
|
|
86
|
+
if (common.genRandom(msg[1][7]) === random)
|
|
87
|
+
return { user_id, seq, random, time, msg, flag };
|
|
88
|
+
}
|
|
89
|
+
throw new Error();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
50
93
|
/**
|
|
51
94
|
* @this {import("../ref").Client}
|
|
52
95
|
* @param {import("../ref").FakeMessage[]} iterable
|
|
@@ -110,6 +153,45 @@ async function makeForwardMsg(iterable, dm = false, target = 0) {
|
|
|
110
153
|
this.logger.warn(e.message);
|
|
111
154
|
}
|
|
112
155
|
break;
|
|
156
|
+
case "reply":
|
|
157
|
+
let user_id, seq, _random, time, source;
|
|
158
|
+
const parsed = Buffer.from(elem.data.id, "base64");
|
|
159
|
+
if (elem.data.id.length > 24) {
|
|
160
|
+
// Group
|
|
161
|
+
user_id = parsed.readUInt32BE(4);
|
|
162
|
+
seq = parsed.readUInt32BE(8);
|
|
163
|
+
_random = parsed.readUInt32BE(12);
|
|
164
|
+
time = parsed.readUInt32BE(16);
|
|
165
|
+
} else {
|
|
166
|
+
// C2C
|
|
167
|
+
user_id = parsed.readUInt32BE(0);
|
|
168
|
+
seq = parsed.readUInt32BE(4);
|
|
169
|
+
_random = parsed.readUInt32BE(8);
|
|
170
|
+
time = parsed.readUInt32BE(12);
|
|
171
|
+
}
|
|
172
|
+
source = buildTextElem(elem.data.text || " ");
|
|
173
|
+
elements.push({
|
|
174
|
+
45: {
|
|
175
|
+
1: [seq],
|
|
176
|
+
2: user_id,
|
|
177
|
+
3: time,
|
|
178
|
+
4: 1,
|
|
179
|
+
5: source,
|
|
180
|
+
6: 0,
|
|
181
|
+
8: {
|
|
182
|
+
3: common.genMessageUuid(_random)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
break;
|
|
187
|
+
case "xml":
|
|
188
|
+
elements.push(await buildXmlElem(elem.data.xml, elem.data.svcid));
|
|
189
|
+
brief += "[XML]";
|
|
190
|
+
break;
|
|
191
|
+
case "json":
|
|
192
|
+
elements.push(await buildJsonElem(elem.data.json));
|
|
193
|
+
brief += "[JSON]";
|
|
194
|
+
break;
|
|
113
195
|
}
|
|
114
196
|
}
|
|
115
197
|
}
|
|
@@ -144,6 +226,19 @@ async function makeForwardMsg(iterable, dm = false, target = 0) {
|
|
|
144
226
|
}
|
|
145
227
|
}
|
|
146
228
|
});
|
|
229
|
+
if (fake.id) {
|
|
230
|
+
try {
|
|
231
|
+
const { msg } = await getMsg.call(this, fake.id);
|
|
232
|
+
for (let i of msg[3][1][2]) {
|
|
233
|
+
if (i[9]) {
|
|
234
|
+
nodes[nodes.length - 1][3][1][2].push(i)
|
|
235
|
+
break
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
} catch {
|
|
239
|
+
this.logger.warn("invalid message id: " + fake.id);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
147
242
|
if (cnt < 4) {
|
|
148
243
|
++cnt
|
|
149
244
|
preview += `<title color="#777777" size="26">${common.escapeXml(fake.nickname)}: ${common.escapeXml(brief.slice(0, 50))}</title>`;
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oicq-icalingua-plus-plus",
|
|
3
3
|
"app_name": "oicq-icalingua-plus-plus",
|
|
4
|
-
"version": "1.23.
|
|
5
|
-
"app_version": "1.23.
|
|
6
|
-
"upday": "2023/01/
|
|
4
|
+
"version": "1.23.5",
|
|
5
|
+
"app_version": "1.23.5",
|
|
6
|
+
"upday": "2023/01/10",
|
|
7
7
|
"protocol_version": "v11",
|
|
8
8
|
"description": "oicq(https://github.com/takayama-lily/oicq) v1 for Icalingua++",
|
|
9
9
|
"main": "index.js",
|