teeworlds 2.3.9 → 2.4.1

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 CHANGED
@@ -25,6 +25,7 @@ var movement_1 = __importDefault(require("./movement"));
25
25
  var MsgPacker_1 = require("./MsgPacker");
26
26
  var snapshot_1 = require("./snapshot");
27
27
  var huffman_1 = __importDefault(require("./huffman"));
28
+ var game_1 = require("./components/game");
28
29
  var huff = new huffman_1.default();
29
30
  var States;
30
31
  (function (States) {
@@ -36,42 +37,79 @@ var States;
36
37
  States[States["STATE_QUITTING"] = 5] = "STATE_QUITTING";
37
38
  States[States["STATE_RESTARTING"] = 6] = "STATE_RESTARTING";
38
39
  })(States || (States = {}));
39
- var NETMSGTYPE;
40
- (function (NETMSGTYPE) {
41
- NETMSGTYPE[NETMSGTYPE["EX"] = 0] = "EX";
42
- NETMSGTYPE[NETMSGTYPE["SV_MOTD"] = 1] = "SV_MOTD";
43
- NETMSGTYPE[NETMSGTYPE["SV_BROADCAST"] = 2] = "SV_BROADCAST";
44
- NETMSGTYPE[NETMSGTYPE["SV_CHAT"] = 3] = "SV_CHAT";
45
- NETMSGTYPE[NETMSGTYPE["SV_KILLMSG"] = 4] = "SV_KILLMSG";
46
- NETMSGTYPE[NETMSGTYPE["SV_SOUNDGLOBAL"] = 5] = "SV_SOUNDGLOBAL";
47
- NETMSGTYPE[NETMSGTYPE["SV_TUNEPARAMS"] = 6] = "SV_TUNEPARAMS";
48
- NETMSGTYPE[NETMSGTYPE["SV_EXTRAPROJECTILE"] = 7] = "SV_EXTRAPROJECTILE";
49
- NETMSGTYPE[NETMSGTYPE["SV_READYTOENTER"] = 8] = "SV_READYTOENTER";
50
- NETMSGTYPE[NETMSGTYPE["SV_WEAPONPICKUP"] = 9] = "SV_WEAPONPICKUP";
51
- NETMSGTYPE[NETMSGTYPE["SV_EMOTICON"] = 10] = "SV_EMOTICON";
52
- NETMSGTYPE[NETMSGTYPE["SV_VOTECLEAROPTIONS"] = 11] = "SV_VOTECLEAROPTIONS";
53
- NETMSGTYPE[NETMSGTYPE["SV_VOTEOPTIONLISTADD"] = 12] = "SV_VOTEOPTIONLISTADD";
54
- NETMSGTYPE[NETMSGTYPE["SV_VOTEOPTIONADD"] = 13] = "SV_VOTEOPTIONADD";
55
- NETMSGTYPE[NETMSGTYPE["SV_VOTEOPTIONREMOVE"] = 14] = "SV_VOTEOPTIONREMOVE";
56
- NETMSGTYPE[NETMSGTYPE["SV_VOTESET"] = 15] = "SV_VOTESET";
57
- NETMSGTYPE[NETMSGTYPE["SV_VOTESTATUS"] = 16] = "SV_VOTESTATUS";
58
- NETMSGTYPE[NETMSGTYPE["CL_SAY"] = 17] = "CL_SAY";
59
- NETMSGTYPE[NETMSGTYPE["CL_SETTEAM"] = 18] = "CL_SETTEAM";
60
- NETMSGTYPE[NETMSGTYPE["CL_SETSPECTATORMODE"] = 19] = "CL_SETSPECTATORMODE";
61
- NETMSGTYPE[NETMSGTYPE["CL_STARTINFO"] = 20] = "CL_STARTINFO";
62
- NETMSGTYPE[NETMSGTYPE["CL_CHANGEINFO"] = 21] = "CL_CHANGEINFO";
63
- NETMSGTYPE[NETMSGTYPE["CL_KILL"] = 22] = "CL_KILL";
64
- NETMSGTYPE[NETMSGTYPE["CL_EMOTICON"] = 23] = "CL_EMOTICON";
65
- NETMSGTYPE[NETMSGTYPE["CL_VOTE"] = 24] = "CL_VOTE";
66
- NETMSGTYPE[NETMSGTYPE["CL_CALLVOTE"] = 25] = "CL_CALLVOTE";
67
- NETMSGTYPE[NETMSGTYPE["CL_ISDDNETLEGACY"] = 26] = "CL_ISDDNETLEGACY";
68
- NETMSGTYPE[NETMSGTYPE["SV_DDRACETIMELEGACY"] = 27] = "SV_DDRACETIMELEGACY";
69
- NETMSGTYPE[NETMSGTYPE["SV_RECORDLEGACY"] = 28] = "SV_RECORDLEGACY";
70
- NETMSGTYPE[NETMSGTYPE["UNUSED"] = 29] = "UNUSED";
71
- NETMSGTYPE[NETMSGTYPE["SV_TEAMSSTATELEGACY"] = 30] = "SV_TEAMSSTATELEGACY";
72
- NETMSGTYPE[NETMSGTYPE["CL_SHOWOTHERSLEGACY"] = 31] = "CL_SHOWOTHERSLEGACY";
73
- NETMSGTYPE[NETMSGTYPE["NUM"] = 32] = "NUM";
74
- })(NETMSGTYPE || (NETMSGTYPE = {}));
40
+ var NETMSG_Game;
41
+ (function (NETMSG_Game) {
42
+ NETMSG_Game[NETMSG_Game["EX"] = 0] = "EX";
43
+ NETMSG_Game[NETMSG_Game["SV_MOTD"] = 1] = "SV_MOTD";
44
+ NETMSG_Game[NETMSG_Game["SV_BROADCAST"] = 2] = "SV_BROADCAST";
45
+ NETMSG_Game[NETMSG_Game["SV_CHAT"] = 3] = "SV_CHAT";
46
+ NETMSG_Game[NETMSG_Game["SV_KILLMSG"] = 4] = "SV_KILLMSG";
47
+ NETMSG_Game[NETMSG_Game["SV_SOUNDGLOBAL"] = 5] = "SV_SOUNDGLOBAL";
48
+ NETMSG_Game[NETMSG_Game["SV_TUNEPARAMS"] = 6] = "SV_TUNEPARAMS";
49
+ NETMSG_Game[NETMSG_Game["SV_EXTRAPROJECTILE"] = 7] = "SV_EXTRAPROJECTILE";
50
+ NETMSG_Game[NETMSG_Game["SV_READYTOENTER"] = 8] = "SV_READYTOENTER";
51
+ NETMSG_Game[NETMSG_Game["SV_WEAPONPICKUP"] = 9] = "SV_WEAPONPICKUP";
52
+ NETMSG_Game[NETMSG_Game["SV_EMOTICON"] = 10] = "SV_EMOTICON";
53
+ NETMSG_Game[NETMSG_Game["SV_VOTECLEAROPTIONS"] = 11] = "SV_VOTECLEAROPTIONS";
54
+ NETMSG_Game[NETMSG_Game["SV_VOTEOPTIONLISTADD"] = 12] = "SV_VOTEOPTIONLISTADD";
55
+ NETMSG_Game[NETMSG_Game["SV_VOTEOPTIONADD"] = 13] = "SV_VOTEOPTIONADD";
56
+ NETMSG_Game[NETMSG_Game["SV_VOTEOPTIONREMOVE"] = 14] = "SV_VOTEOPTIONREMOVE";
57
+ NETMSG_Game[NETMSG_Game["SV_VOTESET"] = 15] = "SV_VOTESET";
58
+ NETMSG_Game[NETMSG_Game["SV_VOTESTATUS"] = 16] = "SV_VOTESTATUS";
59
+ NETMSG_Game[NETMSG_Game["CL_SAY"] = 17] = "CL_SAY";
60
+ NETMSG_Game[NETMSG_Game["CL_SETTEAM"] = 18] = "CL_SETTEAM";
61
+ NETMSG_Game[NETMSG_Game["CL_SETSPECTATORMODE"] = 19] = "CL_SETSPECTATORMODE";
62
+ NETMSG_Game[NETMSG_Game["CL_STARTINFO"] = 20] = "CL_STARTINFO";
63
+ NETMSG_Game[NETMSG_Game["CL_CHANGEINFO"] = 21] = "CL_CHANGEINFO";
64
+ NETMSG_Game[NETMSG_Game["CL_KILL"] = 22] = "CL_KILL";
65
+ NETMSG_Game[NETMSG_Game["CL_EMOTICON"] = 23] = "CL_EMOTICON";
66
+ NETMSG_Game[NETMSG_Game["CL_VOTE"] = 24] = "CL_VOTE";
67
+ NETMSG_Game[NETMSG_Game["CL_CALLVOTE"] = 25] = "CL_CALLVOTE";
68
+ NETMSG_Game[NETMSG_Game["CL_ISDDNETLEGACY"] = 26] = "CL_ISDDNETLEGACY";
69
+ NETMSG_Game[NETMSG_Game["SV_DDRACETIMELEGACY"] = 27] = "SV_DDRACETIMELEGACY";
70
+ NETMSG_Game[NETMSG_Game["SV_RECORDLEGACY"] = 28] = "SV_RECORDLEGACY";
71
+ NETMSG_Game[NETMSG_Game["UNUSED"] = 29] = "UNUSED";
72
+ NETMSG_Game[NETMSG_Game["SV_TEAMSSTATELEGACY"] = 30] = "SV_TEAMSSTATELEGACY";
73
+ NETMSG_Game[NETMSG_Game["CL_SHOWOTHERSLEGACY"] = 31] = "CL_SHOWOTHERSLEGACY";
74
+ NETMSG_Game[NETMSG_Game["NUM"] = 32] = "NUM";
75
+ })(NETMSG_Game || (NETMSG_Game = {}));
76
+ var NETMSG_Sys;
77
+ (function (NETMSG_Sys) {
78
+ NETMSG_Sys[NETMSG_Sys["NETMSG_EX"] = 0] = "NETMSG_EX";
79
+ // the first thing sent by the client
80
+ // contains the version info for the client
81
+ NETMSG_Sys[NETMSG_Sys["NETMSG_INFO"] = 1] = "NETMSG_INFO";
82
+ // sent by server
83
+ NETMSG_Sys[NETMSG_Sys["NETMSG_MAP_CHANGE"] = 2] = "NETMSG_MAP_CHANGE";
84
+ NETMSG_Sys[NETMSG_Sys["NETMSG_MAP_DATA"] = 3] = "NETMSG_MAP_DATA";
85
+ NETMSG_Sys[NETMSG_Sys["NETMSG_CON_READY"] = 4] = "NETMSG_CON_READY";
86
+ NETMSG_Sys[NETMSG_Sys["NETMSG_SNAP"] = 5] = "NETMSG_SNAP";
87
+ NETMSG_Sys[NETMSG_Sys["NETMSG_SNAPEMPTY"] = 6] = "NETMSG_SNAPEMPTY";
88
+ NETMSG_Sys[NETMSG_Sys["NETMSG_SNAPSINGLE"] = 7] = "NETMSG_SNAPSINGLE";
89
+ NETMSG_Sys[NETMSG_Sys["NETMSG_SNAPSMALL"] = 8] = "NETMSG_SNAPSMALL";
90
+ NETMSG_Sys[NETMSG_Sys["NETMSG_INPUTTIMING"] = 9] = "NETMSG_INPUTTIMING";
91
+ NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_AUTH_STATUS"] = 10] = "NETMSG_RCON_AUTH_STATUS";
92
+ NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_LINE"] = 11] = "NETMSG_RCON_LINE";
93
+ NETMSG_Sys[NETMSG_Sys["NETMSG_AUTH_CHALLANGE"] = 12] = "NETMSG_AUTH_CHALLANGE";
94
+ NETMSG_Sys[NETMSG_Sys["NETMSG_AUTH_RESULT"] = 13] = "NETMSG_AUTH_RESULT";
95
+ // sent by client
96
+ NETMSG_Sys[NETMSG_Sys["NETMSG_READY"] = 14] = "NETMSG_READY";
97
+ NETMSG_Sys[NETMSG_Sys["NETMSG_ENTERGAME"] = 15] = "NETMSG_ENTERGAME";
98
+ NETMSG_Sys[NETMSG_Sys["NETMSG_INPUT"] = 16] = "NETMSG_INPUT";
99
+ NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_CMD"] = 17] = "NETMSG_RCON_CMD";
100
+ NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_AUTH"] = 18] = "NETMSG_RCON_AUTH";
101
+ NETMSG_Sys[NETMSG_Sys["NETMSG_REQUEST_MAP_DATA"] = 19] = "NETMSG_REQUEST_MAP_DATA";
102
+ NETMSG_Sys[NETMSG_Sys["NETMSG_AUTH_START"] = 20] = "NETMSG_AUTH_START";
103
+ NETMSG_Sys[NETMSG_Sys["NETMSG_AUTH_RESPONSE"] = 21] = "NETMSG_AUTH_RESPONSE";
104
+ // sent by both
105
+ NETMSG_Sys[NETMSG_Sys["NETMSG_PING"] = 22] = "NETMSG_PING";
106
+ NETMSG_Sys[NETMSG_Sys["NETMSG_PING_REPLY"] = 23] = "NETMSG_PING_REPLY";
107
+ NETMSG_Sys[NETMSG_Sys["NETMSG_ERROR"] = 24] = "NETMSG_ERROR";
108
+ // sent by server (todo: move it up)
109
+ NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_CMD_ADD"] = 25] = "NETMSG_RCON_CMD_ADD";
110
+ NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_CMD_REM"] = 26] = "NETMSG_RCON_CMD_REM";
111
+ NETMSG_Sys[NETMSG_Sys["NUM_NETMSGS"] = 27] = "NUM_NETMSGS";
112
+ })(NETMSG_Sys || (NETMSG_Sys = {}));
75
113
  function toHexStream(buff) {
76
114
  return buff.toJSON().data.map(function (a) { return ('0' + (a & 0xff).toString(16)).slice(-2); }).join("");
77
115
  }
