teeworlds 2.4.0 → 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 +251 -166
- package/lib/client.ts +190 -82
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -37,42 +37,79 @@ var States;
|
|
|
37
37
|
States[States["STATE_QUITTING"] = 5] = "STATE_QUITTING";
|
|
38
38
|
States[States["STATE_RESTARTING"] = 6] = "STATE_RESTARTING";
|
|
39
39
|
})(States || (States = {}));
|
|
40
|
-
var
|
|
41
|
-
(function (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
})(
|
|
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 = {}));
|
|
76
113
|
function toHexStream(buff) {
|
|
77
114
|
return buff.toJSON().data.map(function (a) { return ('0' + (a & 0xff).toString(16)).slice(-2); }).join("");
|
|
78
115
|
}
|
|
@@ -114,6 +151,7 @@ var Client = /** @class */ (function (_super) {
|
|
|
114
151
|
_this.SnapUnpacker = new snapshot_1.Snapshot();
|
|
115
152
|
// this.eSnapHolder = [];
|
|
116
153
|
_this.requestResend = false;
|
|
154
|
+
_this.VoteList = [];
|
|
117
155
|
if (options)
|
|
118
156
|
_this.options = options;
|
|
119
157
|
_this.snaps = [];
|
|
@@ -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);
|
|
@@ -290,7 +329,8 @@ var Client = /** @class */ (function (_super) {
|
|
|
290
329
|
}
|
|
291
330
|
else
|
|
292
331
|
packet = packet.slice(2);
|
|
293
|
-
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
|
|
294
334
|
chunk.msgid = (packet[0] - (packet[0] & 1)) / 2;
|
|
295
335
|
chunk.msg = messageTypes[packet[0] & 1][chunk.msgid];
|
|
296
336
|
chunk.raw = packet.slice(1, chunk.bytes);
|
|
@@ -354,7 +394,7 @@ var Client = /** @class */ (function (_super) {
|
|
|
354
394
|
this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
|
|
355
395
|
if (this.socket)
|
|
356
396
|
this.socket.on("message", function (packet, rinfo) {
|
|
357
|
-
var _a, _b, _c, _d, _e, _f
|
|
397
|
+
var _a, _b, _c, _d, _e, _f;
|
|
358
398
|
if (_this.State == 0 || rinfo.address != _this.host || rinfo.port != _this.port)
|
|
359
399
|
return;
|
|
360
400
|
clearInterval(connectInterval);
|
|
@@ -418,10 +458,6 @@ var Client = /** @class */ (function (_super) {
|
|
|
418
458
|
}
|
|
419
459
|
}
|
|
420
460
|
});
|
|
421
|
-
unpacked.chunks.filter(function (chunk) { return chunk.msgid == NETMSGTYPE.SV_BROADCAST && chunk.type == 'game'; }).forEach(function (a) {
|
|
422
|
-
var unpacker = new MsgUnpacker_1.MsgUnpacker(a.raw.toJSON().data);
|
|
423
|
-
_this.emit("broadcast", unpacker.unpackString());
|
|
424
|
-
});
|
|
425
461
|
_this.sentChunkQueue.forEach(function (buff, i) {
|
|
426
462
|
var chunk = _this.MsgToChunk(buff);
|
|
427
463
|
if (chunk.flags & 1) {
|
|
@@ -429,144 +465,186 @@ var Client = /** @class */ (function (_super) {
|
|
|
429
465
|
_this.sentChunkQueue.splice(i, 1);
|
|
430
466
|
}
|
|
431
467
|
});
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
var DeltaTick = GameTick - unpacker.unpackInt();
|
|
444
|
-
var PartSize = 0;
|
|
445
|
-
var Crc = 0;
|
|
446
|
-
var CompleteSize = 0;
|
|
447
|
-
if (chunk.msg == "SNAP") {
|
|
448
|
-
NumParts = unpacker.unpackInt();
|
|
449
|
-
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());
|
|
450
479
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
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);
|
|
454
485
|
}
|
|
455
|
-
if (
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
_this.
|
|
460
|
-
_this.
|
|
461
|
-
_this.
|
|
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);
|
|
462
496
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
_this.AckGameTick = snapUnpacked.recvTick;
|
|
472
|
-
if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
|
|
473
|
-
_this.PredGameTick = _this.AckGameTick + 1;
|
|
474
|
-
_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 */
|
|
475
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]);
|
|
476
509
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
var unpacker = new MsgUnpacker_1.MsgUnpacker(
|
|
488
|
-
var
|
|
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 = {
|
|
489
609
|
team: unpacker.unpackInt(),
|
|
490
610
|
client_id: unpacker.unpackInt(),
|
|
491
611
|
message: unpacker.unpackString()
|
|
492
612
|
};
|
|
493
|
-
if (
|
|
494
|
-
|
|
495
|
-
ClientInfo: _this.client_info(
|
|
496
|
-
PlayerInfo: _this.player_info(
|
|
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)
|
|
497
617
|
};
|
|
498
618
|
}
|
|
499
|
-
_this.emit("message",
|
|
619
|
+
_this.emit("message", unpacked_2);
|
|
500
620
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
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);
|
|
514
645
|
}
|
|
515
|
-
if (unpacked.killer_id != -1 && unpacked.killer_id < 64)
|
|
516
|
-
unpacked.killer = { ClientInfo: _this.client_info(unpacked.killer_id), PlayerInfo: _this.player_info(unpacked.killer_id) };
|
|
517
|
-
_this.emit("kill", unpacked);
|
|
518
|
-
}
|
|
519
|
-
else if (a.msg == "SV_MOTD") {
|
|
520
|
-
var unpacker = new MsgUnpacker_1.MsgUnpacker(a.raw.toJSON().data);
|
|
521
|
-
var message = unpacker.unpackString();
|
|
522
|
-
_this.emit("motd", message);
|
|
523
646
|
}
|
|
524
647
|
});
|
|
525
|
-
if (unpacked.chunks[0] && chunkMessages.includes("SV_READY_TO_ENTER")) {
|
|
526
|
-
var Msg = new MsgPacker_1.MsgPacker(15, true, 1); /* entergame */
|
|
527
|
-
_this.SendMsgEx(Msg);
|
|
528
|
-
}
|
|
529
|
-
else if ((unpacked.chunks[0] && chunkMessages.includes("CAPABILITIES") || unpacked.chunks[0] && chunkMessages.includes("MAP_CHANGE"))) {
|
|
530
|
-
// send ready
|
|
531
|
-
var Msg = new MsgPacker_1.MsgPacker(14, true, 1); /* ready */
|
|
532
|
-
_this.SendMsgEx(Msg);
|
|
533
|
-
}
|
|
534
|
-
else if ((unpacked.chunks[0] && chunkMessages.includes("CON_READY"))) {
|
|
535
|
-
var info = new MsgPacker_1.MsgPacker(20, false, 1);
|
|
536
|
-
if ((_h = _this.options) === null || _h === void 0 ? void 0 : _h.identity) {
|
|
537
|
-
info.AddString(_this.options.identity.name);
|
|
538
|
-
info.AddString(_this.options.identity.clan);
|
|
539
|
-
info.AddInt(_this.options.identity.country);
|
|
540
|
-
info.AddString(_this.options.identity.skin);
|
|
541
|
-
info.AddInt(_this.options.identity.use_custom_color);
|
|
542
|
-
info.AddInt(_this.options.identity.color_body);
|
|
543
|
-
info.AddInt(_this.options.identity.color_feet);
|
|
544
|
-
}
|
|
545
|
-
else {
|
|
546
|
-
info.AddString(_this.name); /* name */
|
|
547
|
-
info.AddString(""); /* clan */
|
|
548
|
-
info.AddInt(-1); /* country */
|
|
549
|
-
info.AddString("greyfox"); /* skin */
|
|
550
|
-
info.AddInt(1); /* use custom color */
|
|
551
|
-
info.AddInt(10346103); /* color body */
|
|
552
|
-
info.AddInt(65535); /* color feet */
|
|
553
|
-
}
|
|
554
|
-
var crashmeplx = new MsgPacker_1.MsgPacker(17, true, 1); // rcon
|
|
555
|
-
crashmeplx.AddString("crashmeplx"); // 64 player support message
|
|
556
|
-
_this.SendMsgEx([info, crashmeplx]);
|
|
557
|
-
}
|
|
558
|
-
else if (unpacked.chunks[0] && chunkMessages.includes("PING")) {
|
|
559
|
-
var info = new MsgPacker_1.MsgPacker(23, true, 1);
|
|
560
|
-
_this.SendMsgEx(info);
|
|
561
|
-
}
|
|
562
|
-
if (chunkMessages.includes("SNAP") || chunkMessages.includes("SNAP_EMPTY") || chunkMessages.includes("SNAP_SINGLE")) {
|
|
563
|
-
_this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
|
|
564
|
-
if (_this.receivedSnaps == 2) {
|
|
565
|
-
if (_this.State != States.STATE_ONLINE)
|
|
566
|
-
_this.emit('connected');
|
|
567
|
-
_this.State = States.STATE_ONLINE;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
648
|
if (new Date().getTime() - _this.time >= 1000 && _this.State == States.STATE_ONLINE) {
|
|
571
649
|
_this.time = new Date().getTime();
|
|
572
650
|
_this.SendControlMsg(0);
|
|
@@ -661,6 +739,13 @@ var Client = /** @class */ (function (_super) {
|
|
|
661
739
|
enumerable: false,
|
|
662
740
|
configurable: true
|
|
663
741
|
});
|
|
742
|
+
Object.defineProperty(Client.prototype, "VoteOptionList", {
|
|
743
|
+
get: function () {
|
|
744
|
+
return this.VoteList;
|
|
745
|
+
},
|
|
746
|
+
enumerable: false,
|
|
747
|
+
configurable: true
|
|
748
|
+
});
|
|
664
749
|
return Client;
|
|
665
750
|
}(stream_1.EventEmitter));
|
|
666
751
|
exports.Client = Client;
|
package/lib/client.ts
CHANGED
|
@@ -25,7 +25,7 @@ enum States {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
enum
|
|
28
|
+
enum NETMSG_Game {
|
|
29
29
|
EX,
|
|
30
30
|
SV_MOTD,
|
|
31
31
|
SV_BROADCAST,
|
|
@@ -61,12 +61,58 @@ enum NETMSGTYPE {
|
|
|
61
61
|
NUM
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
enum NETMSG_Sys {
|
|
65
|
+
NETMSG_EX = 0,
|
|
66
|
+
|
|
67
|
+
// the first thing sent by the client
|
|
68
|
+
// contains the version info for the client
|
|
69
|
+
NETMSG_INFO = 1,
|
|
70
|
+
|
|
71
|
+
// sent by server
|
|
72
|
+
NETMSG_MAP_CHANGE, // sent when client should switch map
|
|
73
|
+
NETMSG_MAP_DATA, // map transfer, contains a chunk of the map file
|
|
74
|
+
NETMSG_CON_READY, // connection is ready, client should send start info
|
|
75
|
+
NETMSG_SNAP, // normal snapshot, multiple parts
|
|
76
|
+
NETMSG_SNAPEMPTY, // empty snapshot
|
|
77
|
+
NETMSG_SNAPSINGLE, // ?
|
|
78
|
+
NETMSG_SNAPSMALL, //
|
|
79
|
+
NETMSG_INPUTTIMING, // reports how off the input was
|
|
80
|
+
NETMSG_RCON_AUTH_STATUS, // result of the authentication
|
|
81
|
+
NETMSG_RCON_LINE, // line that should be printed to the remote console
|
|
82
|
+
|
|
83
|
+
NETMSG_AUTH_CHALLANGE, //
|
|
84
|
+
NETMSG_AUTH_RESULT, //
|
|
85
|
+
|
|
86
|
+
// sent by client
|
|
87
|
+
NETMSG_READY, //
|
|
88
|
+
NETMSG_ENTERGAME,
|
|
89
|
+
NETMSG_INPUT, // contains the inputdata from the client
|
|
90
|
+
NETMSG_RCON_CMD, //
|
|
91
|
+
NETMSG_RCON_AUTH, //
|
|
92
|
+
NETMSG_REQUEST_MAP_DATA, //
|
|
93
|
+
|
|
94
|
+
NETMSG_AUTH_START, //
|
|
95
|
+
NETMSG_AUTH_RESPONSE, //
|
|
96
|
+
|
|
97
|
+
// sent by both
|
|
98
|
+
NETMSG_PING,
|
|
99
|
+
NETMSG_PING_REPLY,
|
|
100
|
+
NETMSG_ERROR,
|
|
101
|
+
|
|
102
|
+
// sent by server (todo: move it up)
|
|
103
|
+
NETMSG_RCON_CMD_ADD,
|
|
104
|
+
NETMSG_RCON_CMD_REM,
|
|
105
|
+
|
|
106
|
+
NUM_NETMSGS,
|
|
107
|
+
}
|
|
108
|
+
|
|
64
109
|
interface chunk {
|
|
65
110
|
bytes: number,
|
|
66
111
|
flags: number,
|
|
67
112
|
sequence?: number,
|
|
68
113
|
seq?: number,
|
|
69
|
-
type: 'sys' | 'game',
|
|
114
|
+
// type: 'sys' | 'game',
|
|
115
|
+
sys: Boolean,
|
|
70
116
|
msgid: number,
|
|
71
117
|
msg: string,
|
|
72
118
|
raw: Buffer,
|
|
@@ -128,6 +174,12 @@ declare interface iMessage {
|
|
|
128
174
|
message: string
|
|
129
175
|
}
|
|
130
176
|
|
|
177
|
+
declare interface iEmoticon {
|
|
178
|
+
client_id: number,
|
|
179
|
+
emoticon: number,
|
|
180
|
+
author?: { ClientInfo?: ClientInfo, PlayerInfo?: PlayerInfo }
|
|
181
|
+
}
|
|
182
|
+
|
|
131
183
|
declare interface iKillMsg {
|
|
132
184
|
killer_id: number,
|
|
133
185
|
killer?: { ClientInfo?: ClientInfo, PlayerInfo?: PlayerInfo },
|
|
@@ -152,6 +204,7 @@ export declare interface Client {
|
|
|
152
204
|
on(event: 'connected', listener: () => void): this;
|
|
153
205
|
on(event: 'disconnect', listener: (reason: string) => void): this;
|
|
154
206
|
|
|
207
|
+
on(event: 'emote', listener: (message: iEmoticon) => void): this;
|
|
155
208
|
on(event: 'message', listener: (message: iMessage) => void): this;
|
|
156
209
|
on(event: 'broadcast', listener: (message: string) => void): this;
|
|
157
210
|
on(event: 'kill', listener: (kill: iKillMsg) => void): this;
|
|
@@ -193,6 +246,7 @@ export class Client extends EventEmitter {
|
|
|
193
246
|
public movement: Movement;
|
|
194
247
|
public game: Game;
|
|
195
248
|
|
|
249
|
+
private VoteList: string[];
|
|
196
250
|
// eSnapHolder: eSnap[];
|
|
197
251
|
|
|
198
252
|
|
|
@@ -215,6 +269,8 @@ export class Client extends EventEmitter {
|
|
|
215
269
|
// this.eSnapHolder = [];
|
|
216
270
|
this.requestResend = false;
|
|
217
271
|
|
|
272
|
+
this.VoteList = [];
|
|
273
|
+
|
|
218
274
|
if (options)
|
|
219
275
|
this.options = options;
|
|
220
276
|
|
|
@@ -286,7 +342,8 @@ export class Client extends EventEmitter {
|
|
|
286
342
|
packet = packet.slice(3) // remove flags & size
|
|
287
343
|
} else
|
|
288
344
|
packet = packet.slice(2)
|
|
289
|
-
chunk.type = packet[0] & 1 ? "sys" : "game"; // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
|
|
345
|
+
// chunk.type = packet[0] & 1 ? "sys" : "game"; // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
|
|
346
|
+
chunk.sys = Boolean(packet[0] & 1); // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
|
|
290
347
|
chunk.msgid = (packet[0] - (packet[0] & 1)) / 2;
|
|
291
348
|
chunk.msg = messageTypes[packet[0] & 1][chunk.msgid];
|
|
292
349
|
chunk.raw = packet.slice(1, chunk.bytes)
|
|
@@ -414,7 +471,8 @@ export class Client extends EventEmitter {
|
|
|
414
471
|
packet = packet.slice(3) // remove flags & size
|
|
415
472
|
} else
|
|
416
473
|
packet = packet.slice(2)
|
|
417
|
-
chunk.type = packet[0] & 1 ? "sys" : "game"; // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
|
|
474
|
+
// chunk.type = packet[0] & 1 ? "sys" : "game"; // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
|
|
475
|
+
chunk.sys = Boolean(packet[0] & 1); // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
|
|
418
476
|
chunk.msgid = (packet[0]-(packet[0]&1))/2;
|
|
419
477
|
chunk.msg = messageTypes[packet[0]&1][chunk.msgid];
|
|
420
478
|
chunk.raw = packet.slice(1, chunk.bytes)
|
|
@@ -552,11 +610,6 @@ export class Client extends EventEmitter {
|
|
|
552
610
|
}
|
|
553
611
|
|
|
554
612
|
})
|
|
555
|
-
unpacked.chunks.filter(chunk => chunk.msgid == NETMSGTYPE.SV_BROADCAST && chunk.type == 'game').forEach(a => {
|
|
556
|
-
let unpacker = new MsgUnpacker(a.raw.toJSON().data);
|
|
557
|
-
|
|
558
|
-
this.emit("broadcast", unpacker.unpackString());
|
|
559
|
-
})
|
|
560
613
|
this.sentChunkQueue.forEach((buff, i) => {
|
|
561
614
|
let chunk = this.MsgToChunk(buff);
|
|
562
615
|
if (chunk.flags & 1) {
|
|
@@ -564,14 +617,61 @@ export class Client extends EventEmitter {
|
|
|
564
617
|
this.sentChunkQueue.splice(i, 1);
|
|
565
618
|
}
|
|
566
619
|
})
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
unpacked.chunks.forEach((chunk, index) => {
|
|
623
|
+
if (chunk.sys) {
|
|
624
|
+
// system messages
|
|
625
|
+
if (chunk.msgid == NETMSG_Sys.NETMSG_PING) { // ping
|
|
626
|
+
let packer = new MsgPacker(NETMSG_Sys.NETMSG_PING_REPLY, true, 0);
|
|
627
|
+
|
|
628
|
+
this.SendMsgEx(packer); // send ping reply
|
|
629
|
+
} else if (chunk.msgid == NETMSG_Sys.NETMSG_PING_REPLY) { // Ping reply
|
|
630
|
+
this.game._ping_resolve(new Date().getTime())
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// packets neccessary for connection
|
|
634
|
+
// https://ddnet.org/docs/libtw2/connection/
|
|
635
|
+
|
|
636
|
+
if (chunk.msgid == NETMSG_Sys.NETMSG_MAP_CHANGE) {
|
|
637
|
+
var Msg = new MsgPacker(NETMSG_Sys.NETMSG_READY, true, 1); /* ready */
|
|
638
|
+
this.SendMsgEx(Msg);
|
|
639
|
+
} else if (chunk.msgid == NETMSG_Sys.NETMSG_CON_READY) {
|
|
640
|
+
var info = new MsgPacker(NETMSG_Game.CL_STARTINFO, false, 1);
|
|
641
|
+
if (this.options?.identity) {
|
|
642
|
+
info.AddString(this.options.identity.name);
|
|
643
|
+
info.AddString(this.options.identity.clan);
|
|
644
|
+
info.AddInt(this.options.identity.country);
|
|
645
|
+
info.AddString(this.options.identity.skin);
|
|
646
|
+
info.AddInt(this.options.identity.use_custom_color);
|
|
647
|
+
info.AddInt(this.options.identity.color_body);
|
|
648
|
+
info.AddInt(this.options.identity.color_feet);
|
|
649
|
+
} else {
|
|
650
|
+
info.AddString(this.name); /* name */
|
|
651
|
+
info.AddString(""); /* clan */
|
|
652
|
+
info.AddInt(-1); /* country */
|
|
653
|
+
info.AddString("greyfox"); /* skin */
|
|
654
|
+
info.AddInt(1); /* use custom color */
|
|
655
|
+
info.AddInt(10346103); /* color body */
|
|
656
|
+
info.AddInt(65535); /* color feet */
|
|
657
|
+
|
|
658
|
+
}
|
|
659
|
+
var crashmeplx = new MsgPacker(17, true, 1); // rcon
|
|
660
|
+
crashmeplx.AddString("crashmeplx"); // 64 player support message
|
|
661
|
+
this.SendMsgEx([info, crashmeplx]);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (chunk.msgid >= NETMSG_Sys.NETMSG_SNAP && chunk.msgid <= NETMSG_Sys.NETMSG_SNAPSINGLE) {
|
|
665
|
+
this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
|
|
666
|
+
if (this.receivedSnaps == 2) {
|
|
667
|
+
if (this.State != States.STATE_ONLINE)
|
|
668
|
+
this.emit('connected')
|
|
669
|
+
this.State = States.STATE_ONLINE;
|
|
670
|
+
}
|
|
671
|
+
if (Math.abs(this.PredGameTick - this.AckGameTick) > 10)
|
|
572
672
|
this.PredGameTick = this.AckGameTick + 1;
|
|
573
673
|
|
|
574
|
-
snapChunks.forEach(chunk => {
|
|
674
|
+
// snapChunks.forEach(chunk => {
|
|
575
675
|
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
|
|
576
676
|
|
|
577
677
|
let NumParts = 1;
|
|
@@ -625,19 +725,65 @@ export class Client extends EventEmitter {
|
|
|
625
725
|
}
|
|
626
726
|
|
|
627
727
|
|
|
628
|
-
})
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
var chunkMessages = unpacked.chunks.map(a => a.msg)
|
|
632
|
-
if (unpacked.chunks.findIndex(chunk => chunk.msgid == 23 && chunk.type == "sys") !== -1) {
|
|
633
|
-
this.game._ping_resolve(new Date().getTime())
|
|
728
|
+
// })
|
|
729
|
+
|
|
730
|
+
|
|
634
731
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
732
|
+
} else {
|
|
733
|
+
// game messages
|
|
734
|
+
|
|
735
|
+
// vote list:
|
|
736
|
+
if (chunk.msgid == NETMSG_Game.SV_VOTECLEAROPTIONS) {
|
|
737
|
+
this.VoteList = [];
|
|
738
|
+
} else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONLISTADD) {
|
|
739
|
+
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data)
|
|
740
|
+
let NumOptions = unpacker.unpackInt()
|
|
741
|
+
let list: string[] = [];
|
|
742
|
+
for (let i = 0; i < 15; i++) {
|
|
743
|
+
list.push(unpacker.unpackString());
|
|
744
|
+
}
|
|
745
|
+
list = list.slice(NumOptions);
|
|
746
|
+
|
|
747
|
+
this.VoteList.push(...list);
|
|
748
|
+
} else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONADD) {
|
|
749
|
+
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data)
|
|
750
|
+
|
|
751
|
+
this.VoteList.push(unpacker.unpackString());
|
|
752
|
+
} else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONREMOVE) {
|
|
753
|
+
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data)
|
|
754
|
+
|
|
755
|
+
let index = this.VoteList.indexOf(unpacker.unpackString());
|
|
756
|
+
|
|
757
|
+
if (index > -1)
|
|
758
|
+
this.VoteList = this.VoteList.splice(index, 1);
|
|
759
|
+
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// events
|
|
763
|
+
if (chunk.msgid == NETMSG_Game.SV_EMOTICON) {
|
|
764
|
+
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
|
|
765
|
+
let unpacked = {
|
|
766
|
+
client_id: unpacker.unpackInt(),
|
|
767
|
+
emoticon: unpacker.unpackInt()
|
|
768
|
+
} as iEmoticon;
|
|
769
|
+
|
|
770
|
+
if (unpacked.client_id != -1) {
|
|
771
|
+
unpacked.author = {
|
|
772
|
+
ClientInfo: this.client_info(unpacked.client_id),
|
|
773
|
+
PlayerInfo: this.player_info(unpacked.client_id)
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
this.emit("emote", unpacked)
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
} else if (chunk.msgid == NETMSG_Game.SV_BROADCAST) {
|
|
781
|
+
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
|
|
782
|
+
|
|
783
|
+
this.emit("broadcast", unpacker.unpackString());
|
|
784
|
+
} if (chunk.msgid == NETMSG_Game.SV_CHAT) {
|
|
785
|
+
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
|
|
786
|
+
let unpacked: iMessage = {
|
|
641
787
|
team: unpacker.unpackInt(),
|
|
642
788
|
client_id: unpacker.unpackInt(),
|
|
643
789
|
message: unpacker.unpackString()
|
|
@@ -650,14 +796,9 @@ export class Client extends EventEmitter {
|
|
|
650
796
|
}
|
|
651
797
|
}
|
|
652
798
|
this.emit("message", unpacked)
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
var chat = unpacked.chunks.filter(chunk => chunk.msg == "SV_KILL_MSG" || chunk.msg == "SV_MOTD");
|
|
657
|
-
chat.forEach(a => {
|
|
658
|
-
if (a.msg == "SV_KILL_MSG") {
|
|
659
|
-
var unpacked: iKillMsg = {} as iKillMsg;
|
|
660
|
-
let unpacker = new MsgUnpacker(a.raw.toJSON().data);
|
|
799
|
+
} else if (chunk.msgid == NETMSG_Game.SV_KILLMSG) {
|
|
800
|
+
let unpacked: iKillMsg = {} as iKillMsg;
|
|
801
|
+
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
|
|
661
802
|
unpacked.killer_id = unpacker.unpackInt();
|
|
662
803
|
unpacked.victim_id = unpacker.unpackInt();
|
|
663
804
|
unpacked.weapon = unpacker.unpackInt();
|
|
@@ -669,59 +810,22 @@ export class Client extends EventEmitter {
|
|
|
669
810
|
if (unpacked.killer_id != -1 && unpacked.killer_id < 64)
|
|
670
811
|
unpacked.killer = { ClientInfo: this.client_info(unpacked.killer_id), PlayerInfo: this.player_info(unpacked.killer_id) }
|
|
671
812
|
this.emit("kill", unpacked)
|
|
672
|
-
} else if (
|
|
673
|
-
let unpacker = new MsgUnpacker(
|
|
813
|
+
} else if (chunk.msgid == NETMSG_Game.SV_MOTD) {
|
|
814
|
+
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
|
|
674
815
|
let message = unpacker.unpackString();
|
|
675
816
|
this.emit("motd", message);
|
|
676
817
|
}
|
|
677
|
-
})
|
|
678
|
-
|
|
679
|
-
if (unpacked.chunks[0] && chunkMessages.includes("SV_READY_TO_ENTER")) {
|
|
680
|
-
var Msg = new MsgPacker(15, true, 1); /* entergame */
|
|
681
|
-
this.SendMsgEx(Msg);
|
|
682
|
-
} else if ((unpacked.chunks[0] && chunkMessages.includes("CAPABILITIES") || unpacked.chunks[0] && chunkMessages.includes("MAP_CHANGE"))) {
|
|
683
|
-
// send ready
|
|
684
|
-
var Msg = new MsgPacker(14, true, 1); /* ready */
|
|
685
|
-
this.SendMsgEx(Msg);
|
|
686
|
-
} else if ((unpacked.chunks[0] && chunkMessages.includes("CON_READY"))) {
|
|
687
|
-
var info = new MsgPacker(20, false, 1);
|
|
688
|
-
if (this.options?.identity) {
|
|
689
|
-
info.AddString(this.options.identity.name);
|
|
690
|
-
info.AddString(this.options.identity.clan);
|
|
691
|
-
info.AddInt(this.options.identity.country);
|
|
692
|
-
info.AddString(this.options.identity.skin);
|
|
693
|
-
info.AddInt(this.options.identity.use_custom_color);
|
|
694
|
-
info.AddInt(this.options.identity.color_body);
|
|
695
|
-
info.AddInt(this.options.identity.color_feet);
|
|
696
|
-
} else {
|
|
697
|
-
info.AddString(this.name); /* name */
|
|
698
|
-
info.AddString(""); /* clan */
|
|
699
|
-
info.AddInt(-1); /* country */
|
|
700
|
-
info.AddString("greyfox"); /* skin */
|
|
701
|
-
info.AddInt(1); /* use custom color */
|
|
702
|
-
info.AddInt(10346103); /* color body */
|
|
703
|
-
info.AddInt(65535); /* color feet */
|
|
704
|
-
|
|
705
|
-
}
|
|
706
|
-
var crashmeplx = new MsgPacker(17, true, 1); // rcon
|
|
707
|
-
crashmeplx.AddString("crashmeplx"); // 64 player support message
|
|
708
|
-
this.SendMsgEx([info, crashmeplx]);
|
|
709
818
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
if (chunkMessages.includes("SNAP") || chunkMessages.includes("SNAP_EMPTY") || chunkMessages.includes("SNAP_SINGLE")) {
|
|
717
|
-
this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
|
|
718
|
-
if (this.receivedSnaps == 2) {
|
|
719
|
-
if (this.State != States.STATE_ONLINE)
|
|
720
|
-
this.emit('connected')
|
|
721
|
-
this.State = States.STATE_ONLINE;
|
|
819
|
+
// packets neccessary for connection
|
|
820
|
+
// https://ddnet.org/docs/libtw2/connection/
|
|
821
|
+
if (chunk.msgid == NETMSG_Game.SV_READYTOENTER) {
|
|
822
|
+
var Msg = new MsgPacker(15, true, 1); /* entergame */
|
|
823
|
+
this.SendMsgEx(Msg);
|
|
824
|
+
}
|
|
722
825
|
}
|
|
826
|
+
})
|
|
723
827
|
|
|
724
|
-
|
|
828
|
+
|
|
725
829
|
if (new Date().getTime() - this.time >= 1000 && this.State == States.STATE_ONLINE) {
|
|
726
830
|
this.time = new Date().getTime();
|
|
727
831
|
this.SendControlMsg(0);
|
|
@@ -812,4 +916,8 @@ export class Client extends EventEmitter {
|
|
|
812
916
|
.sort((a, b) => a.id - b.id)
|
|
813
917
|
.map(player => player.parsed as PlayerInfo);
|
|
814
918
|
}
|
|
919
|
+
|
|
920
|
+
get VoteOptionList(): string[] {
|
|
921
|
+
return this.VoteList;
|
|
922
|
+
}
|
|
815
923
|
}
|