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.
Files changed (3) hide show
  1. package/lib/client.js +176 -167
  2. package/lib/client.ts +16 -7
  3. 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
- var latestBuf = Buffer.from([0x10 + (((16 << 4) & 0xf0) | ((_this.ack >> 8) & 0xf)), _this.ack & 0xff, 0x00, msg]);
246
- latestBuf = Buffer.concat([latestBuf, Buffer.from(ExtraMsg), _this.TKEN]); // move header (latestBuf), optional extraMsg & TKEN into 1 buffer
247
- _this.socket.send(latestBuf, 0, latestBuf.length, _this.port, _this.host, function (err, bytes) {
248
- resolve(bytes);
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.on("message", function (a) { return __awaiter(_this, void 0, void 0, function () {
306
- var unpacked, chunkMessages, chat, chat, info, client_version, randomUuid, reason, Msg, Msg, info, info, chunks, part_1, num_parts_1;
307
- var _this = this;
308
- return __generator(this, function (_a) {
309
- switch (_a.label) {
310
- case 0: return [4 /*yield*/, this.Unpack(a)];
311
- case 1:
312
- unpacked = _a.sent();
313
- if (unpacked.twprotocol.flags != 128 && unpacked.twprotocol.ack) {
314
- unpacked.chunks.forEach(function (a) {
315
- if (a.msg && !a.msg.startsWith("SNAP")) {
316
- if (a.seq != undefined && a.seq != -1)
317
- _this.ack = a.seq;
318
- }
319
- });
320
- }
321
- chunkMessages = unpacked.chunks.map(function (a) { return a.msg; });
322
- if (chunkMessages.includes("SV_CHAT")) {
323
- chat = unpacked.chunks.filter(function (a) { return a.msg == "SV_CHAT"; });
324
- chat.forEach(function (a) {
325
- if (a.msg == "SV_CHAT") {
326
- var unpacked = {};
327
- unpacked.team = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).result;
328
- var remaining = MsgUnpacker_1.default.unpackInt(a.raw.toJSON().data).remaining;
329
- unpacked.client_id = MsgUnpacker_1.default.unpackInt(remaining).result;
330
- remaining = MsgUnpacker_1.default.unpackInt(remaining).remaining;
331
- unpacked.message = MsgUnpacker_1.default.unpackString(remaining).result;
332
- if (unpacked.client_id != -1)
333
- unpacked.author = { ClientInfo: _this.client_infos[unpacked.client_id], PlayerInfo: _this.player_infos[unpacked.client_id] };
334
- // console.log(unpacked)
335
- _this.emit("message", unpacked);
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
- if (chunkMessages.includes("SV_KILL_MSG")) {
340
- chat = unpacked.chunks.filter(function (a) { return a.msg == "SV_KILL_MSG"; });
341
- chat.forEach(function (a) {
342
- if (a.msg == "SV_KILL_MSG") {
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
- else if (a.toJSON().data[3] == 0x4) {
379
- // disconnected
380
- this.State = 0;
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
- if (unpacked.chunks[0] && chunkMessages.includes("SV_READY_TO_ENTER")) {
387
- Msg = new MsgPacker_1.default(15, true);
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
- this.State = 3;
410
- }
411
- else if (unpacked.chunks[0] && chunkMessages.includes("PING")) {
412
- info = new MsgPacker_1.default(23, true);
413
- this.SendMsgEx(info, 1);
414
- }
415
- if (chunkMessages.includes("SNAP") || chunkMessages.includes("SNAP_EMPTY") || chunkMessages.includes("SNAP_SINGLE")) {
416
- this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
417
- if (this.receivedSnaps >= 2) {
418
- if (this.State != 3)
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
- chunks = unpacked.chunks.filter(function (a) { return a.msg == "SNAP" || a.msg == "SNAP_SINGLE" || a.msg == "SNAP_EMPTY"; });
423
- if (chunks.length > 0) {
424
- part_1 = 0;
425
- num_parts_1 = 1;
426
- chunks.forEach(function (chunk) {
427
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
428
- var AckGameTick = (MsgUnpacker_1.default.unpackInt(chunk.raw.toJSON().data).result);
429
- 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);
430
- 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;
431
- if (chunk.msg == "SNAP") {
432
- 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
433
- 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);
434
- 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
435
- 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);
436
- }
437
- 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
438
- if (chunk.msg != "SNAP_EMPTY")
439
- 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
440
- 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
441
- if (part_1 == 0 || _this.snaps.length > 30) {
442
- _this.snaps = [];
443
- }
444
- _this.snaps.push(chunk.raw);
445
- if ((num_parts_1 - 1) == part_1 && _this.snaps.length == num_parts_1) {
446
- var mergedSnaps = Buffer.concat(_this.snaps);
447
- var snapUnpacked = SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, 1);
448
- snapUnpacked.items.forEach(function (a, i) {
449
- if (a.type_id == items.OBJ_CLIENT_INFO) {
450
- _this.client_infos[a.id] = a.parsed;
451
- // console.log(a.parsed, i)
452
- // console.log(this.client_infos[a.id])
453
- }
454
- else if (a.type_id == items.OBJ_PLAYER_INFO) {
455
- _this.player_infos[i] = a.parsed;
456
- }
457
- else if (a.type_id == items.OBJ_EX || a.type_id > 0x4000) {
458
- if (a.data.length == 5 && (a.parsed.freeze_end > 0 || a.parsed.freeze_end == -1)) {
459
- // var packer = new MsgPacker(22, false)
460
- // this.SendMsgEx(packer, 1)
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
- if (new Date().getTime() - this.time >= 1000) {
469
- this.time = new Date().getTime();
470
- this.SendControlMsg(0);
471
- }
472
- return [2 /*return*/];
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.close();
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
- 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
- })
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.close();
489
+ if (this.socket)
490
+ this.socket.close();
491
+ this.socket = undefined
483
492
  this.State = -1;
484
493
  })
485
494
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teeworlds",
3
- "version": "2.0.1",
3
+ "version": "2.0.4",
4
4
  "description": "Library for (ingame) teeworlds bots.",
5
5
  "license": "MIT",
6
6
  "main": "index.js",