teeworlds 2.0.1 → 2.0.4
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/client.js +176 -167
- package/lib/client.ts +16 -7
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -242,11 +242,13 @@ var Client = /** @class */ (function (_super) {
|
|
|
242
242
|
var _this = this;
|
|
243
243
|
if (ExtraMsg === void 0) { ExtraMsg = ""; }
|
|
244
244
|
return new Promise(function (resolve, reject) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
245
|
+
if (_this.socket) {
|
|
246
|
+
var latestBuf = Buffer.from([0x10 + (((16 << 4) & 0xf0) | ((_this.ack >> 8) & 0xf)), _this.ack & 0xff, 0x00, msg]);
|
|
247
|
+
latestBuf = Buffer.concat([latestBuf, Buffer.from(ExtraMsg), _this.TKEN]); // move header (latestBuf), optional extraMsg & TKEN into 1 buffer
|
|
248
|
+
_this.socket.send(latestBuf, 0, latestBuf.length, _this.port, _this.host, function (err, bytes) {
|
|
249
|
+
resolve(bytes);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
250
252
|
setTimeout(function () { resolve("failed, rip"); }, 2000);
|
|
251
253
|
/* after 2 seconds it was probably not able to send,
|
|
252
254
|
so when sending a quit message the user doesnt
|
|
@@ -257,6 +259,8 @@ var Client = /** @class */ (function (_super) {
|
|
|
257
259
|
Client.prototype.SendMsgEx = function (Msg, Flags) {
|
|
258
260
|
if (this.State == -1)
|
|
259
261
|
throw new Error("Client is not connected");
|
|
262
|
+
if (!this.socket)
|
|
263
|
+
return;
|
|
260
264
|
var header = [];
|
|
261
265
|
header[0] = ((Flags & 3) << 6) | ((Msg.size >> 4) & 0x3f);
|
|
262
266
|
header[1] = (Msg.size & 0xf);
|
|
@@ -273,6 +277,8 @@ var Client = /** @class */ (function (_super) {
|
|
|
273
277
|
var _this = this;
|
|
274
278
|
if (this.State == -1)
|
|
275
279
|
throw new Error("Client is not connected");
|
|
280
|
+
if (!this.socket)
|
|
281
|
+
return;
|
|
276
282
|
var header = [];
|
|
277
283
|
Msgs.forEach(function (Msg, index) {
|
|
278
284
|
header[index] = new Array(2);
|
|
@@ -302,184 +308,187 @@ var Client = /** @class */ (function (_super) {
|
|
|
302
308
|
clearInterval(connectInterval);
|
|
303
309
|
}, 500);
|
|
304
310
|
this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
|
|
305
|
-
this.socket
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
unpacked.
|
|
315
|
-
|
|
316
|
-
if (a.
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
311
|
+
if (this.socket)
|
|
312
|
+
this.socket.on("message", function (a) { return __awaiter(_this, void 0, void 0, function () {
|
|
313
|
+
var unpacked, chunkMessages, chat, chat, info, client_version, randomUuid, reason, Msg, Msg, info, info, chunks, part_1, num_parts_1;
|
|
314
|
+
var _this = this;
|
|
315
|
+
return __generator(this, function (_a) {
|
|
316
|
+
switch (_a.label) {
|
|
317
|
+
case 0: return [4 /*yield*/, this.Unpack(a)];
|
|
318
|
+
case 1:
|
|
319
|
+
unpacked = _a.sent();
|
|
320
|
+
if (unpacked.twprotocol.flags != 128 && unpacked.twprotocol.ack) {
|
|
321
|
+
unpacked.chunks.forEach(function (a) {
|
|
322
|
+
if (a.msg && !a.msg.startsWith("SNAP")) {
|
|
323
|
+
if (a.seq != undefined && a.seq != -1)
|
|
324
|
+
_this.ack = a.seq;
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
chunkMessages = unpacked.chunks.map(function (a) { return a.msg; });
|
|
329
|
+
if (chunkMessages.includes("SV_CHAT")) {
|
|
330
|
+
chat = unpacked.chunks.filter(function (a) { return a.msg == "SV_CHAT"; });
|
|
331
|
+
chat.forEach(function (a) {
|
|
332
|
+
if (a.msg == "SV_CHAT") {
|
|
333
|
+
var unpacked = {};
|
|
334
|
+
unpacked.team = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).result;
|
|
335
|
+
var remaining = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).remaining;
|
|
336
|
+
unpacked.client_id = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
337
|
+
remaining = MsgUnpacker_1.default.unpackInt(remaining).remaining;
|
|
338
|
+
unpacked.message = MsgUnpacker_1.default.unpackString(remaining).result;
|
|
339
|
+
if (unpacked.client_id != -1)
|
|
340
|
+
unpacked.author = { ClientInfo: _this.client_infos[unpacked.client_id], PlayerInfo: _this.player_infos[unpacked.client_id] };
|
|
341
|
+
// console.log(unpacked)
|
|
342
|
+
_this.emit("message", unpacked);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
if (chunkMessages.includes("SV_KILL_MSG")) {
|
|
347
|
+
chat = unpacked.chunks.filter(function (a) { return a.msg == "SV_KILL_MSG"; });
|
|
348
|
+
chat.forEach(function (a) {
|
|
349
|
+
if (a.msg == "SV_KILL_MSG") {
|
|
350
|
+
var unpacked = {};
|
|
351
|
+
unpacked.killer_id = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).result;
|
|
352
|
+
var remaining = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).remaining;
|
|
353
|
+
unpacked.victim_id = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
354
|
+
remaining = MsgUnpacker_1.default.unpackInt(remaining).remaining;
|
|
355
|
+
unpacked.weapon = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
356
|
+
remaining = MsgUnpacker_1.default.unpackInt(remaining).remaining;
|
|
357
|
+
unpacked.special_mode = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
358
|
+
if (unpacked.victim_id != -1)
|
|
359
|
+
unpacked.victim = { ClientInfo: _this.client_infos[unpacked.victim_id], PlayerInfo: _this.player_infos[unpacked.victim_id] };
|
|
360
|
+
if (unpacked.killer_id != -1)
|
|
361
|
+
unpacked.killer = { ClientInfo: _this.client_infos[unpacked.killer_id], PlayerInfo: _this.player_infos[unpacked.killer_id] };
|
|
362
|
+
// console.log(unpacked)
|
|
363
|
+
_this.emit("kill", unpacked);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
if (a.toJSON().data[0] == 0x10) {
|
|
368
|
+
if (a.toString().includes("TKEN") || arrStartsWith(a.toJSON().data, [0x10, 0x0, 0x0, 0x0])) {
|
|
369
|
+
clearInterval(connectInterval);
|
|
370
|
+
this.TKEN = Buffer.from(a.toJSON().data.slice(a.toJSON().data.length - 4, a.toJSON().data.length));
|
|
371
|
+
this.SendControlMsg(3);
|
|
372
|
+
this.State = 2; // loading state
|
|
373
|
+
info = new MsgPacker_1.default(1, true);
|
|
374
|
+
info.AddString("0.6 626fce9a778df4d4");
|
|
375
|
+
info.AddString(""); // password
|
|
376
|
+
client_version = new MsgPacker_1.default(0, true);
|
|
377
|
+
client_version.AddBuffer(Buffer.from("8c00130484613e478787f672b3835bd4", 'hex'));
|
|
378
|
+
randomUuid = new Uint8Array(16);
|
|
379
|
+
crypto_1.randomBytes(16).copy(randomUuid);
|
|
380
|
+
client_version.AddBuffer(Buffer.from(randomUuid));
|
|
381
|
+
client_version.AddInt(15091);
|
|
382
|
+
client_version.AddString("DDNet 15.9.1");
|
|
383
|
+
this.SendMsgExWithChunks([client_version, info], 1);
|
|
336
384
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
var unpacked = {};
|
|
344
|
-
unpacked.killer_id = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).result;
|
|
345
|
-
var remaining = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).remaining;
|
|
346
|
-
unpacked.victim_id = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
347
|
-
remaining = MsgUnpacker_1.default.unpackInt(remaining).remaining;
|
|
348
|
-
unpacked.weapon = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
349
|
-
remaining = MsgUnpacker_1.default.unpackInt(remaining).remaining;
|
|
350
|
-
unpacked.special_mode = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
351
|
-
if (unpacked.victim_id != -1)
|
|
352
|
-
unpacked.victim = { ClientInfo: _this.client_infos[unpacked.victim_id], PlayerInfo: _this.player_infos[unpacked.victim_id] };
|
|
353
|
-
if (unpacked.killer_id != -1)
|
|
354
|
-
unpacked.killer = { ClientInfo: _this.client_infos[unpacked.killer_id], PlayerInfo: _this.player_infos[unpacked.killer_id] };
|
|
355
|
-
// console.log(unpacked)
|
|
356
|
-
_this.emit("kill", unpacked);
|
|
385
|
+
else if (a.toJSON().data[3] == 0x4) {
|
|
386
|
+
// disconnected
|
|
387
|
+
this.State = 0;
|
|
388
|
+
reason = (MsgUnpacker_1.default.unpackString(a.toJSON().data.slice(4)).result);
|
|
389
|
+
this.State = -1;
|
|
390
|
+
this.emit("disconnect", reason);
|
|
357
391
|
}
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
if (a.toJSON().data[0] == 0x10) {
|
|
361
|
-
if (a.toString().includes("TKEN") || arrStartsWith(a.toJSON().data, [0x10, 0x0, 0x0, 0x0])) {
|
|
362
|
-
clearInterval(connectInterval);
|
|
363
|
-
this.TKEN = Buffer.from(a.toJSON().data.slice(a.toJSON().data.length - 4, a.toJSON().data.length));
|
|
364
|
-
this.SendControlMsg(3);
|
|
365
|
-
this.State = 2; // loading state
|
|
366
|
-
info = new MsgPacker_1.default(1, true);
|
|
367
|
-
info.AddString("0.6 626fce9a778df4d4");
|
|
368
|
-
info.AddString(""); // password
|
|
369
|
-
client_version = new MsgPacker_1.default(0, true);
|
|
370
|
-
client_version.AddBuffer(Buffer.from("8c00130484613e478787f672b3835bd4", 'hex'));
|
|
371
|
-
randomUuid = new Uint8Array(16);
|
|
372
|
-
crypto_1.randomBytes(16).copy(randomUuid);
|
|
373
|
-
client_version.AddBuffer(Buffer.from(randomUuid));
|
|
374
|
-
client_version.AddInt(15091);
|
|
375
|
-
client_version.AddString("DDNet 15.9.1");
|
|
376
|
-
this.SendMsgExWithChunks([client_version, info], 1);
|
|
377
392
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
this.
|
|
381
|
-
reason = (MsgUnpacker_1.default.unpackString(a.toJSON().data.slice(4)).result);
|
|
382
|
-
this.State = -1;
|
|
383
|
-
this.emit("disconnect", reason);
|
|
393
|
+
if (unpacked.chunks[0] && chunkMessages.includes("SV_READY_TO_ENTER")) {
|
|
394
|
+
Msg = new MsgPacker_1.default(15, true);
|
|
395
|
+
this.SendMsgEx(Msg, 1);
|
|
384
396
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
this.SendMsgEx(Msg, 1);
|
|
389
|
-
}
|
|
390
|
-
else if ((unpacked.chunks[0] && chunkMessages.includes("CAPABILITIES") || unpacked.chunks[0] && chunkMessages.includes("MAP_CHANGE"))) {
|
|
391
|
-
Msg = new MsgPacker_1.default(14, true);
|
|
392
|
-
this.SendMsgEx(Msg, 1);
|
|
393
|
-
}
|
|
394
|
-
else if ((unpacked.chunks[0] && chunkMessages.includes("CON_READY") || unpacked.chunks[0] && chunkMessages.includes("SV_MOTD"))) {
|
|
395
|
-
info = new MsgPacker_1.default(20, false);
|
|
396
|
-
info.AddString(this.name); /* name */
|
|
397
|
-
info.AddString(""); /* clan */
|
|
398
|
-
info.AddInt(-1); /* country */
|
|
399
|
-
info.AddString("greyfox"); /* skin */
|
|
400
|
-
info.AddInt(1); /* use custom color */
|
|
401
|
-
info.AddInt(10346103); /* color body */
|
|
402
|
-
info.AddInt(65535); /* color feet */
|
|
403
|
-
this.SendMsgEx(info, 1);
|
|
404
|
-
}
|
|
405
|
-
else if (unpacked.chunks[0] && chunkMessages.includes("SV_READY_TO_ENTER")) {
|
|
406
|
-
if (this.State != 3) {
|
|
407
|
-
this.emit('connected');
|
|
397
|
+
else if ((unpacked.chunks[0] && chunkMessages.includes("CAPABILITIES") || unpacked.chunks[0] && chunkMessages.includes("MAP_CHANGE"))) {
|
|
398
|
+
Msg = new MsgPacker_1.default(14, true);
|
|
399
|
+
this.SendMsgEx(Msg, 1);
|
|
408
400
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
401
|
+
else if ((unpacked.chunks[0] && chunkMessages.includes("CON_READY") || unpacked.chunks[0] && chunkMessages.includes("SV_MOTD"))) {
|
|
402
|
+
info = new MsgPacker_1.default(20, false);
|
|
403
|
+
info.AddString(this.name); /* name */
|
|
404
|
+
info.AddString(""); /* clan */
|
|
405
|
+
info.AddInt(-1); /* country */
|
|
406
|
+
info.AddString("greyfox"); /* skin */
|
|
407
|
+
info.AddInt(1); /* use custom color */
|
|
408
|
+
info.AddInt(10346103); /* color body */
|
|
409
|
+
info.AddInt(65535); /* color feet */
|
|
410
|
+
this.SendMsgEx(info, 1);
|
|
411
|
+
}
|
|
412
|
+
else if (unpacked.chunks[0] && chunkMessages.includes("SV_READY_TO_ENTER")) {
|
|
413
|
+
if (this.State != 3) {
|
|
419
414
|
this.emit('connected');
|
|
415
|
+
}
|
|
420
416
|
this.State = 3;
|
|
421
417
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
418
|
+
else if (unpacked.chunks[0] && chunkMessages.includes("PING")) {
|
|
419
|
+
info = new MsgPacker_1.default(23, true);
|
|
420
|
+
this.SendMsgEx(info, 1);
|
|
421
|
+
}
|
|
422
|
+
if (chunkMessages.includes("SNAP") || chunkMessages.includes("SNAP_EMPTY") || chunkMessages.includes("SNAP_SINGLE")) {
|
|
423
|
+
this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
|
|
424
|
+
if (this.receivedSnaps >= 2) {
|
|
425
|
+
if (this.State != 3)
|
|
426
|
+
this.emit('connected');
|
|
427
|
+
this.State = 3;
|
|
428
|
+
}
|
|
429
|
+
chunks = unpacked.chunks.filter(function (a) { return a.msg == "SNAP" || a.msg == "SNAP_SINGLE" || a.msg == "SNAP_EMPTY"; });
|
|
430
|
+
if (chunks.length > 0) {
|
|
431
|
+
part_1 = 0;
|
|
432
|
+
num_parts_1 = 1;
|
|
433
|
+
chunks.forEach(function (chunk) {
|
|
434
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
435
|
+
var AckGameTick = (MsgUnpacker_1.default.unpackInt(chunk.raw.toJSON().data).result);
|
|
436
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.default.unpackInt((_a = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _a === void 0 ? void 0 : _a.toJSON().data).remaining);
|
|
437
|
+
var DeltaTick = MsgUnpacker_1.default.unpackInt((_b = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _b === void 0 ? void 0 : _b.toJSON().data).result;
|
|
438
|
+
if (chunk.msg == "SNAP") {
|
|
439
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.default.unpackInt((_c = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _c === void 0 ? void 0 : _c.toJSON().data).remaining); // delta tick
|
|
440
|
+
num_parts_1 = (MsgUnpacker_1.default.unpackInt((_d = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _d === void 0 ? void 0 : _d.toJSON().data).result);
|
|
441
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.default.unpackInt((_e = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _e === void 0 ? void 0 : _e.toJSON().data).remaining); // num parts
|
|
442
|
+
part_1 = (MsgUnpacker_1.default.unpackInt((_f = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _f === void 0 ? void 0 : _f.toJSON().data).result);
|
|
443
|
+
}
|
|
444
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.default.unpackInt((_g = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _g === void 0 ? void 0 : _g.toJSON().data).remaining); // part
|
|
445
|
+
if (chunk.msg != "SNAP_EMPTY")
|
|
446
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.default.unpackInt((_h = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _h === void 0 ? void 0 : _h.toJSON().data).remaining); // crc
|
|
447
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.default.unpackInt((_j = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _j === void 0 ? void 0 : _j.toJSON().data).remaining); // crc
|
|
448
|
+
if (part_1 == 0 || _this.snaps.length > 30) {
|
|
449
|
+
_this.snaps = [];
|
|
450
|
+
}
|
|
451
|
+
_this.snaps.push(chunk.raw);
|
|
452
|
+
if ((num_parts_1 - 1) == part_1 && _this.snaps.length == num_parts_1) {
|
|
453
|
+
var mergedSnaps = Buffer.concat(_this.snaps);
|
|
454
|
+
var snapUnpacked = SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, 1);
|
|
455
|
+
snapUnpacked.items.forEach(function (a, i) {
|
|
456
|
+
if (a.type_id == items.OBJ_CLIENT_INFO) {
|
|
457
|
+
_this.client_infos[a.id] = a.parsed;
|
|
458
|
+
// console.log(a.parsed, i)
|
|
459
|
+
// console.log(this.client_infos[a.id])
|
|
461
460
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
461
|
+
else if (a.type_id == items.OBJ_PLAYER_INFO) {
|
|
462
|
+
_this.player_infos[i] = a.parsed;
|
|
463
|
+
}
|
|
464
|
+
else if (a.type_id == items.OBJ_EX || a.type_id > 0x4000) {
|
|
465
|
+
if (a.data.length == 5 && (a.parsed.freeze_end > 0 || a.parsed.freeze_end == -1)) {
|
|
466
|
+
// var packer = new MsgPacker(22, false)
|
|
467
|
+
// this.SendMsgEx(packer, 1)
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}
|
|
466
474
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
});
|
|
475
|
-
}); });
|
|
475
|
+
if (new Date().getTime() - this.time >= 1000) {
|
|
476
|
+
this.time = new Date().getTime();
|
|
477
|
+
this.SendControlMsg(0);
|
|
478
|
+
}
|
|
479
|
+
return [2 /*return*/];
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
}); });
|
|
476
483
|
};
|
|
477
484
|
Client.prototype.Disconnect = function () {
|
|
478
485
|
var _this = this;
|
|
479
486
|
return new Promise(function (resolve) {
|
|
480
487
|
_this.SendControlMsg(4).then(function () {
|
|
481
488
|
resolve(true);
|
|
482
|
-
_this.socket
|
|
489
|
+
if (_this.socket)
|
|
490
|
+
_this.socket.close();
|
|
491
|
+
_this.socket = undefined;
|
|
483
492
|
_this.State = -1;
|
|
484
493
|
});
|
|
485
494
|
});
|
package/lib/client.ts
CHANGED
|
@@ -156,7 +156,7 @@ declare interface Client {
|
|
|
156
156
|
receivedSnaps: number; /* wait for 2 ss before seeing self as connected */
|
|
157
157
|
lastMsg: string;
|
|
158
158
|
_port: number;
|
|
159
|
-
socket: net.Socket;
|
|
159
|
+
socket: net.Socket | undefined;
|
|
160
160
|
TKEN: Buffer;
|
|
161
161
|
time: number;
|
|
162
162
|
|
|
@@ -242,12 +242,14 @@ class Client extends EventEmitter {
|
|
|
242
242
|
}
|
|
243
243
|
SendControlMsg(msg: number, ExtraMsg: string = "") {
|
|
244
244
|
return new Promise((resolve, reject) => {
|
|
245
|
+
if (this.socket) {
|
|
246
|
+
var latestBuf = Buffer.from([0x10 + (((16 << 4) & 0xf0) | ((this.ack >> 8) & 0xf)), this.ack & 0xff, 0x00, msg])
|
|
247
|
+
latestBuf = Buffer.concat([latestBuf, Buffer.from(ExtraMsg), this.TKEN]) // move header (latestBuf), optional extraMsg & TKEN into 1 buffer
|
|
248
|
+
this.socket.send(latestBuf, 0, latestBuf.length, this.port, this.host, (err, bytes) => {
|
|
249
|
+
resolve(bytes)
|
|
250
|
+
})
|
|
245
251
|
|
|
246
|
-
|
|
247
|
-
latestBuf = Buffer.concat([latestBuf, Buffer.from(ExtraMsg), this.TKEN]) // move header (latestBuf), optional extraMsg & TKEN into 1 buffer
|
|
248
|
-
this.socket.send(latestBuf, 0, latestBuf.length, this.port, this.host, (err, bytes) => {
|
|
249
|
-
resolve(bytes)
|
|
250
|
-
})
|
|
252
|
+
}
|
|
251
253
|
setTimeout(() => { resolve("failed, rip") }, 2000)
|
|
252
254
|
/* after 2 seconds it was probably not able to send,
|
|
253
255
|
so when sending a quit message the user doesnt
|
|
@@ -258,6 +260,8 @@ class Client extends EventEmitter {
|
|
|
258
260
|
SendMsgEx(Msg: MsgPacker, Flags: number) {
|
|
259
261
|
if (this.State == -1)
|
|
260
262
|
throw new Error("Client is not connected");
|
|
263
|
+
if (!this.socket)
|
|
264
|
+
return;
|
|
261
265
|
var header = []
|
|
262
266
|
header[0] = ((Flags & 3) << 6) | ((Msg.size >> 4) & 0x3f);
|
|
263
267
|
header[1] = (Msg.size & 0xf);
|
|
@@ -274,6 +278,8 @@ class Client extends EventEmitter {
|
|
|
274
278
|
SendMsgExWithChunks(Msgs: MsgPacker[], Flags: number) {
|
|
275
279
|
if (this.State == -1)
|
|
276
280
|
throw new Error("Client is not connected");
|
|
281
|
+
if (!this.socket)
|
|
282
|
+
return;
|
|
277
283
|
var header: any[][] = [];
|
|
278
284
|
|
|
279
285
|
Msgs.forEach((Msg: MsgPacker, index) => {
|
|
@@ -304,6 +310,7 @@ class Client extends EventEmitter {
|
|
|
304
310
|
clearInterval(connectInterval)
|
|
305
311
|
}, 500)
|
|
306
312
|
this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
|
|
313
|
+
if (this.socket)
|
|
307
314
|
this.socket.on("message", async (a) => {
|
|
308
315
|
var unpacked: _packet = await this.Unpack(a)
|
|
309
316
|
if (unpacked.twprotocol.flags != 128 && unpacked.twprotocol.ack) {
|
|
@@ -479,7 +486,9 @@ class Client extends EventEmitter {
|
|
|
479
486
|
return new Promise((resolve) => {
|
|
480
487
|
this.SendControlMsg(4).then(() => {
|
|
481
488
|
resolve(true);
|
|
482
|
-
this.socket
|
|
489
|
+
if (this.socket)
|
|
490
|
+
this.socket.close();
|
|
491
|
+
this.socket = undefined
|
|
483
492
|
this.State = -1;
|
|
484
493
|
})
|
|
485
494
|
})
|