teeworlds 2.3.7 → 2.3.9

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/README.md CHANGED
@@ -6,7 +6,8 @@ https://www.npmjs.com/package/teeworlds
6
6
 
7
7
  # Usage
8
8
  Example file:
9
- ```const teeworlds = require('teeworlds');
9
+ ```
10
+ const teeworlds = require('teeworlds')
10
11
  let client = new teeworlds.Client("127.0.0.1", 8303, "nameless tee");
11
12
 
12
13
  client.connect();
@@ -16,83 +17,73 @@ client.on("connected", () => {
16
17
  })
17
18
 
18
19
  client.on("disconnect", reason => {
19
- // if you got kicked from the server
20
+ // you got kicked from the server
20
21
  console.log("Disconnected: " + reason);
21
22
  })
22
23
 
23
24
  client.on("message", message => {
24
25
  /* {
25
- team: 0,
26
- client_id: 14,
27
- message: 'a',
28
- author: {
29
- ClientInfo: {
30
- name: 'Nudelsaft c:',
31
- clan: '',
32
- country: 276,
33
- skin: 'coala_toptri',
34
- use_custom_color: 0,
35
- color_body: 4718592,
36
- color_feet: 5046016
37
- },
38
- PlayerInfo: { local: 0, client_id: 4, team: 0, score: 36, latency: 0 }
39
- }
40
- }
26
+ team: 0,
27
+ client_id: 14,
28
+ message: 'a',
29
+ author: {
30
+ ClientInfo: {
31
+ name: 'Nudelsaft c:',
32
+ clan: '',
33
+ country: 276,
34
+ skin: 'coala_toptri',
35
+ use_custom_color: 0,
36
+ color_body: 4718592,
37
+ color_feet: 5046016
38
+ },
39
+ PlayerInfo: { local: 0, client_id: 4, team: 0, score: 36, latency: 0 }
40
+ }
41
+ }
41
42
  */
42
43
  console.log(message);
43
44
  })
44
45
 
45
46
  client.on("kill", info => {
46
47
  /* {
47
- killer_id: 14,
48
- victim_id: 14,
49
- weapon: -3,
50
- special_mode: 0,
51
- victim: {
52
- ClientInfo: {
53
- name: 'Nudelsaft c:',
54
- clan: '',
55
- country: 276,
56
- skin: 'coala_toptri',
57
- use_custom_color: 0,
58
- color_body: 4718592,
59
- color_feet: 5046016
60
- },
61
- PlayerInfo: { local: 0, client_id: 4, team: 0, score: 36, latency: 0 }
62
- },
63
- killer: {
64
- ClientInfo: {
65
- name: 'Nudelsaft c:',
66
- clan: '',
67
- country: 276,
68
- skin: 'coala_toptri',
69
- use_custom_color: 0,
70
- color_body: 4718592,
71
- color_feet: 5046016
72
- },
73
- PlayerInfo: { local: 0, client_id: 4, team: 0, score: 36, latency: 0 }
74
- }
75
- }
48
+ killer_id: 14,
49
+ victim_id: 14,
50
+ weapon: -3,
51
+ special_mode: 0,
52
+ victim: {
53
+ ClientInfo: {
54
+ name: 'Nudelsaft c:',
55
+ clan: '',
56
+ country: 276,
57
+ skin: 'coala_toptri',
58
+ use_custom_color: 0,
59
+ color_body: 4718592,
60
+ color_feet: 5046016
61
+ },
62
+ PlayerInfo: { local: 0, client_id: 4, team: 0, score: 36, latency: 0 }
63
+ },
64
+ killer: {
65
+ ClientInfo: {
66
+ name: 'Nudelsaft c:',
67
+ clan: '',
68
+ country: 276,
69
+ skin: 'coala_toptri',
70
+ use_custom_color: 0,
71
+ color_body: 4718592,
72
+ color_feet: 5046016
73
+ },
74
+ PlayerInfo: { local: 0, client_id: 4, team: 0, score: 36, latency: 0 }
75
+ }
76
+ }
76
77
  */
77
78
  console.log(info)
78
79
  })
79
80
 
80
81
  process.on("SIGINT", () => {
81
- client.Disconnect(); // disconnect on ctrl + c
82
+ client.Disconnect().then(() => process.exit(0)); // disconnect on ctrl + c
83
+ // process.exit()
82
84
  })
83
85
  process.stdin.on("data", data => {
84
86
  client.Say(data.toString()); // write input in chat
85
87
 
86
88
  })
87
-
88
- function change() {
89
- client.ChangePlayerInfo({
90
- name: "new name",
91
- clan: "new clan",
92
- country: 12,
93
- skin: "default",
94
- use_custom_color: true,
95
- color_body: 12,
96
- color_feet: 1111
97
- })
98
- }```
89
+ ```
@@ -3,21 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MsgUnpacker = exports.unpackString = exports.unpackInt = void 0;
4
4
  var decoder = new TextDecoder('utf-8');
