teeworlds 2.0.3 → 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 +165 -162
- package/lib/client.ts +5 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -308,184 +308,187 @@ var Client = /** @class */ (function (_super) {
|
|
|
308
308
|
clearInterval(connectInterval);
|
|
309
309
|
}, 500);
|
|
310
310
|
this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
|
|
311
|
-
this.socket
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
unpacked.
|
|
321
|
-
|
|
322
|
-
if (a.
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
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);
|
|
342
384
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
var unpacked = {};
|
|
350
|
-
unpacked.killer_id = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).result;
|
|
351
|
-
var remaining = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).remaining;
|
|
352
|
-
unpacked.victim_id = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
353
|
-
remaining = MsgUnpacker_1.default.unpackInt(remaining).remaining;
|
|
354
|
-
unpacked.weapon = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
355
|
-
remaining = MsgUnpacker_1.default.unpackInt(remaining).remaining;
|
|
356
|
-
unpacked.special_mode = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
357
|
-
if (unpacked.victim_id != -1)
|
|
358
|
-
unpacked.victim = { ClientInfo: _this.client_infos[unpacked.victim_id], PlayerInfo: _this.player_infos[unpacked.victim_id] };
|
|
359
|
-
if (unpacked.killer_id != -1)
|
|
360
|
-
unpacked.killer = { ClientInfo: _this.client_infos[unpacked.killer_id], PlayerInfo: _this.player_infos[unpacked.killer_id] };
|
|
361
|
-
// console.log(unpacked)
|
|
362
|
-
_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);
|
|
363
391
|
}
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
if (a.toJSON().data[0] == 0x10) {
|
|
367
|
-
if (a.toString().includes("TKEN") || arrStartsWith(a.toJSON().data, [0x10, 0x0, 0x0, 0x0])) {
|
|
368
|
-
clearInterval(connectInterval);
|
|
369
|
-
this.TKEN = Buffer.from(a.toJSON().data.slice(a.toJSON().data.length - 4, a.toJSON().data.length));
|
|
370
|
-
this.SendControlMsg(3);
|
|
371
|
-
this.State = 2; // loading state
|
|
372
|
-
info = new MsgPacker_1.default(1, true);
|
|
373
|
-
info.AddString("0.6 626fce9a778df4d4");
|
|
374
|
-
info.AddString(""); // password
|
|
375
|
-
client_version = new MsgPacker_1.default(0, true);
|
|
376
|
-
client_version.AddBuffer(Buffer.from("8c00130484613e478787f672b3835bd4", 'hex'));
|
|
377
|
-
randomUuid = new Uint8Array(16);
|
|
378
|
-
crypto_1.randomBytes(16).copy(randomUuid);
|
|
379
|
-
client_version.AddBuffer(Buffer.from(randomUuid));
|
|
380
|
-
client_version.AddInt(15091);
|
|
381
|
-
client_version.AddString("DDNet 15.9.1");
|
|
382
|
-
this.SendMsgExWithChunks([client_version, info], 1);
|
|
383
392
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
this.
|
|
387
|
-
reason = (MsgUnpacker_1.default.unpackString(a.toJSON().data.slice(4)).result);
|
|
388
|
-
this.State = -1;
|
|
389
|
-
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);
|
|
390
396
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
this.SendMsgEx(Msg, 1);
|
|
395
|
-
}
|
|
396
|
-
else if ((unpacked.chunks[0] && chunkMessages.includes("CAPABILITIES") || unpacked.chunks[0] && chunkMessages.includes("MAP_CHANGE"))) {
|
|
397
|
-
Msg = new MsgPacker_1.default(14, true);
|
|
398
|
-
this.SendMsgEx(Msg, 1);
|
|
399
|
-
}
|
|
400
|
-
else if ((unpacked.chunks[0] && chunkMessages.includes("CON_READY") || unpacked.chunks[0] && chunkMessages.includes("SV_MOTD"))) {
|
|
401
|
-
info = new MsgPacker_1.default(20, false);
|
|
402
|
-
info.AddString(this.name); /* name */
|
|
403
|
-
info.AddString(""); /* clan */
|
|
404
|
-
info.AddInt(-1); /* country */
|
|
405
|
-
info.AddString("greyfox"); /* skin */
|
|
406
|
-
info.AddInt(1); /* use custom color */
|
|
407
|
-
info.AddInt(10346103); /* color body */
|
|
408
|
-
info.AddInt(65535); /* color feet */
|
|
409
|
-
this.SendMsgEx(info, 1);
|
|
410
|
-
}
|
|
411
|
-
else if (unpacked.chunks[0] && chunkMessages.includes("SV_READY_TO_ENTER")) {
|
|
412
|
-
if (this.State != 3) {
|
|
413
|
-
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);
|
|
414
400
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
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) {
|
|
425
414
|
this.emit('connected');
|
|
415
|
+
}
|
|
426
416
|
this.State = 3;
|
|
427
417
|
}
|
|
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
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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])
|
|
467
460
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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
|
+
}
|
|
472
474
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
}); });
|
|
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
|
+
}); });
|
|
482
483
|
};
|
|
483
484
|
Client.prototype.Disconnect = function () {
|
|
484
485
|
var _this = this;
|
|
485
486
|
return new Promise(function (resolve) {
|
|
486
487
|
_this.SendControlMsg(4).then(function () {
|
|
487
488
|
resolve(true);
|
|
488
|
-
_this.socket
|
|
489
|
+
if (_this.socket)
|
|
490
|
+
_this.socket.close();
|
|
491
|
+
_this.socket = undefined;
|
|
489
492
|
_this.State = -1;
|
|
490
493
|
});
|
|
491
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
|
|
|
@@ -310,6 +310,7 @@ class Client extends EventEmitter {
|
|
|
310
310
|
clearInterval(connectInterval)
|
|
311
311
|
}, 500)
|
|
312
312
|
this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
|
|
313
|
+
if (this.socket)
|
|
313
314
|
this.socket.on("message", async (a) => {
|
|
314
315
|
var unpacked: _packet = await this.Unpack(a)
|
|
315
316
|
if (unpacked.twprotocol.flags != 128 && unpacked.twprotocol.ack) {
|
|
@@ -485,7 +486,9 @@ class Client extends EventEmitter {
|
|
|
485
486
|
return new Promise((resolve) => {
|
|
486
487
|
this.SendControlMsg(4).then(() => {
|
|
487
488
|
resolve(true);
|
|
488
|
-
this.socket
|
|
489
|
+
if (this.socket)
|
|
490
|
+
this.socket.close();
|
|
491
|
+
this.socket = undefined
|
|
489
492
|
this.State = -1;
|
|
490
493
|
})
|
|
491
494
|
})
|