@@ -113,10 +151,9 @@ var Client = /** @class */ (function (_super) {
113
151
  _this.SnapUnpacker = new snapshot_1.Snapshot();
114
152
  // this.eSnapHolder = [];
115
153
  _this.requestResend = false;
154
+ _this.VoteList = [];
116
155
  if (options)
117
156
  _this.options = options;
118
- _this.timer = 0;
119
- _this.movement = new movement_1.default();
120
157
  _this.snaps = [];
121
158
  _this.sentChunkQueue = [];
122
159
  _this.queueChunkEx = [];
@@ -124,7 +161,6 @@ var Client = /** @class */ (function (_super) {
124
161
  _this.ack = 0; // ack of messages the client has received
125
162
  _this.clientAck = 0; // ack of messages the client has sent
126
163
  _this.receivedSnaps = 0; /* wait for 2 snaps before seeing self as connected */
127
- _this.lastMsg = "";
128
164
  _this.socket = dgram_1.default.createSocket("udp4");
129
165
  _this.socket.bind();
130
166
  _this.TKEN = Buffer.from([255, 255, 255, 255]);
@@ -132,6 +168,8 @@ var Client = /** @class */ (function (_super) {
132
168
  _this.lastSendTime = new Date().getTime();
133
169
  _this.lastRecvTime = new Date().getTime();
134
170
  _this.lastSentMessages = [];
171
+ _this.movement = new movement_1.default();
172
+ _this.game = new game_1.Game(_this);
135
173
  return _this;
136
174
  }
137
175
  Client.prototype.ResendAfter = function (lastAck) {
@@ -168,7 +206,8 @@ var Client = /** @class */ (function (_super) {
168
206
  }
169
207
  else
170
208
  packet = packet.slice(2);
171
- chunk.type = packet[0] & 1 ? "sys" : "game"; // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
209
+ // chunk.type = packet[0] & 1 ? "sys" : "game"; // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
210
+ chunk.sys = Boolean(packet[0] & 1); // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
172
211
  chunk.msgid = (packet[0] - (packet[0] & 1)) / 2;
173
212
  chunk.msg = messageTypes[packet[0] & 1][chunk.msgid];
174
213
  chunk.raw = packet.slice(1, chunk.bytes);
@@ -183,6 +222,7 @@ var Client = /** @class */ (function (_super) {
183
222
  }
184
223
  return unpacked;
185
224
  };
225
+ /* Send a Control Msg to the server. (used for disconnect)*/
186
226
  Client.prototype.SendControlMsg = function (msg, ExtraMsg) {
187
227
  var _this = this;
188
228
  if (ExtraMsg === void 0) { ExtraMsg = ""; }
@@ -202,6 +242,7 @@ var Client = /** @class */ (function (_super) {
202
242
  */
203
243
  });
204
244
  };
245
+ /* Send a Msg (or Msg[]) to the server.*/
205
246
  Client.prototype.SendMsgEx = function (Msgs) {
206
247
  var _this = this;
207
248
  if (this.State == States.STATE_OFFLINE)
@@ -260,9 +301,11 @@ var Client = /** @class */ (function (_super) {
260
301
  return;
261
302
  this.socket.send(packet, 0, packet.length, this.port, this.host);
262
303
  };
304
+ /* Queue a chunk (It will get sent in the next packet). */
263
305
  Client.prototype.QueueChunkEx = function (Msg) {
264
306
  this.queueChunkEx.push(Msg);
265
307
  };
308
+ /* Send a Raw Buffer (as chunk) to the server. */
266
309
  Client.prototype.SendMsgRaw = function (chunks) {
267
310
  if (this.State == States.STATE_OFFLINE)
268
311
  return;
@@ -286,7 +329,8 @@ var Client = /** @class */ (function (_super) {
286
329
  }
287
330
  else
288
331
  packet = packet.slice(2);
289
- chunk.type = packet[0] & 1 ? "sys" : "game"; // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
332
+ // chunk.type = packet[0] & 1 ? "sys" : "game"; // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
333
+ chunk.sys = Boolean(packet[0] & 1); // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
290
334
  chunk.msgid = (packet[0] - (packet[0] & 1)) / 2;
291
335
  chunk.msg = messageTypes[packet[0] & 1][chunk.msgid];
292
336
  chunk.raw = packet.slice(1, chunk.bytes);
@@ -298,6 +342,7 @@ var Client = /** @class */ (function (_super) {
298
342
  });
299
343
  return chunk;
300
344
  };
345
+ /* Connect the client to the server. */
301
346
  Client.prototype.connect = function () {
302
347
  var _this = this;
303
348
  var _a;
@@ -348,15 +393,15 @@ var Client = /** @class */ (function (_super) {
348
393
  }, 5000);
349
394
  this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
350
395
  if (this.socket)
351
- this.socket.on("message", function (a, rinfo) {
352
- var _a, _b, _c, _d, _e, _f, _g, _h;
396
+ this.socket.on("message", function (packet, rinfo) {
397
+ var _a, _b, _c, _d, _e, _f;
353
398
  if (_this.State == 0 || rinfo.address != _this.host || rinfo.port != _this.port)
354
399
  return;
355
400
  clearInterval(connectInterval);
356
- if (a.toJSON().data[0] == 0x10) {
357
- if (a.toString().includes("TKEN") || a.toJSON().data[3] == 0x2) {
401
+ if (packet.toJSON().data[0] == 0x10) {
402
+ if (packet.toString().includes("TKEN") || packet.toJSON().data[3] == 0x2) {
358
403
  clearInterval(connectInterval);
359
- _this.TKEN = Buffer.from(a.toJSON().data.slice(a.toJSON().data.length - 4, a.toJSON().data.length));
404
+ _this.TKEN = Buffer.from(packet.toJSON().data.slice(packet.toJSON().data.length - 4, packet.toJSON().data.length));
360
405
  _this.SendControlMsg(3);
361
406
  _this.State = States.STATE_LOADING; // loading state
362
407
  _this.receivedSnaps = 0;
@@ -378,45 +423,41 @@ var Client = /** @class */ (function (_super) {
378
423
  }
379
424
  _this.SendMsgEx([client_version, info]);
380
425
  }
381
- else if (a.toJSON().data[3] == 0x4) {
426
+ else if (packet.toJSON().data[3] == 0x4) {
382
427
  // disconnected
383
428
  _this.State = States.STATE_OFFLINE;
384
- var reason = (MsgUnpacker_1.unpackString(a.toJSON().data.slice(4)).result);
429
+ var reason = (MsgUnpacker_1.unpackString(packet.toJSON().data.slice(4)).result);
385
430
  _this.emit("disconnect", reason);
386
431
  }
387
- if (a.toJSON().data[3] !== 0x0) { // keepalive
432
+ if (packet.toJSON().data[3] !== 0x0) { // keepalive
388
433
  _this.lastRecvTime = new Date().getTime();
389
434
  }
390
435
  }
391
436
  else {
392
437
  _this.lastRecvTime = new Date().getTime();
393
438
  }
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
396
- unpacked.chunks.forEach(function (a) {
397
- if (a.flags & 1 && (a.flags !== 15)) { // vital and not connless
398
- if (a.seq === (_this.ack + 1) % (1 << 10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
399
- _this.ack = a.seq;
439
+ var unpacked = _this.Unpack(packet);
440
+ unpacked.chunks = unpacked.chunks.filter(function (chunk) { return ((chunk.flags & 2) && (chunk.flags & 1)) ? chunk.seq > _this.ack : true; }); // filter out already received chunks
441
+ unpacked.chunks.forEach(function (chunk) {
442
+ if (chunk.flags & 1 && (chunk.flags !== 15)) { // vital and not connless
443
+ if (chunk.seq === (_this.ack + 1) % (1 << 10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
444
+ _this.ack = chunk.seq;
400
445
  _this.requestResend = false;
401
446
  }
402
447
  else { //IsSeqInBackroom (old packet that we already got)
403
448
  var Bottom = (_this.ack - (1 << 10) / 2);
404
449
  if (Bottom < 0) {
405
- if ((a.seq <= _this.ack) || (a.seq >= (Bottom + (1 << 10))))
450
+ if ((chunk.seq <= _this.ack) || (chunk.seq >= (Bottom + (1 << 10))))
406
451
  return;
407
452
  }
408
453
  else {
409
- if (a.seq <= _this.ack && a.seq >= Bottom)
454
+ if (chunk.seq <= _this.ack && chunk.seq >= Bottom)
410
455
  return;
411
456
  }
412
457
  _this.requestResend = true;
413
458
  }
414
459
  }
415
460
  });
416
- unpacked.chunks.filter(function (a) { return a.msgid == NETMSGTYPE.SV_BROADCAST && a.type == 'game'; }).forEach(function (a) {
417
- var unpacker = new MsgUnpacker_1.MsgUnpacker(a.raw.toJSON().data);
418
- _this.emit("broadcast", unpacker.unpackString());
419
- });
420
461
  _this.sentChunkQueue.forEach(function (buff, i) {
421
462
  var chunk = _this.MsgToChunk(buff);
422
463
  if (chunk.flags & 1) {
@@ -424,149 +465,193 @@ var Client = /** @class */ (function (_super) {
424
465
  _this.sentChunkQueue.splice(i, 1);
425
466
  }
426
467
  });
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"; });
430
- if (snapChunks.length > 0) {
431
- var part = 0;
432
- var num_parts = 1;
433
- if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
434
- _this.PredGameTick = _this.AckGameTick + 1;
435
- snapChunks.forEach(function (chunk) {
436
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
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();
468
+ unpacked.chunks.forEach(function (chunk, index) {
469
+ var _a;
470
+ var _b;
471
+ if (chunk.sys) {
472
+ // system messages
473
+ if (chunk.msgid == NETMSG_Sys.NETMSG_PING) { // ping
474
+ var packer = new MsgPacker_1.MsgPacker(NETMSG_Sys.NETMSG_PING_REPLY, true, 0);
475
+ _this.SendMsgEx(packer); // send ping reply
476
+ }
477
+ else if (chunk.msgid == NETMSG_Sys.NETMSG_PING_REPLY) { // Ping reply
478
+ _this.game._ping_resolve(new Date().getTime());
447
479
  }
448
- if (chunk.msg != "SNAP_EMPTY") {
449
- Crc = unpacker.unpackInt();
450
- PartSize = unpacker.unpackInt();
480
+ // packets neccessary for connection
481
+ // https://ddnet.org/docs/libtw2/connection/
482
+ if (chunk.msgid == NETMSG_Sys.NETMSG_MAP_CHANGE) {
483
+ var Msg = new MsgPacker_1.MsgPacker(NETMSG_Sys.NETMSG_READY, true, 1); /* ready */
484
+ _this.SendMsgEx(Msg);
451
485
  }
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) {
456
- _this.snaps = [];
457
- _this.SnapshotParts = 0;
458
- _this.currentSnapshotGameTick = GameTick;
486
+ else if (chunk.msgid == NETMSG_Sys.NETMSG_CON_READY) {
487
+ var info = new MsgPacker_1.MsgPacker(NETMSG_Game.CL_STARTINFO, false, 1);
488
+ if ((_b = _this.options) === null || _b === void 0 ? void 0 : _b.identity) {
489
+ info.AddString(_this.options.identity.name);
490
+ info.AddString(_this.options.identity.clan);
491
+ info.AddInt(_this.options.identity.country);
492
+ info.AddString(_this.options.identity.skin);
493
+ info.AddInt(_this.options.identity.use_custom_color);
494
+ info.AddInt(_this.options.identity.color_body);
495
+ info.AddInt(_this.options.identity.color_feet);
459
496
  }
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)) {
464
- var mergedSnaps = Buffer.concat(_this.snaps);
465
- _this.SnapshotParts = 0;
466
- var snapUnpacked = _this.SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, DeltaTick, GameTick);
467
- _this.emit("snapshot");
468
- _this.AckGameTick = snapUnpacked.recvTick;
469
- if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
470
- _this.PredGameTick = _this.AckGameTick + 1;
471
- _this.sendInput();
497
+ else {
498
+ info.AddString(_this.name); /* name */
499
+ info.AddString(""); /* clan */
500
+ info.AddInt(-1); /* country */
501
+ info.AddString("greyfox"); /* skin */
502
+ info.AddInt(1); /* use custom color */
503
+ info.AddInt(10346103); /* color body */
504
+ info.AddInt(65535); /* color feet */
472
505
  }
506
+ var crashmeplx = new MsgPacker_1.MsgPacker(17, true, 1); // rcon
507
+ crashmeplx.AddString("crashmeplx"); // 64 player support message
508
+ _this.SendMsgEx([info, crashmeplx]);
473
509
  }
474
- });
475
- }
476
- var chunkMessages = unpacked.chunks.map(function (a) { return a.msg; });
477
- if (chunkMessages.includes("SV_CHAT")) {
478
- var chat = unpacked.chunks.filter(function (a) { return a.msg == "SV_CHAT"; });
479
- chat.forEach(function (a) {
480
- if (a.msg == "SV_CHAT") {
481
- var unpacker = new MsgUnpacker_1.MsgUnpacker(a.raw.toJSON().data);
482
- var unpacked = {
510
+ if (chunk.msgid >= NETMSG_Sys.NETMSG_SNAP && chunk.msgid <= NETMSG_Sys.NETMSG_SNAPSINGLE) {
511
+ _this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
512
+ if (_this.receivedSnaps == 2) {
513
+ if (_this.State != States.STATE_ONLINE)
514
+ _this.emit('connected');
515
+ _this.State = States.STATE_ONLINE;
516
+ }
517
+ if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
518
+ _this.PredGameTick = _this.AckGameTick + 1;
519
+ // snapChunks.forEach(chunk => {
520
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
521
+ var NumParts = 1;
522
+ var Part = 0;
523
+ var GameTick = unpacker.unpackInt();
524
+ var DeltaTick = GameTick - unpacker.unpackInt();
525
+ var PartSize = 0;
526
+ var Crc = 0;
527
+ var CompleteSize = 0;
528
+ if (chunk.msg == "SNAP") {
529
+ NumParts = unpacker.unpackInt();
530
+ Part = unpacker.unpackInt();
531
+ }
532
+ if (chunk.msg != "SNAP_EMPTY") {
533
+ Crc = unpacker.unpackInt();
534
+ PartSize = unpacker.unpackInt();
535
+ }
536
+ if (PartSize < 1 || NumParts > 64 || Part < 0 || Part >= NumParts || PartSize <= 0 || PartSize > 900)
537
+ return;
538
+ if (GameTick >= _this.currentSnapshotGameTick) {
539
+ if (GameTick != _this.currentSnapshotGameTick) {
540
+ _this.snaps = [];
541
+ _this.SnapshotParts = 0;
542
+ _this.currentSnapshotGameTick = GameTick;
543
+ }
544
+ // chunk.raw = Buffer.from(unpacker.remaining);
545
+ _this.snaps[Part] = Buffer.from(unpacker.remaining);
546
+ _this.SnapshotParts |= 1 << Part;
547
+ if (_this.SnapshotParts == ((1 << NumParts) - 1)) {
548
+ var mergedSnaps = Buffer.concat(_this.snaps);
549
+ _this.SnapshotParts = 0;
550
+ var snapUnpacked = _this.SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, DeltaTick, GameTick);
551
+ _this.emit("snapshot");
552
+ _this.AckGameTick = snapUnpacked.recvTick;
553
+ if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
554
+ _this.PredGameTick = _this.AckGameTick + 1;
555
+ _this.sendInput();
556
+ }
557
+ }
558
+ // })
559
+ }
560
+ }
561
+ else {
562
+ // game messages
563
+ // vote list:
564
+ if (chunk.msgid == NETMSG_Game.SV_VOTECLEAROPTIONS) {
565
+ _this.VoteList = [];
566
+ }
567
+ else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONLISTADD) {
568
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
569
+ var NumOptions = unpacker.unpackInt();
570
+ var list = [];
571
+ for (var i = 0; i < 15; i++) {
572
+ list.push(unpacker.unpackString());
573
+ }
574
+ list = list.slice(NumOptions);
575
+ (_a = _this.VoteList).push.apply(_a, list);
576
+ }
577
+ else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONADD) {
578
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
579
+ _this.VoteList.push(unpacker.unpackString());
580
+ }
581
+ else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONREMOVE) {
582
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
583
+ var index_1 = _this.VoteList.indexOf(unpacker.unpackString());
584
+ if (index_1 > -1)
585
+ _this.VoteList = _this.VoteList.splice(index_1, 1);
586
+ }
587
+ // events
588
+ if (chunk.msgid == NETMSG_Game.SV_EMOTICON) {
589
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
590
+ var unpacked_1 = {
591
+ client_id: unpacker.unpackInt(),
592
+ emoticon: unpacker.unpackInt()
593
+ };
594
+ if (unpacked_1.client_id != -1) {
595
+ unpacked_1.author = {
596
+ ClientInfo: _this.client_info(unpacked_1.client_id),
597
+ PlayerInfo: _this.player_info(unpacked_1.client_id)
598
+ };
599
+ }
600
+ _this.emit("emote", unpacked_1);
601
+ }
602
+ else if (chunk.msgid == NETMSG_Game.SV_BROADCAST) {
603
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
604
+ _this.emit("broadcast", unpacker.unpackString());
605
+ }
606
+ if (chunk.msgid == NETMSG_Game.SV_CHAT) {
607
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
608
+ var unpacked_2 = {
483
609
  team: unpacker.unpackInt(),
484
610
  client_id: unpacker.unpackInt(),
485
611
  message: unpacker.unpackString()
486
612
  };
487
- if (unpacked.client_id != -1) {
488
- unpacked.author = {
489
- ClientInfo: _this.client_info(unpacked.client_id),
490
- PlayerInfo: _this.player_info(unpacked.client_id)
613
+ if (unpacked_2.client_id != -1) {
614
+ unpacked_2.author = {
615
+ ClientInfo: _this.client_info(unpacked_2.client_id),
616
+ PlayerInfo: _this.player_info(unpacked_2.client_id)
491
617
  };
492
618
  }
493
- _this.emit("message", unpacked);
619
+ _this.emit("message", unpacked_2);
494
620
  }
495
- });
496
- }
497
- var chat = unpacked.chunks.filter(function (a) { return a.msg == "SV_KILL_MSG" || a.msg == "SV_MOTD"; });
498
- chat.forEach(function (a) {
499
- if (a.msg == "SV_KILL_MSG") {
500
- var unpacked = {};
501
- var unpacker = new MsgUnpacker_1.MsgUnpacker(a.raw.toJSON().data);
502
- unpacked.killer_id = unpacker.unpackInt();
503
- unpacked.victim_id = unpacker.unpackInt();
504
- unpacked.weapon = unpacker.unpackInt();
505
- unpacked.special_mode = unpacker.unpackInt();
506
- if (unpacked.victim_id != -1 && unpacked.victim_id < 64) {
507
- unpacked.victim = { ClientInfo: _this.client_info(unpacked.victim_id), PlayerInfo: _this.player_info(unpacked.victim_id) };
621
+ else if (chunk.msgid == NETMSG_Game.SV_KILLMSG) {
622
+ var unpacked_3 = {};
623
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
624
+ unpacked_3.killer_id = unpacker.unpackInt();
625
+ unpacked_3.victim_id = unpacker.unpackInt();
626
+ unpacked_3.weapon = unpacker.unpackInt();
627
+ unpacked_3.special_mode = unpacker.unpackInt();
628
+ if (unpacked_3.victim_id != -1 && unpacked_3.victim_id < 64) {
629
+ unpacked_3.victim = { ClientInfo: _this.client_info(unpacked_3.victim_id), PlayerInfo: _this.player_info(unpacked_3.victim_id) };
630
+ }
631
+ if (unpacked_3.killer_id != -1 && unpacked_3.killer_id < 64)
632
+ unpacked_3.killer = { ClientInfo: _this.client_info(unpacked_3.killer_id), PlayerInfo: _this.player_info(unpacked_3.killer_id) };
633
+ _this.emit("kill", unpacked_3);
634
+ }
635
+ else if (chunk.msgid == NETMSG_Game.SV_MOTD) {
636
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
637
+ var message = unpacker.unpackString();
638
+ _this.emit("motd", message);
639
+ }
640
+ // packets neccessary for connection
641
+ // https://ddnet.org/docs/libtw2/connection/
642
+ if (chunk.msgid == NETMSG_Game.SV_READYTOENTER) {
643
+ var Msg = new MsgPacker_1.MsgPacker(15, true, 1); /* entergame */
644
+ _this.SendMsgEx(Msg);
508
645
  }
509
- if (unpacked.killer_id != -1 && unpacked.killer_id < 64)
510
- unpacked.killer = { ClientInfo: _this.client_info(unpacked.killer_id), PlayerInfo: _this.player_info(unpacked.killer_id) };
511
- _this.emit("kill", unpacked);
512
- }
513
- else if (a.msg == "SV_MOTD") {
514
- var unpacker = new MsgUnpacker_1.MsgUnpacker(a.raw.toJSON().data);
515
- var message = unpacker.unpackString();
516
- _this.emit("motd", message);
517
646
  }
518
647
  });
519
- if (unpacked.chunks[0] && chunkMessages.includes("SV_READY_TO_ENTER")) {
520
- var Msg = new MsgPacker_1.MsgPacker(15, true, 1); /* entergame */
521
- _this.SendMsgEx(Msg);
522
- }
523
- else if ((unpacked.chunks[0] && chunkMessages.includes("CAPABILITIES") || unpacked.chunks[0] && chunkMessages.includes("MAP_CHANGE"))) {
524
- // send ready
525
- var Msg = new MsgPacker_1.MsgPacker(14, true, 1); /* ready */
526
- _this.SendMsgEx(Msg);
527
- }
528
- else if ((unpacked.chunks[0] && chunkMessages.includes("CON_READY"))) {
529
- var info = new MsgPacker_1.MsgPacker(20, false, 1);
530
- if ((_h = _this.options) === null || _h === void 0 ? void 0 : _h.identity) {
531
- info.AddString(_this.options.identity.name);
532
- info.AddString(_this.options.identity.clan);
533
- info.AddInt(_this.options.identity.country);
534
- info.AddString(_this.options.identity.skin);
535
- info.AddInt(_this.options.identity.use_custom_color);
536
- info.AddInt(_this.options.identity.color_body);
537
- info.AddInt(_this.options.identity.color_feet);
538
- }
539
- else {
540
- info.AddString(_this.name); /* name */
541
- info.AddString(""); /* clan */
542
- info.AddInt(-1); /* country */
543
- info.AddString("greyfox"); /* skin */
544
- info.AddInt(1); /* use custom color */
545
- info.AddInt(10346103); /* color body */
546
- info.AddInt(65535); /* color feet */
547
- }
548
- var crashmeplx = new MsgPacker_1.MsgPacker(17, true, 1); // rcon
549
- crashmeplx.AddString("crashmeplx"); // 64 player support message
550
- _this.SendMsgEx([info, crashmeplx]);
551
- }
552
- else if (unpacked.chunks[0] && chunkMessages.includes("PING")) {
553
- var info = new MsgPacker_1.MsgPacker(23, true, 1);
554
- _this.SendMsgEx(info);
555
- }
556
- if (chunkMessages.includes("SNAP") || chunkMessages.includes("SNAP_EMPTY") || chunkMessages.includes("SNAP_SINGLE")) {
557
- _this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
558
- if (_this.receivedSnaps == 2) {
559
- if (_this.State != States.STATE_ONLINE)
560
- _this.emit('connected');
561
- _this.State = States.STATE_ONLINE;
562
- }
563
- }
564
648
  if (new Date().getTime() - _this.time >= 1000 && _this.State == States.STATE_ONLINE) {
565
649
  _this.time = new Date().getTime();
566
650
  _this.SendControlMsg(0);
567
651
  }
568
652
  });
569
653
  };
654
+ /* Sending the input. (automatically done unless options.lightweight is on) */
570
655
  Client.prototype.sendInput = function (input) {
571
656
  if (input === void 0) { input = this.movement.input; }
572
657
  if (this.State != States.STATE_ONLINE)
@@ -599,6 +684,7 @@ var Client = /** @class */ (function (_super) {
599
684
  enumerable: false,
600
685
  configurable: true
601
686
  });
687
+ /* Disconnect the client. */
602
688
  Client.prototype.Disconnect = function () {
603
689
  var _this = this;
604
690
  return new Promise(function (resolve) {
@@ -611,71 +697,11 @@ var Client = /** @class */ (function (_super) {
611
697
  });
612
698
  });
613
699
  };
614
- Client.prototype.Say = function (message, team) {
615
- var _a;
616
- if (team === void 0) { team = false; }
617
- var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_SAY, false, 1);
618
- packer.AddInt(team ? 1 : 0); // team
619
- packer.AddString(message);
620
- if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
621
- this.QueueChunkEx(packer);
622
- else
623
- this.SendMsgEx(packer);
624
- };
625
- Client.prototype.Vote = function (vote) {
626
- var _a;
627
- var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_VOTE, false, 1);
628
- packer.AddInt(vote ? 1 : -1);
629
- if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
630
- this.QueueChunkEx(packer);
631
- else
632
- this.SendMsgEx(packer);
633
- };
634
- Client.prototype.ChangePlayerInfo = function (playerInfo) {
635
- var _a;
636
- var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_CHANGEINFO, false, 1);
637
- packer.AddString(playerInfo.name); //m_pName);
638
- packer.AddString(playerInfo.clan); //m_pClan);
639
- packer.AddInt(playerInfo.country); //m_Country);
640
- packer.AddString(playerInfo.skin); //m_pSkin);
641
- packer.AddInt(playerInfo.use_custom_color ? 1 : 0); //m_UseCustomColor);
642
- packer.AddInt(playerInfo.color_body); //m_ColorBody);
643
- packer.AddInt(playerInfo.color_feet); //m_ColorFeet);
644
- if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
645
- this.QueueChunkEx(packer);
646
- else
647
- this.SendMsgEx(packer);
648
- };
649
- Client.prototype.Kill = function () {
650
- var _a;
651
- var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_KILL, false, 1);
652
- if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
653
- this.QueueChunkEx(packer);
654
- else
655
- this.SendMsgEx(packer);
656
- };
657
- Client.prototype.ChangeTeam = function (team) {
658
- var _a;
659
- var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_SETTEAM, false, 1);
660
- packer.AddInt(team);
661
- if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
662
- this.QueueChunkEx(packer);
663
- else
664
- this.SendMsgEx(packer);
665
- };
666
- Client.prototype.Emote = function (emote) {
667
- var _a;
668
- var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_EMOTICON, false, 1);
669
- packer.AddInt(emote);
670
- if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
671
- this.QueueChunkEx(packer);
672
- else
673
- this.SendMsgEx(packer);
674
- };
700
+ /* Get the client_info from a specific player id. */
675
701
  Client.prototype.client_info = function (id) {
676
- var delta = this.SnapUnpacker.deltas.filter(function (a) {
677
- return a.type_id == 11
678
- && a.id == id;
702
+ var delta = this.SnapUnpacker.deltas.filter(function (_delta) {
703
+ return _delta.type_id == 11
704
+ && _delta.id == id;
679
705
  });
680
706
  if (delta.length == 0)
681
707
  return undefined;
@@ -684,28 +710,38 @@ var Client = /** @class */ (function (_super) {
684
710
  // .map(a => a.parsed as ClientInfo);
685
711
  };
686
712
  Object.defineProperty(Client.prototype, "client_infos", {
713
+ /* Get all client infos. */
687
714
  get: function () {
688
- return this.SnapUnpacker.deltas.filter(function (a) { return a.type_id == 11; })
715
+ return this.SnapUnpacker.deltas.filter(function (_delta) { return _delta.type_id == 11; })
689
716
  .sort(function (a, b) { return a.id - b.id; })
690
717
  .map(function (a) { return a.parsed; });
691
718
  },
692
719
  enumerable: false,
693
720
  configurable: true
694
721
  });
722
+ /* Get the player info from a specific player id. */
695
723
  Client.prototype.player_info = function (id) {
696
- var delta = this.SnapUnpacker.deltas.filter(function (a) {
697
- return a.type_id == 10
698
- && a.id == id;
724
+ var delta = this.SnapUnpacker.deltas.filter(function (_delta) {
725
+ return _delta.type_id == 10
726
+ && _delta.id == id;
699
727
  });
700
728
  if (delta.length == 0)
701
729
  return undefined;
702
730
  return delta[0].parsed;
703
731
  };
704
732
  Object.defineProperty(Client.prototype, "player_infos", {
733
+ /* Get all player infos. */
705
734
  get: function () {
706
- return this.SnapUnpacker.deltas.filter(function (a) { return a.type_id == 10; })
735
+ return this.SnapUnpacker.deltas.filter(function (_delta) { return _delta.type_id == 10; })
707
736
  .sort(function (a, b) { return a.id - b.id; })
708
- .map(function (a) { return a.parsed; });
737
+ .map(function (player) { return player.parsed; });
738
+ },
739
+ enumerable: false,
740
+ configurable: true
741
+ });
742
+ Object.defineProperty(Client.prototype, "VoteOptionList", {
743
+ get: function () {
744
+ return this.VoteList;
709
745
  },
710
746
  enumerable: false,
711
747
  configurable: true