oicq-icalingua-plus-plus 1.26.4 → 1.26.6
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/lib/message/face.js +27 -9
- package/lib/service.js +110 -89
- package/package.json +3 -3
package/lib/message/face.js
CHANGED
|
@@ -80,7 +80,7 @@ const map = {
|
|
|
80
80
|
106: "委屈",
|
|
81
81
|
107: "快哭了",
|
|
82
82
|
108: "阴险",
|
|
83
|
-
109: "
|
|
83
|
+
109: "左亲亲",
|
|
84
84
|
110: "吓",
|
|
85
85
|
111: "可怜",
|
|
86
86
|
112: "菜刀",
|
|
@@ -94,8 +94,8 @@ const map = {
|
|
|
94
94
|
120: "拳头",
|
|
95
95
|
121: "差劲",
|
|
96
96
|
122: "爱你",
|
|
97
|
-
123: "
|
|
98
|
-
124: "
|
|
97
|
+
123: "NO",
|
|
98
|
+
124: "OK",
|
|
99
99
|
125: "转圈",
|
|
100
100
|
126: "磕头",
|
|
101
101
|
127: "回头",
|
|
@@ -127,6 +127,7 @@ const map = {
|
|
|
127
127
|
176: "小纠结",
|
|
128
128
|
177: "喷血",
|
|
129
129
|
178: "斜眼笑",
|
|
130
|
+
179: "doge",
|
|
130
131
|
180: "惊喜",
|
|
131
132
|
181: "戳一戳",
|
|
132
133
|
182: "笑哭",
|
|
@@ -319,12 +320,10 @@ const map = {
|
|
|
319
320
|
389: "/太赞了",
|
|
320
321
|
390: "/太头秃",
|
|
321
322
|
391: "/太沧桑",
|
|
322
|
-
|
|
323
323
|
392: "/龙年快乐",
|
|
324
324
|
393: "/新年中龙",
|
|
325
325
|
394: "/新年大龙",
|
|
326
326
|
395: "/略略略",
|
|
327
|
-
|
|
328
327
|
396: "/狼狗",
|
|
329
328
|
397: "/抛媚眼",
|
|
330
329
|
398: "/超级ok",
|
|
@@ -343,12 +342,10 @@ const map = {
|
|
|
343
342
|
411: "/一起嗨",
|
|
344
343
|
412: "/开心",
|
|
345
344
|
413: "/摇起来",
|
|
346
|
-
|
|
347
345
|
415: "/划龙舟",
|
|
348
346
|
416: "/中龙舟",
|
|
349
347
|
417: "/大龙舟",
|
|
350
348
|
418: "/填罐罐",
|
|
351
|
-
|
|
352
349
|
419: "/火车",
|
|
353
350
|
420: "/中火车",
|
|
354
351
|
421: "/大火车",
|
|
@@ -362,8 +359,17 @@ const map = {
|
|
|
362
359
|
429: "/蛇年快乐",
|
|
363
360
|
430: "/蛇身",
|
|
364
361
|
431: "/蛇尾",
|
|
365
|
-
432: "
|
|
366
|
-
|
|
362
|
+
432: "/灵蛇献瑞",
|
|
363
|
+
433: "/大鸽",
|
|
364
|
+
435: "/关我鸟事",
|
|
365
|
+
436: "/跟鸽走",
|
|
366
|
+
437: "/鸽鸽生气",
|
|
367
|
+
438: "/可靠",
|
|
368
|
+
439: "/鸽瞅瞅",
|
|
369
|
+
440: "/鸽喜欢",
|
|
370
|
+
441: "/相信鸽",
|
|
371
|
+
442: "/鸽王",
|
|
372
|
+
449: "/+1",
|
|
367
373
|
450: "/撇嘴",
|
|
368
374
|
451: "/色",
|
|
369
375
|
452: "/微笑",
|
|
@@ -385,6 +391,18 @@ const map = {
|
|
|
385
391
|
468: "/失眠",
|
|
386
392
|
469: "/坚毅",
|
|
387
393
|
470: "/马到成功",
|
|
394
|
+
472: "/心动",
|
|
395
|
+
474: "/给你一拳",
|
|
396
|
+
475: "/干饭",
|
|
397
|
+
476: "/不是吧",
|
|
398
|
+
477: "/你懂的",
|
|
399
|
+
478: "/对的对的",
|
|
400
|
+
479: "/不对不对",
|
|
401
|
+
480: "/散味儿",
|
|
402
|
+
481: "/学习",
|
|
403
|
+
482: "/热化了",
|
|
404
|
+
483: "/略",
|
|
405
|
+
484: "/比爱心",
|
|
388
406
|
};
|
|
389
407
|
|
|
390
408
|
const FACE_OLD_BUF = Buffer.from([0x00, 0x01, 0x00, 0x04, 0x52, 0xCC, 0xF5, 0xD0]);
|
package/lib/service.js
CHANGED
|
@@ -176,117 +176,138 @@ function highwayUploadStream(readable, obj, ip, port) {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
const __ = Buffer.from([41])
|
|
179
|
-
// TODO: 优化内存占用
|
|
180
179
|
function highwayHttpUpload(readable, obj) {
|
|
181
|
-
const agent = new http.Agent({ maxSockets:
|
|
180
|
+
const agent = new http.Agent({ maxSockets: 1 })
|
|
182
181
|
const ip = this.storage.ip
|
|
183
182
|
const port = this.storage.port
|
|
184
183
|
if (!port) throw new Error("没有上传通道,如果你刚刚登录,请等待几秒")
|
|
185
184
|
|
|
186
185
|
console.log(`highway(http) ip:${ip} port:${port}`)
|
|
187
186
|
const url = "http://" + ip + ":" + port + "/cgi-bin/httpconn?htcmd=0x6FF0087&uin=" + this.uin
|
|
188
|
-
|
|
189
|
-
let offset = 0, limit = 524288
|
|
187
|
+
const limit = 524288
|
|
190
188
|
obj.ticket = this.storage.sig_session
|
|
191
189
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
let
|
|
190
|
+
let seq = 1
|
|
191
|
+
let offset = 0
|
|
192
|
+
let totalChunks = 0
|
|
193
|
+
let readEnded = false
|
|
194
|
+
|
|
195
|
+
// 顺序队列:每读到一个完整分块就推入,drain 循环逐个串行上传
|
|
196
|
+
const queue = []
|
|
197
|
+
let notify = null // 用于队列非空时唤醒 drain
|
|
198
|
+
let errFlag = null // 记录首个错误,终止后续上传
|
|
199
|
+
let quickDone = false
|
|
196
200
|
|
|
201
|
+
const buildBuf = (chunk, chunkOffset) => {
|
|
202
|
+
const head = pb.encode({
|
|
203
|
+
1: {
|
|
204
|
+
1: 1,
|
|
205
|
+
2: String(this.uin),
|
|
206
|
+
3: "PicUp.DataUp",
|
|
207
|
+
4: seq++,
|
|
208
|
+
5: 0,
|
|
209
|
+
6: this.apk.subid,
|
|
210
|
+
8: obj.cmdid,
|
|
211
|
+
},
|
|
212
|
+
2: {
|
|
213
|
+
1: 0,
|
|
214
|
+
2: obj.size,
|
|
215
|
+
3: chunkOffset,
|
|
216
|
+
4: chunk.length,
|
|
217
|
+
6: obj.ticket,
|
|
218
|
+
8: md5(chunk),
|
|
219
|
+
9: obj.md5,
|
|
220
|
+
10: 0,
|
|
221
|
+
13: 0,
|
|
222
|
+
},
|
|
223
|
+
3: obj.ext,
|
|
224
|
+
4: Date.now()
|
|
225
|
+
})
|
|
226
|
+
const header = Buffer.allocUnsafe(9)
|
|
227
|
+
header.writeUInt8(40)
|
|
228
|
+
header.writeUInt32BE(head.length, 1)
|
|
229
|
+
header.writeUInt32BE(chunk.length, 5)
|
|
230
|
+
return Buffer.concat([header, head, chunk, __])
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// 读取流 → 分块 → 入队
|
|
197
234
|
readable.on("data", data => {
|
|
235
|
+
if (errFlag || quickDone) return
|
|
198
236
|
let _offset = 0
|
|
199
237
|
while (_offset < data.length) {
|
|
200
238
|
const chunk = data.slice(_offset, limit + _offset)
|
|
201
|
-
const head = pb.encode({
|
|
202
|
-
1: {
|
|
203
|
-
1: 1,
|
|
204
|
-
2: String(this.uin),
|
|
205
|
-
3: "PicUp.DataUp",
|
|
206
|
-
4: seq++,
|
|
207
|
-
5: 0,
|
|
208
|
-
6: this.apk.subid,
|
|
209
|
-
8: obj.cmdid,
|
|
210
|
-
},
|
|
211
|
-
2: {
|
|
212
|
-
1: 0,
|
|
213
|
-
2: obj.size,
|
|
214
|
-
3: offset + _offset,
|
|
215
|
-
4: chunk.length,
|
|
216
|
-
6: obj.ticket,
|
|
217
|
-
8: md5(chunk),
|
|
218
|
-
9: obj.md5,
|
|
219
|
-
10: 0,
|
|
220
|
-
13: 0,
|
|
221
|
-
},
|
|
222
|
-
3: obj.ext,
|
|
223
|
-
4: Date.now()
|
|
224
|
-
})
|
|
225
239
|
_offset += chunk.length
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const buf = Buffer.concat([_, head, chunk, __])
|
|
231
|
-
bufs.add(buf)
|
|
240
|
+
++totalChunks
|
|
241
|
+
const buf = buildBuf(chunk, offset + _offset - chunk.length)
|
|
242
|
+
queue.push(buf)
|
|
243
|
+
if (notify) { notify(); notify = null }
|
|
232
244
|
}
|
|
233
245
|
offset += data.length
|
|
234
246
|
})
|
|
235
247
|
|
|
248
|
+
readable.on("err", err => { errFlag = err })
|
|
249
|
+
|
|
250
|
+
// 串行 drain 循环:逐个从队列取分块上传
|
|
251
|
+
const drain = async () => {
|
|
252
|
+
let finished = 0
|
|
253
|
+
while (true) {
|
|
254
|
+
while (queue.length === 0) {
|
|
255
|
+
if (errFlag) return
|
|
256
|
+
if (readEnded) {
|
|
257
|
+
// 流已结束且队列为空,检查是否全部完成
|
|
258
|
+
if (finished >= totalChunks) return
|
|
259
|
+
}
|
|
260
|
+
// 等待新分块入队
|
|
261
|
+
await new Promise(r => { notify = r })
|
|
262
|
+
}
|
|
263
|
+
const buf = queue.shift()
|
|
264
|
+
const r = await axios.post(url, buf, {
|
|
265
|
+
responseType: "arraybuffer",
|
|
266
|
+
httpAgent: agent,
|
|
267
|
+
headers: {
|
|
268
|
+
"Content-Length": String(buf.length),
|
|
269
|
+
"Content-Type": "application/octet-stream"
|
|
270
|
+
}
|
|
271
|
+
})
|
|
272
|
+
let rsp
|
|
273
|
+
try {
|
|
274
|
+
const respBuf = Buffer.from(r?.data)
|
|
275
|
+
const header = respBuf.slice(9, respBuf.length - 1)
|
|
276
|
+
rsp = pb.decode(header)
|
|
277
|
+
} catch (err) {
|
|
278
|
+
throw err
|
|
279
|
+
}
|
|
280
|
+
if (rsp?.[3] !== 0) {
|
|
281
|
+
throw new Error(`${rsp[3]}, unknown highway error`)
|
|
282
|
+
}
|
|
283
|
+
++finished
|
|
284
|
+
const percentage = (finished / totalChunks * 100).toFixed(2)
|
|
285
|
+
this.logger.debug(`highway(http) chunk uploaded (${percentage}%)`)
|
|
286
|
+
if (typeof obj.callback === "function")
|
|
287
|
+
obj.callback(percentage)
|
|
288
|
+
// 快传:服务端已持有全部数据,跳过后续分块
|
|
289
|
+
if (rsp[7]?.toBuffer().length > 0) {
|
|
290
|
+
quickDone = true
|
|
291
|
+
this.logger.debug(`highway(http) can quick upload`)
|
|
292
|
+
this.logger.debug(`highway(http) chunk uploaded (100.00%)`)
|
|
293
|
+
if (typeof obj.callback === "function")
|
|
294
|
+
obj.callback("100.00")
|
|
295
|
+
return
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
236
300
|
return new Promise((resolve, reject) => {
|
|
237
301
|
readable.on("err", reject)
|
|
238
|
-
.on("end",
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
await axios.post(url, buf, {
|
|
243
|
-
responseType: "arraybuffer",
|
|
244
|
-
httpAgent: agent,
|
|
245
|
-
signal: controller.signal,
|
|
246
|
-
headers: {
|
|
247
|
-
"Content-Length": String(buf.length),
|
|
248
|
-
"Content-Type": "application/octet-stream"
|
|
249
|
-
}
|
|
250
|
-
}).then(r => {
|
|
251
|
-
let percentage, rsp
|
|
252
|
-
try {
|
|
253
|
-
const buf = Buffer.from(r?.data)
|
|
254
|
-
const header = buf.slice(9, buf.length - 1)
|
|
255
|
-
rsp = pb.decode(header)
|
|
256
|
-
} catch (err) {
|
|
257
|
-
this.logger.error(err)
|
|
258
|
-
reject(err)
|
|
259
|
-
return
|
|
260
|
-
}
|
|
261
|
-
if (rsp?.[3] !== 0) {
|
|
262
|
-
controller.abort()
|
|
263
|
-
reject(new Error(`${rsp[3]}, unknown highway error"`))
|
|
264
|
-
return
|
|
265
|
-
}
|
|
266
|
-
++finished
|
|
267
|
-
percentage = (finished / bufs.size * 100).toFixed(2)
|
|
268
|
-
this.logger.debug(`highway(http) chunk uploaded (${percentage}%)`)
|
|
269
|
-
if (typeof obj.callback === "function" && percentage)
|
|
270
|
-
obj.callback(percentage)
|
|
271
|
-
if (finished < bufs.size && rsp[7]?.toBuffer().length > 0) {
|
|
272
|
-
controller.abort()
|
|
273
|
-
flag = true
|
|
274
|
-
this.logger.debug(`highway(http) can quick upload`)
|
|
275
|
-
this.logger.debug(`highway(http) chunk uploaded (100.00%)`)
|
|
276
|
-
if (typeof obj.callback === "function")
|
|
277
|
-
obj.callback("100.00")
|
|
278
|
-
}
|
|
279
|
-
if (finished >= bufs.size && !rsp[7]?.toBuffer().length)
|
|
280
|
-
reject("文件校验未通过,上传失败")
|
|
281
|
-
}).catch(err => {
|
|
282
|
-
if (err instanceof axios.Cancel === false) {
|
|
283
|
-
reject(err)
|
|
284
|
-
}
|
|
285
|
-
flag = true
|
|
286
|
-
})
|
|
287
|
-
}
|
|
288
|
-
resolve(undefined)
|
|
302
|
+
readable.on("end", () => {
|
|
303
|
+
readEnded = true
|
|
304
|
+
// 流结束时唤醒 drain(如果它正在等待)
|
|
305
|
+
if (notify) { notify(); notify = null }
|
|
289
306
|
})
|
|
307
|
+
drain().then(() => {
|
|
308
|
+
if (errFlag) reject(errFlag)
|
|
309
|
+
else resolve(undefined)
|
|
310
|
+
}).catch(reject)
|
|
290
311
|
})
|
|
291
312
|
}
|
|
292
313
|
|
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.26.
|
|
5
|
-
"app_version": "1.26.
|
|
6
|
-
"upday": "2026/
|
|
4
|
+
"version": "1.26.6",
|
|
5
|
+
"app_version": "1.26.6",
|
|
6
|
+
"upday": "2026/07/18",
|
|
7
7
|
"protocol_version": "v11",
|
|
8
8
|
"description": "oicq(https://github.com/takayama-lily/oicq) v1 for Icalingua++",
|
|
9
9
|
"main": "index.js",
|