oicq-icalingua-plus-plus 1.24.39 → 1.24.40
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/oicq.js +19 -4
- package/lib/qimei.js +21 -6
- package/lib/service.js +40 -3
- package/package.json +3 -3
package/lib/oicq.js
CHANGED
|
@@ -14,7 +14,7 @@ const { timestamp, BUF0, BUF16, unzip, log } = require("./common");
|
|
|
14
14
|
const push = require("./onlinepush");
|
|
15
15
|
const sysmsg = require("./core/sysmsg");
|
|
16
16
|
const { initFL, initGL } = require("./core/friendlist");
|
|
17
|
-
const { int32ip2str, getUploadChannel } = require("./service");
|
|
17
|
+
const { int32ip2str, getUploadChannel, checkIPConnectivity } = require("./service");
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* @this {Client}
|
|
@@ -102,6 +102,11 @@ function pushReqListener(blob, seq) {
|
|
|
102
102
|
if (v[1] === 10) {
|
|
103
103
|
this.storage.port = v[2][0][3];
|
|
104
104
|
this.storage.ip = int32ip2str(v[2][0][2]);
|
|
105
|
+
checkIPConnectivity(this.storage.ip, this.storage.port).then((res) => {
|
|
106
|
+
if (res) return;
|
|
107
|
+
this.logger.warn("上传通道IP不可用,将使用通用域名");
|
|
108
|
+
this.storage.ip = "v6.htdata.qq.com";
|
|
109
|
+
});
|
|
105
110
|
}
|
|
106
111
|
}
|
|
107
112
|
this.saveStorageConfig();
|
|
@@ -170,7 +175,6 @@ function msfOfflineListener(blob) {
|
|
|
170
175
|
* @this {Client}
|
|
171
176
|
*/
|
|
172
177
|
function kickoffListener(data) {
|
|
173
|
-
this._wt.deleteToken();
|
|
174
178
|
this.status = STATUS_PENDING;
|
|
175
179
|
this._stopHeartbeat();
|
|
176
180
|
this.logger.warn(data.info);
|
|
@@ -191,6 +195,7 @@ function kickoffListener(data) {
|
|
|
191
195
|
this.logger.mark("3秒后重新连接..");
|
|
192
196
|
setTimeout(this.login.bind(this), 3000);
|
|
193
197
|
}
|
|
198
|
+
if (sub_type !== "kickoff") this._wt.deleteToken();
|
|
194
199
|
this.em("system.offline." + sub_type, { message: data.info });
|
|
195
200
|
}
|
|
196
201
|
|
|
@@ -209,6 +214,7 @@ Client.prototype._register = async function () {
|
|
|
209
214
|
};
|
|
210
215
|
|
|
211
216
|
Client.prototype._var4 = 0;
|
|
217
|
+
Client.prototype._nt_hb_var = 0;
|
|
212
218
|
Client.prototype._runCircleTask = async function () {
|
|
213
219
|
if (this._var4++ > 10) {
|
|
214
220
|
await this._wt.refreshD2();
|
|
@@ -235,13 +241,22 @@ Client.prototype._startHeartbeat = function () {
|
|
|
235
241
|
}
|
|
236
242
|
this._wt.syncTimeDiff();
|
|
237
243
|
this._wt.heartbeat();
|
|
238
|
-
if (this.config.useNT)
|
|
244
|
+
if (this.config.useNT) {
|
|
245
|
+
if (this._nt_hb_var++ >= 5) {
|
|
246
|
+
this._nt_hb_var = 0;
|
|
247
|
+
this._wt.ssoHeartbeat();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
239
250
|
if (timestamp() - this.sig.qsign_token_time >= (60 * 60)) {
|
|
240
251
|
this.sig.qsign_token_time = timestamp();
|
|
241
252
|
this.refreshQSignToken();
|
|
242
253
|
}
|
|
243
254
|
if (!this.storage.port) {
|
|
244
|
-
|
|
255
|
+
try {
|
|
256
|
+
await getUploadChannel.call(this);
|
|
257
|
+
} catch {
|
|
258
|
+
this.logger.warn("getUploadChannel failed");
|
|
259
|
+
}
|
|
245
260
|
}
|
|
246
261
|
}, 30000);
|
|
247
262
|
};
|
package/lib/qimei.js
CHANGED
|
@@ -17,6 +17,22 @@ LQ+FLkpncClKVIrBwv6PHyUvuCb0rIarmgDnzkfQAqVufEtR64iazGDKatvJ9y6B
|
|
|
17
17
|
9NMbHddGSAUmRTCrHQIDAQAB
|
|
18
18
|
-----END PUBLIC KEY-----`;
|
|
19
19
|
|
|
20
|
+
class SeededRandom {
|
|
21
|
+
constructor(seed) {
|
|
22
|
+
this.seed = seed;
|
|
23
|
+
this.state = md5(seed.toString()).toString("hex");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
next() {
|
|
27
|
+
this.state = md5(this.state + secret).toString("hex");
|
|
28
|
+
return parseInt(this.state.substring(0, 8), 16) / 0xffffffff;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
nextInt(min, max) {
|
|
32
|
+
return Math.floor(this.next() * (max - min + 1)) + min;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
function dateFormat(fmt = "YYYY-mm-dd HH:MM:SS", date = new Date()) {
|
|
21
37
|
let ret;
|
|
22
38
|
const opt = {
|
|
@@ -43,10 +59,9 @@ function dateFormat(fmt = "YYYY-mm-dd HH:MM:SS", date = new Date()) {
|
|
|
43
59
|
* @returns
|
|
44
60
|
*/
|
|
45
61
|
function genRandomPayloadByDevice(info, apk, platform) {
|
|
62
|
+
const seededRandom = new SeededRandom(info.android_id);
|
|
46
63
|
const rangeRand = (max = 1, min = 0) => {
|
|
47
|
-
|
|
48
|
-
const diff = max - min
|
|
49
|
-
return Math.floor(Math.random() * diff) + min
|
|
64
|
+
return seededRandom.nextInt(min, max);
|
|
50
65
|
};
|
|
51
66
|
const reserved = {
|
|
52
67
|
"harmony": "0",
|
|
@@ -67,10 +82,10 @@ function genRandomPayloadByDevice(info, apk, platform) {
|
|
|
67
82
|
"kernel": info.proc_version
|
|
68
83
|
};
|
|
69
84
|
let beaconId = "";
|
|
70
|
-
const timestamp =
|
|
71
|
-
const mtime1 = new Date(
|
|
85
|
+
const timestamp = info.mtime || apk.buildtime * 1000 + rangeRand(10 * 24 * 60 * 60 * 1000, 0);
|
|
86
|
+
const mtime1 = new Date(timestamp);
|
|
72
87
|
const mtimeStr1 = dateFormat("YYYY-mm-ddHHMMSS", mtime1) + "." + info.imei.slice(2, 11);
|
|
73
|
-
const mtime2 = new Date(
|
|
88
|
+
const mtime2 = new Date(timestamp - parseInt(info.imei.slice(2, 4)));
|
|
74
89
|
const mtimeStr2 = dateFormat("YYYY-mm-ddHHMMSS", mtime2) + "." + info.imei.slice(5, 14);
|
|
75
90
|
for (let i = 1; i <= 40; i++) {
|
|
76
91
|
if ([1, 13, 14, 17, 18, 21, 33, 34, 37, 38].includes(i)) {
|
package/lib/service.js
CHANGED
|
@@ -354,10 +354,47 @@ async function getUploadChannel() {
|
|
|
354
354
|
const rsp = pb.decode(blob)[1281];
|
|
355
355
|
this.storage.sig_session = rsp[1].toBuffer();
|
|
356
356
|
this.storage.session_key = rsp[2].toBuffer();
|
|
357
|
-
|
|
358
|
-
this.storage.
|
|
357
|
+
const server = Array.isArray(rsp[3][2]) ? rsp[3][2][0] : rsp[3][2];
|
|
358
|
+
this.storage.ip = int32ip2str(server[2]);
|
|
359
|
+
this.storage.port = server[3];
|
|
360
|
+
if (!(await checkIPConnectivity(this.storage.ip, this.storage.port))) {
|
|
361
|
+
this.logger.warn("上传通道IP不可用,将使用通用域名");
|
|
362
|
+
this.storage.ip = "v6.htdata.qq.com";
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* 检查IP地址是否连通
|
|
368
|
+
* @param {string} ip - 要检查的IP地址
|
|
369
|
+
* @param {number} port - 要检查的端口号
|
|
370
|
+
* @param {number} timeout - 超时时间,单位毫秒
|
|
371
|
+
* @returns {Promise<boolean>}
|
|
372
|
+
*/
|
|
373
|
+
function checkIPConnectivity(ip, port, timeout = 5000) {
|
|
374
|
+
return new Promise((resolve) => {
|
|
375
|
+
const socket = new net.Socket();
|
|
376
|
+
|
|
377
|
+
socket.setTimeout(timeout);
|
|
378
|
+
|
|
379
|
+
socket.on('connect', () => {
|
|
380
|
+
socket.destroy();
|
|
381
|
+
resolve(true);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
socket.on('timeout', () => {
|
|
385
|
+
socket.destroy();
|
|
386
|
+
resolve(false);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
socket.on('error', () => {
|
|
390
|
+
socket.destroy();
|
|
391
|
+
resolve(false);
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
socket.connect(port, ip);
|
|
395
|
+
});
|
|
359
396
|
}
|
|
360
397
|
|
|
361
398
|
module.exports = {
|
|
362
|
-
downloadFromWeb, highwayUploadStream, int32ip2str, highwayHttpUpload, MAX_UPLOAD_SIZE, getUploadChannel,
|
|
399
|
+
downloadFromWeb, highwayUploadStream, int32ip2str, highwayHttpUpload, MAX_UPLOAD_SIZE, getUploadChannel, checkIPConnectivity
|
|
363
400
|
};
|
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.24.
|
|
5
|
-
"app_version": "1.24.
|
|
6
|
-
"upday": "2024/08/
|
|
4
|
+
"version": "1.24.40",
|
|
5
|
+
"app_version": "1.24.40",
|
|
6
|
+
"upday": "2024/08/08",
|
|
7
7
|
"protocol_version": "v11",
|
|
8
8
|
"description": "oicq(https://github.com/takayama-lily/oicq) v1 for Icalingua++",
|
|
9
9
|
"main": "index.js",
|