5
5
  function unpackInt(pSrc) {
6
- var result = 0;
7
- var iter = pSrc[Symbol.iterator]();
8
- var src = iter.next();
9
- src = src.value;
10
- var sign = ((src >> 6) & 1);
11
- result |= (src & 63);
12
- for (var i = 0; i < 4; i++) {
13
- if ((src & 128) === 0)
6
+ var srcIndex = 0;
7
+ var sign = ((pSrc[srcIndex] >> 6) & 1);
8
+ var result = (pSrc[srcIndex] & 63);
9
+ while (srcIndex <= 4) {
10
+ if ((pSrc[srcIndex] & 128) === 0)
14
11
  break;
15
- src = iter.next();
16
- src = src.value;
17
- result |= ((src & 127)) << (6 + 7 * i);
12
+ srcIndex++;
13
+ result |= ((pSrc[srcIndex] & 127)) << (6 + 7 * (srcIndex - 1));
18
14
  }
19
15
  result ^= -sign;
20
- return { result: result, remaining: Array.from(iter) };
16
+ return { result: result, remaining: pSrc.slice(srcIndex + 1) };
21
17
  }
22
18
  exports.unpackInt = unpackInt;
23
19
  function unpackString(pSrc) {
@@ -1,26 +1,22 @@
1
1
  const decoder = new TextDecoder('utf-8');
2
2
  export function unpackInt(pSrc: number[]): {result: number, remaining: number[]} {
3
- var result = 0;
4
3
 
5
- var iter = pSrc[Symbol.iterator]()
6
- var src: any = iter.next()
7
- src = src.value
8
- var sign = ((src >> 6) & 1)
4
+ var srcIndex = 0;
5
+ const sign = ((pSrc[srcIndex] >> 6) & 1)
9
6
 
10
- result |= (src & 0b0011_1111)
11
- for (let i = 0; i < 4; i++) {
7
+ var result = (pSrc[srcIndex] & 0b0011_1111)
8
+ while (srcIndex <= 4) {
12
9
 
13
- if ((src & 0b1000_0000) === 0)
10
+ if ((pSrc[srcIndex] & 0b1000_0000) === 0)
14
11
  break;
15
- src = iter.next()
16
12
 
17
- src = src.value;
18
- result |= ((src & 0b0111_1111)) << (6+7*i)
13
+ srcIndex++;
14
+ result |= ((pSrc[srcIndex] & 0b0111_1111)) << (6+7*(srcIndex-1))
19
15
 
20
16
  }
21
17
  result ^= -sign;
22
18
 
23
- return {result, remaining: Array.from(iter)};
19
+ return {result, remaining: pSrc.slice(srcIndex+1)};
24
20
  }
25
21
  export function unpackString(pSrc: number[]): {result: string, remaining: number[]} {
26
22
  var result = pSrc.slice(0, pSrc.indexOf(0))
package/lib/client.js CHANGED
@@ -108,6 +108,8 @@ var Client = /** @class */ (function (_super) {
108
108
  _this.name = nickname;
109
109
  _this.AckGameTick = 0;
110
110
  _this.PredGameTick = 0;
111
+ _this.currentSnapshotGameTick = 0;
112
+ _this.SnapshotParts = 0;
111
113
  _this.SnapUnpacker = new snapshot_1.Snapshot();
112
114
  // this.eSnapHolder = [];
113
115
  _this.requestResend = false;
@@ -298,6 +300,7 @@ var Client = /** @class */ (function (_super) {
298
300
  };
299
301
  Client.prototype.connect = function () {
300
302
  var _this = this;
303
+ var _a;
301
304
  this.State = States.STATE_CONNECTING;
302
305
  var predTimer = setInterval(function () {
303
306
  if (_this.State == States.STATE_ONLINE) {
@@ -314,14 +317,16 @@ var Client = /** @class */ (function (_super) {
314
317
  else
315
318
  clearInterval(connectInterval);
316
319
  }, 500);
317
- var inputInterval = setInterval(function () {
318
- if (_this.State == States.STATE_OFFLINE)
319
- clearInterval(inputInterval);
320
- if (_this.State != States.STATE_ONLINE)
321
- return;
322
- _this.time = new Date().getTime();
323
- _this.sendInput();
324
- }, 500);
320
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight)) {
321
+ var inputInterval_1 = setInterval(function () {
322
+ if (_this.State == States.STATE_OFFLINE)
323
+ clearInterval(inputInterval_1);
324
+ if (_this.State != States.STATE_ONLINE)
325
+ return;
326
+ _this.time = new Date().getTime();
327
+ _this.sendInput();
328
+ }, 500);
329
+ }
325
330
  var resendTimeout = setInterval(function () {
326
331
  if (_this.State != States.STATE_OFFLINE) {
327
332
  if (((new Date().getTime()) - _this.lastSendTime) > 900 && _this.sentChunkQueue.length > 0) {
@@ -344,7 +349,7 @@ var Client = /** @class */ (function (_super) {
344
349
  this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
345
350
  if (this.socket)
346
351
  this.socket.on("message", function (a, rinfo) {
347
- var _a, _b, _c, _d, _e, _f, _g;
352
+ var _a, _b, _c, _d, _e, _f, _g, _h;
348
353
  if (_this.State == 0 || rinfo.address != _this.host || rinfo.port != _this.port)
349
354
  return;
350
355
  clearInterval(connectInterval);
@@ -387,6 +392,7 @@ var Client = /** @class */ (function (_super) {
387
392
  _this.lastRecvTime = new Date().getTime();
388
393
  }
389
394
  var unpacked = _this.Unpack(a);
395
+ unpacked.chunks = unpacked.chunks.filter(function (a) { return ((a.flags & 2) && (a.flags & 1)) ? a.seq > _this.ack : true; }); // filter out already received chunks
390
396
  unpacked.chunks.forEach(function (a) {
391
397
  if (a.flags & 1 && (a.flags !== 15)) { // vital and not connless
392
398
  if (a.seq === (_this.ack + 1) % (1 << 10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
@@ -418,46 +424,50 @@ var Client = /** @class */ (function (_super) {
418
424
  _this.sentChunkQueue.splice(i, 1);
419
425
  }
420
426
  });
421
- var snapChunks = unpacked.chunks.filter(function (a) { return a.msg === "SNAP" || a.msg === "SNAP_SINGLE" || a.msg === "SNAP_EMPTY"; });
427
+ var snapChunks = [];
428
+ if (((_g = _this.options) === null || _g === void 0 ? void 0 : _g.lightweight) !== true)
429
+ snapChunks = unpacked.chunks.filter(function (a) { return a.msg === "SNAP" || a.msg === "SNAP_SINGLE" || a.msg === "SNAP_EMPTY"; });
422
430
  if (snapChunks.length > 0) {
423
431
  var part = 0;
424
432
  var num_parts = 1;
433
+ if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
434
+ _this.PredGameTick = _this.AckGameTick + 1;
425
435
  snapChunks.forEach(function (chunk) {
426
436
  var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
427
- var AckGameTick = unpacker.unpackInt();
428
- var DeltaTick = AckGameTick - unpacker.unpackInt();
429
- if (AckGameTick >= _this.AckGameTick) {
430
- if (_this.AckGameTick == -1) { // reset ack
431
- if (DeltaTick == -1) { // acked reset
432
- _this.AckGameTick = AckGameTick;
433
- }
434
- }
435
- else
436
- _this.AckGameTick = AckGameTick;
437
- if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
438
- _this.PredGameTick = AckGameTick + 1;
439
- var num_parts_1 = 1;
440
- var part_1 = 0;
441
- if (chunk.msg === "SNAP") {
442
- num_parts_1 = unpacker.unpackInt();
443
- part_1 = unpacker.unpackInt();
444
- }
445
- var crc = 0;
446
- var part_size = 0;
447
- if (chunk.msg != "SNAP_EMPTY") {
448
- crc = unpacker.unpackInt(); // crc
449
- part_size = unpacker.unpackInt();
450
- }
451
- if (part_1 === 0 || _this.snaps.length > 30) {
437
+ var NumParts = 1;
438
+ var Part = 0;
439
+ var GameTick = unpacker.unpackInt();
440
+ var DeltaTick = GameTick - unpacker.unpackInt();
441
+ var PartSize = 0;
442
+ var Crc = 0;
443
+ var CompleteSize = 0;
444
+ if (chunk.msg == "SNAP") {
445
+ NumParts = unpacker.unpackInt();
446
+ Part = unpacker.unpackInt();
447
+ }
448
+ if (chunk.msg != "SNAP_EMPTY") {
449
+ Crc = unpacker.unpackInt();
450
+ PartSize = unpacker.unpackInt();
451
+ }
452
+ if (PartSize < 1 || NumParts > 64 || Part < 0 || Part >= NumParts || PartSize <= 0 || PartSize > 900)
453
+ return;
454
+ if (GameTick >= _this.currentSnapshotGameTick) {
455
+ if (GameTick != _this.currentSnapshotGameTick) {
452
456
  _this.snaps = [];
457
+ _this.SnapshotParts = 0;
458
+ _this.currentSnapshotGameTick = GameTick;
453
459
  }
454
- chunk.raw = Buffer.from(unpacker.remaining);
455
- _this.snaps.push(chunk.raw);
456
- if ((num_parts_1 - 1) === part_1 && _this.snaps.length === num_parts_1) {
460
+ // chunk.raw = Buffer.from(unpacker.remaining);
461
+ _this.snaps[Part] = Buffer.from(unpacker.remaining);
462
+ _this.SnapshotParts |= 1 << Part;
463
+ if (_this.SnapshotParts == ((1 << NumParts) - 1)) {
457
464
  var mergedSnaps = Buffer.concat(_this.snaps);
458
- var snapUnpacked = _this.SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, DeltaTick, AckGameTick);
459
- _this.AckGameTick = snapUnpacked.recvTick;
465
+ _this.SnapshotParts = 0;
466
+ var snapUnpacked = _this.SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, DeltaTick, GameTick);
460
467
  _this.emit("snapshot");
468
+ _this.AckGameTick = snapUnpacked.recvTick;
469
+ if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
470
+ _this.PredGameTick = _this.AckGameTick + 1;
461
471
  _this.sendInput();
462
472
  }
463
473
  }
@@ -517,7 +527,7 @@ var Client = /** @class */ (function (_super) {
517
527
  }
518
528
  else if ((unpacked.chunks[0] && chunkMessages.includes("CON_READY"))) {
519
529
  var info = new MsgPacker_1.MsgPacker(20, false, 1);
520
- if ((_g = _this.options) === null || _g === void 0 ? void 0 : _g.identity) {
530
+ if ((_h = _this.options) === null || _h === void 0 ? void 0 : _h.identity) {
521
531
  info.AddString(_this.options.identity.name);
522
532
  info.AddString(_this.options.identity.clan);
523
533
  info.AddInt(_this.options.identity.country);
@@ -602,18 +612,27 @@ var Client = /** @class */ (function (_super) {
602
612
  });
603
613
  };
604
614
  Client.prototype.Say = function (message, team) {
615
+ var _a;
605
616
  if (team === void 0) { team = false; }
606
617
  var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_SAY, false, 1);
607
618
  packer.AddInt(team ? 1 : 0); // team
608
619
  packer.AddString(message);
609
- this.QueueChunkEx(packer);
620
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
621
+ this.QueueChunkEx(packer);
622
+ else
623
+ this.SendMsgEx(packer);
610
624
  };
611
625
  Client.prototype.Vote = function (vote) {
626
+ var _a;
612
627
  var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_VOTE, false, 1);
613
628
  packer.AddInt(vote ? 1 : -1);
614
- this.QueueChunkEx(packer);
629
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
630
+ this.QueueChunkEx(packer);
631
+ else
632
+ this.SendMsgEx(packer);
615
633
  };
616
634
  Client.prototype.ChangePlayerInfo = function (playerInfo) {
635
+ var _a;
617
636
  var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_CHANGEINFO, false, 1);
618
637
  packer.AddString(playerInfo.name); //m_pName);
619
638
  packer.AddString(playerInfo.clan); //m_pClan);
@@ -622,21 +641,36 @@ var Client = /** @class */ (function (_super) {
622
641
  packer.AddInt(playerInfo.use_custom_color ? 1 : 0); //m_UseCustomColor);
623
642
  packer.AddInt(playerInfo.color_body); //m_ColorBody);
624
643
  packer.AddInt(playerInfo.color_feet); //m_ColorFeet);
625
- this.QueueChunkEx(packer);
644
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
645
+ this.QueueChunkEx(packer);
646
+ else
647
+ this.SendMsgEx(packer);
626
648
  };
627
649
  Client.prototype.Kill = function () {
650
+ var _a;
628
651
  var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_KILL, false, 1);
629
- this.QueueChunkEx(packer);
652
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
653
+ this.QueueChunkEx(packer);
654
+ else
655
+ this.SendMsgEx(packer);
630
656
  };
631
657
  Client.prototype.ChangeTeam = function (team) {
658
+ var _a;
632
659
  var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_SETTEAM, false, 1);
633
660
  packer.AddInt(team);
634
- this.QueueChunkEx(packer);
661
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
662
+ this.QueueChunkEx(packer);
663
+ else
664
+ this.SendMsgEx(packer);
635
665
  };
636
666
  Client.prototype.Emote = function (emote) {
667
+ var _a;
637
668
  var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_EMOTICON, false, 1);
638
669
  packer.AddInt(emote);
639
- this.QueueChunkEx(packer);
670
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
671
+ this.QueueChunkEx(packer);
672
+ else
673
+ this.SendMsgEx(packer);
640
674
  };
641
675
  Client.prototype.client_info = function (id) {
642
676
  var delta = this.SnapUnpacker.deltas.filter(function (a) {
package/lib/client.ts CHANGED
@@ -141,7 +141,8 @@ declare interface iOptions {
141
141
  password?: string,
142
142
  ddnet_version?: {version: number, release_version: string},
143
143
  timeout?: number, // in ms
144
- NET_VERSION?: string
144
+ NET_VERSION?: string,
145
+ lightweight?: boolean // experimental, only sends keepalive's (sendinput has to be called manually)
145
146
  }
146
147
 
147
148
  export declare interface Client {
@@ -161,6 +162,9 @@ export declare interface Client {
161
162
  timer: number;
162
163
  PredGameTick: number;
163
164
  AckGameTick: number;
165
+
166
+ SnapshotParts: number;
167
+ currentSnapshotGameTick: number;
164
168
 
165
169
  movement: Movement;
166
170
 
@@ -202,6 +206,10 @@ export class Client extends EventEmitter {
202
206
  this.name = nickname;
203
207
  this.AckGameTick = 0;
204
208
  this.PredGameTick = 0;
209
+ this.currentSnapshotGameTick = 0;
210
+
211
+ this.SnapshotParts = 0;
212
+
205
213
  this.SnapUnpacker = new Snapshot();
206
214
  // this.eSnapHolder = [];
207
215
  this.requestResend = false;
@@ -434,15 +442,16 @@ export class Client extends EventEmitter {
434
442
  else
435
443
  clearInterval(connectInterval)
436
444
  }, 500);
437
-
438
- let inputInterval = setInterval(() => {
439
- if (this.State == States.STATE_OFFLINE)
440
- clearInterval(inputInterval)
441
- if (this.State != States.STATE_ONLINE)
442
- return;
443
- this.time = new Date().getTime();
444
- this.sendInput();
445
- }, 500)
445
+ if (!this.options?.lightweight) {
446
+ let inputInterval = setInterval(() => {
447
+ if (this.State == States.STATE_OFFLINE)
448
+ clearInterval(inputInterval)
449
+ if (this.State != States.STATE_ONLINE)
450
+ return;
451
+ this.time = new Date().getTime();
452
+ this.sendInput();
453
+ }, 500)
454
+ }
446
455
 
447
456
  let resendTimeout = setInterval(() => {
448
457
  if (this.State != States.STATE_OFFLINE) {
@@ -514,6 +523,8 @@ export class Client extends EventEmitter {
514
523
 
515
524
 
516
525
  var unpacked: _packet = this.Unpack(a);
526
+ unpacked.chunks = unpacked.chunks.filter(a => ((a.flags & 2) && (a.flags & 1)) ? a.seq! > this.ack : true); // filter out already received chunks
527
+
517
528
  unpacked.chunks.forEach(a => {
518
529
  if (a.flags & 1 && (a.flags !== 15)) { // vital and not connless
519
530
  if (a.seq === (this.ack+1)%(1<<10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
@@ -549,59 +560,69 @@ export class Client extends EventEmitter {
549
560
  this.sentChunkQueue.splice(i, 1);
550
561
  }
551
562
  })
552
- var snapChunks = unpacked.chunks.filter(a => a.msg === "SNAP" || a.msg === "SNAP_SINGLE" || a.msg === "SNAP_EMPTY");
563
+ let snapChunks: chunk[] = [];
564
+ if (this.options?.lightweight !== true)
565
+ snapChunks = unpacked.chunks.filter(a => a.msg === "SNAP" || a.msg === "SNAP_SINGLE" || a.msg === "SNAP_EMPTY");
553
566
  if (snapChunks.length > 0) {
554
567
  let part = 0;
555
568
  let num_parts = 1;
569
+ if (Math.abs(this.PredGameTick - this.AckGameTick) > 10)
570
+ this.PredGameTick = this.AckGameTick + 1;
571
+
556
572
  snapChunks.forEach(chunk => {
557
573
  let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
558
574
 
559
- let AckGameTick = unpacker.unpackInt();
560
-
561
- let DeltaTick = AckGameTick - unpacker.unpackInt();
562
- if (AckGameTick >= this.AckGameTick) {
563
- if (this.AckGameTick == -1) {// reset ack
564
- if (DeltaTick == -1) {// acked reset
565
- this.AckGameTick = AckGameTick;
566
- }
567
- } else
568
- this.AckGameTick = AckGameTick;
569
- if (Math.abs(this.PredGameTick - this.AckGameTick) > 10)
570
- this.PredGameTick = AckGameTick + 1;
571
-
572
- let num_parts = 1;
573
- let part = 0;
575
+ let NumParts = 1;
576
+ let Part = 0;
577
+ let GameTick = unpacker.unpackInt();
578
+ let DeltaTick = GameTick - unpacker.unpackInt();
579
+ let PartSize = 0;
580
+ let Crc = 0;
581
+ let CompleteSize = 0;
582
+
583
+ if (chunk.msg == "SNAP") {
584
+ NumParts = unpacker.unpackInt();
585
+ Part = unpacker.unpackInt();
586
+ }
574
587
 
575
- if (chunk.msg === "SNAP") {
576
- num_parts = unpacker.unpackInt();
577
- part = unpacker.unpackInt();
578
- }
579
-
580
- let crc = 0;
581
- let part_size = 0;
582
588
  if (chunk.msg != "SNAP_EMPTY") {
583
- crc = unpacker.unpackInt(); // crc
584
- part_size = unpacker.unpackInt();
589
+ Crc = unpacker.unpackInt();
590
+ PartSize = unpacker.unpackInt();
585
591
  }
586
- if (part === 0 || this.snaps.length > 30) {
587
- this.snaps = [];
588
- }
589
- chunk.raw = Buffer.from(unpacker.remaining);
590
- this.snaps.push(chunk.raw)
591
-
592
- if ((num_parts - 1) === part && this.snaps.length === num_parts) {
593
592
 
594
- let mergedSnaps = Buffer.concat(this.snaps);
593
+ if (PartSize < 1 || NumParts > 64 || Part < 0 || Part >= NumParts || PartSize <= 0 || PartSize > 900)
594
+ return;
595
595
 
596
- let snapUnpacked = this.SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, DeltaTick, AckGameTick);
597
- this.AckGameTick = snapUnpacked.recvTick;
598
-
599
- this.emit("snapshot");
596
+ if (GameTick >= this.currentSnapshotGameTick) {
597
+ if (GameTick != this.currentSnapshotGameTick) {
598
+ this.snaps = [];
599
+ this.SnapshotParts = 0;
600
+ this.currentSnapshotGameTick = GameTick;
601
+ }
602
+
603
+ // chunk.raw = Buffer.from(unpacker.remaining);
604
+ this.snaps[Part] = Buffer.from(unpacker.remaining);
605
+
606
+ this.SnapshotParts |= 1 << Part;
600
607
 
601
- this.sendInput();
602
- }
608
+ if (this.SnapshotParts == ((1 << NumParts) - 1)) {
609
+ let mergedSnaps = Buffer.concat(this.snaps);
610
+ this.SnapshotParts = 0;
603
611
 
604
- }
612
+ let snapUnpacked = this.SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, DeltaTick, GameTick);
613
+
614
+ this.emit("snapshot");
615
+ this.AckGameTick = snapUnpacked.recvTick;
616
+ if (Math.abs(this.PredGameTick - this.AckGameTick) > 10)
617
+ this.PredGameTick = this.AckGameTick + 1;
618
+
619
+ this.sendInput();
620
+ }
621
+
622
+
623
+ }
624
+
625
+
605
626
  })
606
627
  }
607
628
  var chunkMessages = unpacked.chunks.map(a => a.msg)
@@ -749,12 +770,18 @@ export class Client extends EventEmitter {
749
770
  var packer = new MsgPacker(NETMSGTYPE.CL_SAY, false, 1);
750
771
  packer.AddInt(team ? 1 : 0); // team
751
772
  packer.AddString(message);
752
- this.QueueChunkEx(packer);
773
+ if (!this.options?.lightweight)
774
+ this.QueueChunkEx(packer);
775
+ else
776
+ this.SendMsgEx(packer);
753
777
  }
754
778
  Vote(vote: boolean) {
755
779
  var packer = new MsgPacker(NETMSGTYPE.CL_VOTE, false, 1);
756
780
  packer.AddInt(vote ? 1 : -1);
757
- this.QueueChunkEx(packer);
781
+ if (!this.options?.lightweight)
782
+ this.QueueChunkEx(packer);
783
+ else
784
+ this.SendMsgEx(packer);
758
785
  }
759
786
  ChangePlayerInfo(playerInfo: ClientInfo) {
760
787
  var packer = new MsgPacker(NETMSGTYPE.CL_CHANGEINFO, false, 1);
@@ -765,21 +792,33 @@ export class Client extends EventEmitter {
765
792
  packer.AddInt(playerInfo.use_custom_color ? 1 : 0); //m_UseCustomColor);
766
793
  packer.AddInt(playerInfo.color_body); //m_ColorBody);
767
794
  packer.AddInt(playerInfo.color_feet); //m_ColorFeet);
768
- this.QueueChunkEx(packer);
795
+ if (!this.options?.lightweight)
796
+ this.QueueChunkEx(packer);
797
+ else
798
+ this.SendMsgEx(packer);
769
799
  }
770
800
  Kill() {
771
801
  var packer = new MsgPacker(NETMSGTYPE.CL_KILL, false, 1);
772
- this.QueueChunkEx(packer);
802
+ if (!this.options?.lightweight)
803
+ this.QueueChunkEx(packer);
804
+ else
805
+ this.SendMsgEx(packer);
773
806
  }
774
807
  ChangeTeam(team: number) {
775
808
  var packer = new MsgPacker(NETMSGTYPE.CL_SETTEAM, false, 1);
776
809
  packer.AddInt(team);
777
- this.QueueChunkEx(packer);
810
+ if (!this.options?.lightweight)
811
+ this.QueueChunkEx(packer);
812
+ else
813
+ this.SendMsgEx(packer);
778
814
  }
779
815
  Emote(emote: number) {
780
816
  var packer = new MsgPacker(NETMSGTYPE.CL_EMOTICON, false, 1);
781
817
  packer.AddInt(emote);
782
- this.QueueChunkEx(packer);
818
+ if (!this.options?.lightweight)
819
+ this.QueueChunkEx(packer);
820
+ else
821
+ this.SendMsgEx(packer);
783
822
  }
784
823
  client_info(id: number) {
785
824
  let delta = this.SnapUnpacker.deltas.filter(a =>
package/lib/snapshot.js CHANGED
@@ -57,20 +57,20 @@ var Snapshot = /** @class */ (function () {
57
57
  }
58
58
  Snapshot.prototype.IntsToStr = function (pInts) {
59
59
  var pIntz = [];
60
- var pStr = '';
60
+ // var pStr = ''
61
61
  for (var _i = 0, pInts_1 = pInts; _i < pInts_1.length; _i++) {
62
62
  var x = pInts_1[_i];
63
- pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
63
+ // pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
64
64
  pIntz.push((((x) >> 24) & 0xff) - 128);
65
- pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
65
+ // pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
66
66
  pIntz.push((((x) >> 16) & 0xff) - 128);
67
- pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
67
+ // pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
68
68
  pIntz.push((((x) >> 8) & 0xff) - 128);
69
- pStr += String.fromCharCode(((x) & 0xff) - 128);
69
+ // pStr += String.fromCharCode(((x) & 0xff) - 128);
70
70
  pIntz.push(((x) & 0xff) - 128);
71
71
  }
72
72
  pIntz.splice(-1, 1);
73
- pStr = decoder.decode(new Uint8Array(pIntz));
73
+ var pStr = decoder.decode(new Uint8Array(pIntz));
74
74
  pStr = pStr.replace(/\0.*/g, ''); // Remove content from first null char to end.
75
75
  return pStr;
76
76
  };
@@ -302,8 +302,9 @@ var Snapshot = /** @class */ (function () {
302
302
  }
303
303
  if (snap.length == 0) {
304
304
  // empty snap, copy old one into new ack
305
- this.eSnapHolder.filter(function (a) { return a.ack == deltatick; }).forEach(function (snap) {
306
- _this.eSnapHolder.push({ Snapshot: snap.Snapshot, ack: recvTick });
305
+ this.eSnapHolder.forEach(function (snap) {
306
+ if (snap.ack == deltatick)
307
+ _this.eSnapHolder.push({ Snapshot: snap.Snapshot, ack: recvTick });
307
308
  });
308
309
  return { items: [], recvTick: recvTick };
309
310
  }
@@ -316,15 +317,6 @@ var Snapshot = /** @class */ (function () {
316
317
  var num_removed_items = unpacker.unpackInt();
317
318
  var num_item_deltas = unpacker.unpackInt();
318
319
  unpacker.unpackInt(); // _zero padding
319
- var _loop_1 = function (i) {
320
- var deleted_key = unpacker.unpackInt(); // removed_item_keys
321
- var index = this_1.deltas.map(function (delta) { return delta.key; }).indexOf(deleted_key);
322
- // console.log("deleting ", deleted_key, index)
323
- if (index > -1)
324
- this_1.deltas.splice(index, 1);
325
- this_1.eSnapHolder = this_1.eSnapHolder.filter(function (a) { return a.Snapshot.Key !== deleted_key; });
326
- };
327
- var this_1 = this;
328
320
  /*snapshot_delta:
329
321
  [ 4] num_removed_items
330
322
  [ 4] num_item_deltas
@@ -332,9 +324,22 @@ var Snapshot = /** @class */ (function () {
332
324
  [*4] removed_item_keys
333
325
  [ ] item_deltas
334
326
  */
327
+ var deleted = [];
328
+ var _loop_1 = function (i) {
329
+ var deleted_key = unpacker.unpackInt(); // removed_item_keys
330
+ // let index = this.deltas.map(delta => delta.key).indexOf(deleted_key);
331
+ var index = this_1.deltas.findIndex(function (delta) { return delta.key === deleted_key; });
332
+ // console.log("deleting ", deleted_key, index)
333
+ if (index > -1)
334
+ this_1.deltas.splice(index, 1);
335
+ deleted.push(deleted_key);
336
+ };
337
+ var this_1 = this;
335
338
  for (var i = 0; i < num_removed_items; i++) {
336
339
  _loop_1(i);
337
340
  }
341
+ if (deleted.length)
342
+ this.eSnapHolder = this.eSnapHolder.filter(function (a) { return !deleted.includes(a.Snapshot.Key); });
338
343
  /*item_delta:
339
344
  [ 4] type_id
340
345
  [ 4] id
@@ -350,7 +355,7 @@ var Snapshot = /** @class */ (function () {
350
355
  deltaSnaps.forEach(function (a) {
351
356
  newSnaps.push({ Snapshot: a.Snapshot, ack: recvTick });
352
357
  });
353
- for (var i = 0; i < num_item_deltas; i++) {
358
+ var _loop_2 = function (i) {
354
359
  var type_id = unpacker.unpackInt();
355
360
  var id = unpacker.unpackInt();
356
361
  var key = (((type_id) << 16) | (id));
@@ -369,31 +374,38 @@ var Snapshot = /** @class */ (function () {
369
374
  }
370
375
  // console.log(index, deltatick)
371
376
  if (deltatick >= 0) {
372
- var index = deltaSnaps.map(function (delta) { return delta.Snapshot.Key; }).indexOf(key);
377
+ // let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
378
+ var index = deltaSnaps.findIndex(function (delta) { return delta.Snapshot.Key === key; });
373
379
  if (index > -1) {
374
380
  var out = UndiffItem(deltaSnaps[index].Snapshot.Data, data);
375
381
  data = out;
376
382
  } // else no previous, use new data
377
383
  }
378
- var parsed = this.parseItem(data, type_id);
379
- this.eSnapHolder.push({ Snapshot: { Data: data, Key: key }, ack: recvTick });
384
+ var parsed = this_2.parseItem(data, type_id);
385
+ this_2.eSnapHolder.push({ Snapshot: { Data: data, Key: key }, ack: recvTick });
380
386
  items.items.push({ data: data, parsed: parsed, type_id: type_id, id: id, key: key });
387
+ };
388
+ var this_2 = this;
389
+ for (var i = 0; i < num_item_deltas; i++) {
390
+ _loop_2(i);
381
391
  }
382
- var _loop_2 = function (newSnap) {
383
- if (this_2.eSnapHolder.filter(function (a) { return a.ack == newSnap.ack && a.Snapshot.Key == newSnap.Snapshot.Key; }).length === 0) { // ugly copy new snap to eSnapHolder (if it isnt pushed already)
384
- this_2.eSnapHolder.push({ Snapshot: { Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key }, ack: recvTick });
385
- }
386
- var ____index = this_2.deltas.map(function (delta) { return delta.key; }).indexOf(newSnap.Snapshot.Key);
387
- if (____index > -1 && deltatick > -1) {
388
- this_2.deltas[____index] = { data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this_2.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff)) };
392
+ var _loop_3 = function (newSnap) {
393
+ if (this_3.eSnapHolder.findIndex(function (a) { return a.ack == newSnap.ack && a.Snapshot.Key == newSnap.Snapshot.Key; }) === -1) { // ugly copy new snap to eSnapHolder (if it isnt pushed already)
394
+ this_3.eSnapHolder.push({ Snapshot: { Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key }, ack: recvTick });
389
395
  }
390
- else
391
- this_2.deltas.push({ data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this_2.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff)) });
396
+ if (deltatick > -1) {
397
+ var ____index = this_3.deltas.findIndex(function (delta) { return delta.key == newSnap.Snapshot.Key; });
398
+ if (____index > -1) {
399
+ this_3.deltas[____index] = { data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this_3.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff)) };
400
+ return "continue";
401
+ }
402
+ } // else
403
+ this_3.deltas.push({ data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this_3.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff)) });
392
404
  };
393
- var this_2 = this;
405
+ var this_3 = this;
394
406
  for (var _i = 0, newSnaps_1 = newSnaps; _i < newSnaps_1.length; _i++) {
395
407
  var newSnap = newSnaps_1[_i];
396
- _loop_2(newSnap);
408
+ _loop_3(newSnap);
397
409
  }
398
410
  return { items: items, recvTick: recvTick };
399
411
  };
package/lib/snapshot.ts CHANGED
@@ -60,19 +60,19 @@ export class Snapshot {
60
60
 
61
61
  private IntsToStr(pInts: number[]): string {
62
62
  var pIntz: number[] = [];
63
- var pStr = ''
63
+ // var pStr = ''
64
64
  for (let x of pInts) {
65
- pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
65
+ // pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
66
66
  pIntz.push((((x) >> 24) & 0xff) - 128);
67
- pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
67
+ // pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
68
68
  pIntz.push((((x) >> 16) & 0xff) - 128);
69
- pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
69
+ // pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
70
70
  pIntz.push((((x) >> 8) & 0xff) - 128);
71
- pStr += String.fromCharCode(((x) & 0xff) - 128);
71
+ // pStr += String.fromCharCode(((x) & 0xff) - 128);
72
72
  pIntz.push(((x) & 0xff) - 128);
73
73
  }
74
74
  pIntz.splice(-1, 1)
75
- pStr = decoder.decode(new Uint8Array(pIntz));
75
+ let pStr = decoder.decode(new Uint8Array(pIntz));
76
76
 
77
77
  pStr = pStr.replace(/\0.*/g, ''); // Remove content from first null char to end.
78
78
  return pStr;
@@ -306,7 +306,8 @@ export class Snapshot {
306
306
  }
307
307
  if (snap.length == 0) {
308
308
  // empty snap, copy old one into new ack
309
- this.eSnapHolder.filter(a => a.ack == deltatick).forEach(snap => {
309
+ this.eSnapHolder.forEach(snap => {
310
+ if (snap.ack == deltatick)
310
311
  this.eSnapHolder.push({Snapshot: snap.Snapshot, ack: recvTick});
311
312
 
312
313
  })
@@ -330,14 +331,19 @@ export class Snapshot {
330
331
  [ ] item_deltas
331
332
  */
332
333
 
334
+ var deleted: number[] = [];
333
335
  for (let i = 0; i < num_removed_items; i++) {
334
336
  let deleted_key = unpacker.unpackInt(); // removed_item_keys
335
- let index = this.deltas.map(delta => delta.key).indexOf(deleted_key);
337
+ // let index = this.deltas.map(delta => delta.key).indexOf(deleted_key);
338
+ let index = this.deltas.findIndex(delta => delta.key === deleted_key);
336
339
  // console.log("deleting ", deleted_key, index)
337
340
  if (index > -1)
338
341
  this.deltas.splice(index, 1);
339
- this.eSnapHolder = this.eSnapHolder.filter(a => a.Snapshot.Key !== deleted_key);
342
+ deleted.push(deleted_key)
340
343
  }
344
+ if (deleted.length)
345
+ this.eSnapHolder = this.eSnapHolder.filter(a => !deleted.includes(a.Snapshot.Key));
346
+
341
347
  /*item_delta:
342
348
  [ 4] type_id
343
349
  [ 4] id
@@ -378,7 +384,8 @@ export class Snapshot {
378
384
  }
379
385
  // console.log(index, deltatick)
380
386
  if (deltatick >= 0) {
381
- let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
387
+ // let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
388
+ let index = deltaSnaps.findIndex(delta => delta.Snapshot.Key === key);
382
389
  if (index > -1) {
383
390
 
384
391
  let out = UndiffItem(deltaSnaps[index].Snapshot.Data, data)
@@ -395,21 +402,25 @@ export class Snapshot {
395
402
 
396
403
  }
397
404
  for (let newSnap of newSnaps) {
398
- if (this.eSnapHolder.filter(a => a.ack == newSnap.ack && a.Snapshot.Key == newSnap.Snapshot.Key).length === 0) { // ugly copy new snap to eSnapHolder (if it isnt pushed already)
405
+ if (this.eSnapHolder.findIndex(a => a.ack == newSnap.ack && a.Snapshot.Key == newSnap.Snapshot.Key) === -1) { // ugly copy new snap to eSnapHolder (if it isnt pushed already)
399
406
  this.eSnapHolder.push({Snapshot: {Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key}, ack: recvTick});
400
407
  }
401
- let ____index = this.deltas.map(delta => delta.key).indexOf(newSnap.Snapshot.Key);
402
-
403
- if (____index > -1 && deltatick > -1) {
404
- this.deltas[____index] = {data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff))};
405
- } else
406
- this.deltas.push({data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff))});
408
+ if (deltatick > -1) {
409
+ let ____index = this.deltas.findIndex(delta => delta.key == newSnap.Snapshot.Key)
410
+
411
+ if (____index > -1) {
412
+ this.deltas[____index] = {data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff))};
413
+ continue;
414
+ }
415
+ } // else
416
+ this.deltas.push({data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff))});
407
417
  }
408
418
 
409
419
 
410
420
  return {items, recvTick};
411
421
  }
412
422
  }
423
+
413
424
  function UndiffItem(oldItem: number[], newItem: number[]): number[] {
414
425
  let out: number[] = newItem;
415
426
  if (JSON.stringify(newItem) === JSON.stringify(oldItem))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teeworlds",
3
- "version": "2.3.7",
3
+ "version": "2.3.9",
4
4
  "description": "Library for (ingame) teeworlds bots.",
5
5
  "license": "MIT",
6
6
  "main": "index.js",