teeworlds 2.5.2 → 2.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -14,12 +14,58 @@ var __extends = (this && this.__extends) || (function () {
14
14
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
15
  };
16
16
  })();
17
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
+ return new (P || (P = Promise))(function (resolve, reject) {
20
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
21
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
22
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
23
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
24
+ });
25
+ };
26
+ var __generator = (this && this.__generator) || function (thisArg, body) {
27
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
28
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
29
+ function verb(n) { return function (v) { return step([n, v]); }; }
30
+ function step(op) {
31
+ if (f) throw new TypeError("Generator is already executing.");
32
+ while (_) try {
33
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
34
+ if (y = 0, t) op = [op[0] & 2, t.value];
35
+ switch (op[0]) {
36
+ case 0: case 1: t = op; break;
37
+ case 4: _.label++; return { value: op[1], done: false };
38
+ case 5: _.label++; y = op[1]; op = [0]; continue;
39
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
40
+ default:
41
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
42
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
43
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
44
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
45
+ if (t[2]) _.ops.pop();
46
+ _.trys.pop(); continue;
47
+ }
48
+ op = body.call(thisArg, _);
49
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
50
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
+ }
52
+ };
53
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
54
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
55
+ if (ar || !(i in from)) {
56
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
57
+ ar[i] = from[i];
58
+ }
59
+ }
60
+ return to.concat(ar || Array.prototype.slice.call(from));
61
+ };
17
62
  var __importDefault = (this && this.__importDefault) || function (mod) {
18
63
  return (mod && mod.__esModule) ? mod : { "default": mod };
19
64
  };
20
65
  Object.defineProperty(exports, "__esModule", { value: true });
21
66
  exports.Client = void 0;
22
67
  var crypto_1 = require("crypto");
68
+ var dns_1 = require("dns");
23
69
  var dgram_1 = __importDefault(require("dgram"));
24
70
  var stream_1 = require("stream");
25
71
  var MsgUnpacker_1 = require("./MsgUnpacker");
@@ -31,104 +77,9 @@ var huffman_1 = require("./huffman");
31
77
  var game_1 = require("./components/game");
32
78
  var snapshot_2 = require("./components/snapshot");
33
79
  var UUIDManager_1 = require("./UUIDManager");
80
+ var protocol_1 = require("./enums_types/protocol");
81
+ var rcon_1 = require("./components/rcon");
34
82
  var huff = new huffman_1.Huffman();
35
- var States;
36
- (function (States) {
37
- States[States["STATE_OFFLINE"] = 0] = "STATE_OFFLINE";
38
- States[States["STATE_CONNECTING"] = 1] = "STATE_CONNECTING";
39
- States[States["STATE_LOADING"] = 2] = "STATE_LOADING";
40
- States[States["STATE_ONLINE"] = 3] = "STATE_ONLINE";
41
- States[States["STATE_DEMOPLAYBACK"] = 4] = "STATE_DEMOPLAYBACK";
42
- States[States["STATE_QUITTING"] = 5] = "STATE_QUITTING";
43
- States[States["STATE_RESTARTING"] = 6] = "STATE_RESTARTING";
44
- })(States || (States = {}));
45
- var NETMSG_Game;
46
- (function (NETMSG_Game) {
47
- NETMSG_Game[NETMSG_Game["EX"] = 0] = "EX";
48
- NETMSG_Game[NETMSG_Game["SV_MOTD"] = 1] = "SV_MOTD";
49
- NETMSG_Game[NETMSG_Game["SV_BROADCAST"] = 2] = "SV_BROADCAST";
50
- NETMSG_Game[NETMSG_Game["SV_CHAT"] = 3] = "SV_CHAT";
51
- NETMSG_Game[NETMSG_Game["SV_KILLMSG"] = 4] = "SV_KILLMSG";
52
- NETMSG_Game[NETMSG_Game["SV_SOUNDGLOBAL"] = 5] = "SV_SOUNDGLOBAL";
53
- NETMSG_Game[NETMSG_Game["SV_TUNEPARAMS"] = 6] = "SV_TUNEPARAMS";
54
- NETMSG_Game[NETMSG_Game["SV_EXTRAPROJECTILE"] = 7] = "SV_EXTRAPROJECTILE";
55
- NETMSG_Game[NETMSG_Game["SV_READYTOENTER"] = 8] = "SV_READYTOENTER";
56
- NETMSG_Game[NETMSG_Game["SV_WEAPONPICKUP"] = 9] = "SV_WEAPONPICKUP";
57
- NETMSG_Game[NETMSG_Game["SV_EMOTICON"] = 10] = "SV_EMOTICON";
58
- NETMSG_Game[NETMSG_Game["SV_VOTECLEAROPTIONS"] = 11] = "SV_VOTECLEAROPTIONS";
59
- NETMSG_Game[NETMSG_Game["SV_VOTEOPTIONLISTADD"] = 12] = "SV_VOTEOPTIONLISTADD";
60
- NETMSG_Game[NETMSG_Game["SV_VOTEOPTIONADD"] = 13] = "SV_VOTEOPTIONADD";
61
- NETMSG_Game[NETMSG_Game["SV_VOTEOPTIONREMOVE"] = 14] = "SV_VOTEOPTIONREMOVE";
62
- NETMSG_Game[NETMSG_Game["SV_VOTESET"] = 15] = "SV_VOTESET";
63
- NETMSG_Game[NETMSG_Game["SV_VOTESTATUS"] = 16] = "SV_VOTESTATUS";
64
- NETMSG_Game[NETMSG_Game["CL_SAY"] = 17] = "CL_SAY";
65
- NETMSG_Game[NETMSG_Game["CL_SETTEAM"] = 18] = "CL_SETTEAM";
66
- NETMSG_Game[NETMSG_Game["CL_SETSPECTATORMODE"] = 19] = "CL_SETSPECTATORMODE";
67
- NETMSG_Game[NETMSG_Game["CL_STARTINFO"] = 20] = "CL_STARTINFO";
68
- NETMSG_Game[NETMSG_Game["CL_CHANGEINFO"] = 21] = "CL_CHANGEINFO";
69
- NETMSG_Game[NETMSG_Game["CL_KILL"] = 22] = "CL_KILL";
70
- NETMSG_Game[NETMSG_Game["CL_EMOTICON"] = 23] = "CL_EMOTICON";
71
- NETMSG_Game[NETMSG_Game["CL_VOTE"] = 24] = "CL_VOTE";
72
- NETMSG_Game[NETMSG_Game["CL_CALLVOTE"] = 25] = "CL_CALLVOTE";
73
- NETMSG_Game[NETMSG_Game["CL_ISDDNETLEGACY"] = 26] = "CL_ISDDNETLEGACY";
74
- NETMSG_Game[NETMSG_Game["SV_DDRACETIMELEGACY"] = 27] = "SV_DDRACETIMELEGACY";
75
- NETMSG_Game[NETMSG_Game["SV_RECORDLEGACY"] = 28] = "SV_RECORDLEGACY";
76
- NETMSG_Game[NETMSG_Game["UNUSED"] = 29] = "UNUSED";
77
- NETMSG_Game[NETMSG_Game["SV_TEAMSSTATELEGACY"] = 30] = "SV_TEAMSSTATELEGACY";
78
- NETMSG_Game[NETMSG_Game["CL_SHOWOTHERSLEGACY"] = 31] = "CL_SHOWOTHERSLEGACY";
79
- NETMSG_Game[NETMSG_Game["NUM"] = 32] = "NUM";
80
- })(NETMSG_Game || (NETMSG_Game = {}));
81
- var NETMSG_Sys;
82
- (function (NETMSG_Sys) {
83
- NETMSG_Sys[NETMSG_Sys["NETMSG_EX"] = 0] = "NETMSG_EX";
84
- // the first thing sent by the client
85
- // contains the version info for the client
86
- NETMSG_Sys[NETMSG_Sys["NETMSG_INFO"] = 1] = "NETMSG_INFO";
87
- // sent by server
88
- NETMSG_Sys[NETMSG_Sys["NETMSG_MAP_CHANGE"] = 2] = "NETMSG_MAP_CHANGE";
89
- NETMSG_Sys[NETMSG_Sys["NETMSG_MAP_DATA"] = 3] = "NETMSG_MAP_DATA";
90
- NETMSG_Sys[NETMSG_Sys["NETMSG_CON_READY"] = 4] = "NETMSG_CON_READY";
91
- NETMSG_Sys[NETMSG_Sys["NETMSG_SNAP"] = 5] = "NETMSG_SNAP";
92
- NETMSG_Sys[NETMSG_Sys["NETMSG_SNAPEMPTY"] = 6] = "NETMSG_SNAPEMPTY";
93
- NETMSG_Sys[NETMSG_Sys["NETMSG_SNAPSINGLE"] = 7] = "NETMSG_SNAPSINGLE";
94
- NETMSG_Sys[NETMSG_Sys["NETMSG_SNAPSMALL"] = 8] = "NETMSG_SNAPSMALL";
95
- NETMSG_Sys[NETMSG_Sys["NETMSG_INPUTTIMING"] = 9] = "NETMSG_INPUTTIMING";
96
- NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_AUTH_STATUS"] = 10] = "NETMSG_RCON_AUTH_STATUS";
97
- NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_LINE"] = 11] = "NETMSG_RCON_LINE";
98
- NETMSG_Sys[NETMSG_Sys["NETMSG_AUTH_CHALLANGE"] = 12] = "NETMSG_AUTH_CHALLANGE";
99
- NETMSG_Sys[NETMSG_Sys["NETMSG_AUTH_RESULT"] = 13] = "NETMSG_AUTH_RESULT";
100
- // sent by client
101
- NETMSG_Sys[NETMSG_Sys["NETMSG_READY"] = 14] = "NETMSG_READY";
102
- NETMSG_Sys[NETMSG_Sys["NETMSG_ENTERGAME"] = 15] = "NETMSG_ENTERGAME";
103
- NETMSG_Sys[NETMSG_Sys["NETMSG_INPUT"] = 16] = "NETMSG_INPUT";
104
- NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_CMD"] = 17] = "NETMSG_RCON_CMD";
105
- NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_AUTH"] = 18] = "NETMSG_RCON_AUTH";
106
- NETMSG_Sys[NETMSG_Sys["NETMSG_REQUEST_MAP_DATA"] = 19] = "NETMSG_REQUEST_MAP_DATA";
107
- NETMSG_Sys[NETMSG_Sys["NETMSG_AUTH_START"] = 20] = "NETMSG_AUTH_START";
108
- NETMSG_Sys[NETMSG_Sys["NETMSG_AUTH_RESPONSE"] = 21] = "NETMSG_AUTH_RESPONSE";
109
- // sent by both
110
- NETMSG_Sys[NETMSG_Sys["NETMSG_PING"] = 22] = "NETMSG_PING";
111
- NETMSG_Sys[NETMSG_Sys["NETMSG_PING_REPLY"] = 23] = "NETMSG_PING_REPLY";
112
- NETMSG_Sys[NETMSG_Sys["NETMSG_ERROR"] = 24] = "NETMSG_ERROR";
113
- // sent by server (todo: move it up)
114
- NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_CMD_ADD"] = 25] = "NETMSG_RCON_CMD_ADD";
115
- NETMSG_Sys[NETMSG_Sys["NETMSG_RCON_CMD_REM"] = 26] = "NETMSG_RCON_CMD_REM";
116
- NETMSG_Sys[NETMSG_Sys["NUM_NETMSGS"] = 27] = "NUM_NETMSGS";
117
- NETMSG_Sys[NETMSG_Sys["NETMSG_WHATIS"] = 65536] = "NETMSG_WHATIS";
118
- NETMSG_Sys[NETMSG_Sys["NETMSG_ITIS"] = 65537] = "NETMSG_ITIS";
119
- NETMSG_Sys[NETMSG_Sys["NETMSG_IDONTKNOW"] = 65538] = "NETMSG_IDONTKNOW";
120
- NETMSG_Sys[NETMSG_Sys["NETMSG_RCONTYPE"] = 65539] = "NETMSG_RCONTYPE";
121
- NETMSG_Sys[NETMSG_Sys["NETMSG_MAP_DETAILS"] = 65540] = "NETMSG_MAP_DETAILS";
122
- NETMSG_Sys[NETMSG_Sys["NETMSG_CAPABILITIES"] = 65541] = "NETMSG_CAPABILITIES";
123
- NETMSG_Sys[NETMSG_Sys["NETMSG_CLIENTVER"] = 65542] = "NETMSG_CLIENTVER";
124
- NETMSG_Sys[NETMSG_Sys["NETMSG_PINGEX"] = 65543] = "NETMSG_PINGEX";
125
- NETMSG_Sys[NETMSG_Sys["NETMSG_PONGEX"] = 65544] = "NETMSG_PONGEX";
126
- NETMSG_Sys[NETMSG_Sys["NETMSG_CHECKSUM_REQUEST"] = 65545] = "NETMSG_CHECKSUM_REQUEST";
127
- NETMSG_Sys[NETMSG_Sys["NETMSG_CHECKSUM_RESPONSE"] = 65546] = "NETMSG_CHECKSUM_RESPONSE";
128
- NETMSG_Sys[NETMSG_Sys["NETMSG_CHECKSUM_ERROR"] = 65547] = "NETMSG_CHECKSUM_ERROR";
129
- NETMSG_Sys[NETMSG_Sys["NETMSG_REDIRECT"] = 65548] = "NETMSG_REDIRECT";
130
- NETMSG_Sys[NETMSG_Sys["NETMSG_I_AM_NPM_PACKAGE"] = 65549] = "NETMSG_I_AM_NPM_PACKAGE";
131
- })(NETMSG_Sys || (NETMSG_Sys = {}));
132
83
  var messageTypes = [
133
84
  ["none, starts at 1", "SV_MOTD", "SV_BROADCAST", "SV_CHAT", "SV_KILL_MSG", "SV_SOUND_GLOBAL", "SV_TUNE_PARAMS", "SV_EXTRA_PROJECTILE", "SV_READY_TO_ENTER", "SV_WEAPON_PICKUP", "SV_EMOTICON", "SV_VOTE_CLEAR_OPTIONS", "SV_VOTE_OPTION_LIST_ADD", "SV_VOTE_OPTION_ADD", "SV_VOTE_OPTION_REMOVE", "SV_VOTE_SET", "SV_VOTE_STATUS", "CL_SAY", "CL_SET_TEAM", "CL_SET_SPECTATOR_MODE", "CL_START_INFO", "CL_CHANGE_INFO", "CL_KILL", "CL_EMOTICON", "CL_VOTE", "CL_CALL_VOTE", "CL_IS_DDNET", "SV_DDRACE_TIME", "SV_RECORD", "UNUSED", "SV_TEAMS_STATE", "CL_SHOW_OTHERS_LEGACY"],
134
85
  ["none, starts at 1", "INFO", "MAP_CHANGE", "MAP_DATA", "CON_READY", "SNAP", "SNAP_EMPTY", "SNAP_SINGLE", "INPUT_TIMING", "RCON_AUTH_STATUS", "RCON_LINE", "READY", "ENTER_GAME", "INPUT", "RCON_CMD", "RCON_AUTH", "REQUEST_MAP_DATA", "PING", "PING_REPLY", "RCON_CMD_ADD", "RCON_CMD_REMOVE"]
@@ -144,6 +95,7 @@ var Client = /** @class */ (function (_super) {
144
95
  _this.PredGameTick = 0;
145
96
  _this.currentSnapshotGameTick = 0;
146
97
  _this.SnapshotParts = 0;
98
+ _this.rcon = new rcon_1.Rcon(_this);
147
99
  _this.SnapUnpacker = new snapshot_1.Snapshot(_this);
148
100
  // this.eSnapHolder = [];
149
101
  _this.requestResend = false;
@@ -153,9 +105,10 @@ var Client = /** @class */ (function (_super) {
153
105
  _this.snaps = [];
154
106
  _this.sentChunkQueue = [];
155
107
  _this.queueChunkEx = [];
156
- _this.State = States.STATE_OFFLINE; // 0 = offline; 1 = STATE_CONNECTING = 1, STATE_LOADING = 2, STATE_ONLINE = 3
108
+ _this.State = protocol_1.States.STATE_OFFLINE; // 0 = offline; 1 = STATE_CONNECTING = 1, STATE_LOADING = 2, STATE_ONLINE = 3
157
109
  _this.ack = 0; // ack of messages the client has received
158
110
  _this.clientAck = 0; // ack of messages the client has sent
111
+ _this.lastCheckedChunkAck = 0; // this.ack gets reset to this when flushing - used for resetting tick on e.g. map change
159
112
  _this.receivedSnaps = 0; /* wait for 2 snaps before seeing self as connected */
160
113
  _this.socket = dgram_1.default.createSocket("udp4");
161
114
  _this.socket.bind();
@@ -168,22 +121,42 @@ var Client = /** @class */ (function (_super) {
168
121
  _this.game = new game_1.Game(_this);
169
122
  _this.SnapshotUnpacker = new snapshot_2.SnapshotWrapper(_this);
170
123
  _this.UUIDManager = new UUIDManager_1.UUIDManager();
171
- _this.UUIDManager.RegisterName("what-is@ddnet.tw", NETMSG_Sys.NETMSG_WHATIS);
172
- _this.UUIDManager.RegisterName("it-is@ddnet.tw", NETMSG_Sys.NETMSG_ITIS);
173
- _this.UUIDManager.RegisterName("i-dont-know@ddnet.tw", NETMSG_Sys.NETMSG_IDONTKNOW);
174
- _this.UUIDManager.RegisterName("rcon-type@ddnet.tw", NETMSG_Sys.NETMSG_RCONTYPE);
175
- _this.UUIDManager.RegisterName("map-details@ddnet.tw", NETMSG_Sys.NETMSG_MAP_DETAILS);
176
- _this.UUIDManager.RegisterName("capabilities@ddnet.tw", NETMSG_Sys.NETMSG_CAPABILITIES);
177
- _this.UUIDManager.RegisterName("clientver@ddnet.tw", NETMSG_Sys.NETMSG_CLIENTVER);
178
- _this.UUIDManager.RegisterName("ping@ddnet.tw", NETMSG_Sys.NETMSG_PING);
179
- _this.UUIDManager.RegisterName("pong@ddnet.tw", NETMSG_Sys.NETMSG_PONGEX);
180
- _this.UUIDManager.RegisterName("checksum-request@ddnet.tw", NETMSG_Sys.NETMSG_CHECKSUM_REQUEST);
181
- _this.UUIDManager.RegisterName("checksum-response@ddnet.tw", NETMSG_Sys.NETMSG_CHECKSUM_RESPONSE);
182
- _this.UUIDManager.RegisterName("checksum-error@ddnet.tw", NETMSG_Sys.NETMSG_CHECKSUM_ERROR);
183
- _this.UUIDManager.RegisterName("redirect@ddnet.org", NETMSG_Sys.NETMSG_REDIRECT);
184
- _this.UUIDManager.RegisterName("i-am-npm-package@swarfey.gitlab.io", NETMSG_Sys.NETMSG_I_AM_NPM_PACKAGE);
124
+ _this.UUIDManager.RegisterName("what-is@ddnet.tw", 65536 /* NETMSG.System.NETMSG_WHATIS */);
125
+ _this.UUIDManager.RegisterName("it-is@ddnet.tw", 65537 /* NETMSG.System.NETMSG_ITIS */);
126
+ _this.UUIDManager.RegisterName("i-dont-know@ddnet.tw", 65538 /* NETMSG.System.NETMSG_IDONTKNOW */);
127
+ _this.UUIDManager.RegisterName("rcon-type@ddnet.tw", 65539 /* NETMSG.System.NETMSG_RCONTYPE */);
128
+ _this.UUIDManager.RegisterName("map-details@ddnet.tw", 65540 /* NETMSG.System.NETMSG_MAP_DETAILS */);
129
+ _this.UUIDManager.RegisterName("capabilities@ddnet.tw", 65541 /* NETMSG.System.NETMSG_CAPABILITIES */);
130
+ _this.UUIDManager.RegisterName("clientver@ddnet.tw", 65542 /* NETMSG.System.NETMSG_CLIENTVER */);
131
+ _this.UUIDManager.RegisterName("ping@ddnet.tw", 22 /* NETMSG.System.NETMSG_PING */);
132
+ _this.UUIDManager.RegisterName("pong@ddnet.tw", 65544 /* NETMSG.System.NETMSG_PONGEX */);
133
+ _this.UUIDManager.RegisterName("checksum-request@ddnet.tw", 65545 /* NETMSG.System.NETMSG_CHECKSUM_REQUEST */);
134
+ _this.UUIDManager.RegisterName("checksum-response@ddnet.tw", 65546 /* NETMSG.System.NETMSG_CHECKSUM_RESPONSE */);
135
+ _this.UUIDManager.RegisterName("checksum-error@ddnet.tw", 65547 /* NETMSG.System.NETMSG_CHECKSUM_ERROR */);
136
+ _this.UUIDManager.RegisterName("redirect@ddnet.org", 65548 /* NETMSG.System.NETMSG_REDIRECT */);
137
+ _this.UUIDManager.RegisterName("i-am-npm-package@swarfey.gitlab.io", 65549 /* NETMSG.System.NETMSG_I_AM_NPM_PACKAGE */);
185
138
  return _this;
186
139
  }
140
+ Client.prototype.on = function (event, listener) {
141
+ return _super.prototype.on.call(this, event, listener);
142
+ };
143
+ Client.prototype.emit = function (event) {
144
+ var args = [];
145
+ for (var _i = 1; _i < arguments.length; _i++) {
146
+ args[_i - 1] = arguments[_i];
147
+ }
148
+ return _super.prototype.emit.apply(this, __spreadArray([event], args, false));
149
+ };
150
+ Client.prototype.OnEnterGame = function () {
151
+ this.snaps = [];
152
+ this.SnapUnpacker = new snapshot_1.Snapshot(this);
153
+ this.SnapshotParts = 0;
154
+ this.receivedSnaps = 0;
155
+ this.SnapshotUnpacker = new snapshot_2.SnapshotWrapper(this);
156
+ this.currentSnapshotGameTick = 0;
157
+ this.AckGameTick = -1;
158
+ this.PredGameTick = 0;
159
+ };
187
160
  Client.prototype.ResendAfter = function (lastAck) {
188
161
  this.clientAck = lastAck;
189
162
  var toResend = [];
@@ -211,7 +184,6 @@ var Client = /** @class */ (function (_super) {
211
184
  var chunk = {};
212
185
  chunk.bytes = ((packet[0] & 0x3f) << 4) | (packet[1] & ((1 << 4) - 1));
213
186
  chunk.flags = (packet[0] >> 6) & 3;
214
- chunk.sequence = -1;
215
187
  if (chunk.flags & 1) {
216
188
  chunk.seq = ((packet[1] & 0xf0) << 2) | packet[2];
217
189
  packet = packet.slice(3); // remove flags & size
@@ -261,7 +233,7 @@ var Client = /** @class */ (function (_super) {
261
233
  Client.prototype.SendMsgEx = function (Msgs, flags) {
262
234
  var _this = this;
263
235
  if (flags === void 0) { flags = 0; }
264
- if (this.State == States.STATE_OFFLINE)
236
+ if (this.State == protocol_1.States.STATE_OFFLINE)
265
237
  return;
266
238
  if (!this.socket)
267
239
  return;
@@ -317,13 +289,31 @@ var Client = /** @class */ (function (_super) {
317
289
  return;
318
290
  this.socket.send(packet, 0, packet.length, this.port, this.host);
319
291
  };
320
- /** Queue a chunk (It will get sent in the next packet). */
292
+ /** Queue a chunk (instantly sent if flush flag is set - otherwise it will be sent in the next packet). */
321
293
  Client.prototype.QueueChunkEx = function (Msg) {
294
+ if (Msg instanceof Array) {
295
+ for (var _i = 0, Msg_1 = Msg; _i < Msg_1.length; _i++) {
296
+ var chunk = Msg_1[_i];
297
+ this.QueueChunkEx(chunk);
298
+ }
299
+ return;
300
+ }
301
+ if (this.queueChunkEx.length > 0) {
302
+ var total_size = 0;
303
+ for (var _a = 0, _b = this.queueChunkEx; _a < _b.length; _a++) {
304
+ var chunk = _b[_a];
305
+ total_size += chunk.size;
306
+ }
307
+ if (total_size + Msg.size + 3 > 1394 - 4)
308
+ this.Flush();
309
+ }
322
310
  this.queueChunkEx.push(Msg);
311
+ if (Msg.flag & 4)
312
+ this.Flush();
323
313
  };
324
314
  /** Send a Raw Buffer (as chunk) to the server. */
325
315
  Client.prototype.SendMsgRaw = function (chunks) {
326
- if (this.State == States.STATE_OFFLINE)
316
+ if (this.State == protocol_1.States.STATE_OFFLINE)
327
317
  return;
328
318
  if (!this.socket)
329
319
  return;
@@ -338,7 +328,6 @@ var Client = /** @class */ (function (_super) {
338
328
  var chunk = {};
339
329
  chunk.bytes = ((packet[0] & 0x3f) << 4) | (packet[1] & ((1 << 4) - 1));
340
330
  chunk.flags = (packet[0] >> 6) & 3;
341
- chunk.sequence = -1;
342
331
  if (chunk.flags & 1) {
343
332
  chunk.seq = ((packet[1] & 0xf0) << 2) | packet[2];
344
333
  packet = packet.slice(3); // remove flags & size
@@ -361,394 +350,428 @@ var Client = /** @class */ (function (_super) {
361
350
  }
362
351
  return chunk;
363
352
  };
353
+ Client.prototype.Flush = function () {
354
+ // if (this.queueChunkEx.length == 0)
355
+ console.log("flushing");
356
+ this.SendMsgEx(this.queueChunkEx);
357
+ this.queueChunkEx = [];
358
+ this.ack = this.lastCheckedChunkAck;
359
+ };
364
360
  /** Connect the client to the server. */
365
361
  Client.prototype.connect = function () {
366
- var _this = this;
367
362
  var _a;
368
- this.State = States.STATE_CONNECTING;
369
- var predTimer = setInterval(function () {
370
- if (_this.State == States.STATE_ONLINE) {
371
- if (_this.AckGameTick > 0)
372
- _this.PredGameTick++;
373
- }
374
- else if (_this.State == States.STATE_OFFLINE)
375
- clearInterval(predTimer);
376
- }, 1000 / 50); // 50 ticks per second
377
- this.SendControlMsg(1, "TKEN");
378
- var connectInterval = setInterval(function () {
379
- if (_this.State == States.STATE_CONNECTING)
380
- _this.SendControlMsg(1, "TKEN");
381
- else
382
- clearInterval(connectInterval);
383
- }, 500);
384
- if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight)) {
385
- var inputInterval_1 = setInterval(function () {
386
- if (_this.State == States.STATE_OFFLINE)
387
- clearInterval(inputInterval_1);
388
- if (_this.State != States.STATE_ONLINE)
389
- return;
390
- _this.time = new Date().getTime();
391
- _this.sendInput();
392
- }, 50);
393
- }
394
- var resendTimeout = setInterval(function () {
395
- if (_this.State != States.STATE_OFFLINE) {
396
- if (((new Date().getTime()) - _this.lastSendTime) > 900 && _this.sentChunkQueue.length > 0) {
397
- _this.SendMsgRaw([_this.sentChunkQueue[0]]);
363
+ return __awaiter(this, void 0, void 0, function () {
364
+ var predTimer, connectInterval, inputInterval_1, resendTimeout, Timeout;
365
+ var _this = this;
366
+ return __generator(this, function (_b) {
367
+ // test via regex whether or not this.host is a domain or an ip
368
+ // if not, resolve it
369
+ if (!this.host.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) {
370
+ (0, dns_1.lookup)(this.host, 4, function (err, address, family) {
371
+ if (err)
372
+ throw err;
373
+ _this.host = address;
374
+ console.log(err, address, family);
375
+ });
398
376
  }
399
- }
400
- else
401
- clearInterval(resendTimeout);
402
- }, 1000);
403
- var Timeout = setInterval(function () {
404
- var _a;
405
- var timeoutTime = ((_a = _this.options) === null || _a === void 0 ? void 0 : _a.timeout) ? _this.options.timeout : 15000;
406
- if ((new Date().getTime() - _this.lastRecvTime) > timeoutTime) {
407
- _this.State = States.STATE_OFFLINE;
408
- _this.emit("timeout");
409
- _this.emit("disconnect", "Timed Out. (no packets received for " + (new Date().getTime() - _this.lastRecvTime) + "ms)");
410
- clearInterval(Timeout);
411
- }
412
- }, 5000);
413
- this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
414
- if (this.socket)
415
- this.socket.on("message", function (packet, rinfo) {
416
- var _a, _b, _c, _d, _e, _f;
417
- if (_this.State == 0 || rinfo.address != _this.host || rinfo.port != _this.port)
418
- return;
419
- clearInterval(connectInterval);
420
- if (packet[0] == 0x10) {
421
- if (packet.toString().includes("TKEN") || packet[3] == 0x2) {
377
+ this.State = protocol_1.States.STATE_CONNECTING;
378
+ predTimer = setInterval(function () {
379
+ if (_this.State == protocol_1.States.STATE_ONLINE) {
380
+ if (_this.AckGameTick > 0)
381
+ _this.PredGameTick++;
382
+ }
383
+ else if (_this.State == protocol_1.States.STATE_OFFLINE)
384
+ clearInterval(predTimer);
385
+ }, 1000 / 50);
386
+ this.SendControlMsg(1, "TKEN");
387
+ connectInterval = setInterval(function () {
388
+ if (_this.State == protocol_1.States.STATE_CONNECTING)
389
+ _this.SendControlMsg(1, "TKEN");
390
+ else
422
391
  clearInterval(connectInterval);
423
- _this.TKEN = packet.slice(-4);
424
- _this.SendControlMsg(3);
425
- _this.State = States.STATE_LOADING; // loading state
426
- _this.receivedSnaps = 0;
427
- var info = new MsgPacker_1.MsgPacker(1, true, 1);
428
- info.AddString(((_a = _this.options) === null || _a === void 0 ? void 0 : _a.NET_VERSION) ? _this.options.NET_VERSION : "0.6 626fce9a778df4d4");
429
- info.AddString(((_b = _this.options) === null || _b === void 0 ? void 0 : _b.password) === undefined ? "" : (_c = _this.options) === null || _c === void 0 ? void 0 : _c.password); // password
430
- var client_version = new MsgPacker_1.MsgPacker(0, true, 1);
431
- client_version.AddBuffer(Buffer.from("8c00130484613e478787f672b3835bd4", 'hex'));
432
- var randomUuid = (0, crypto_1.randomBytes)(16);
433
- client_version.AddBuffer(randomUuid);
434
- if (((_d = _this.options) === null || _d === void 0 ? void 0 : _d.ddnet_version) !== undefined) {
435
- client_version.AddInt((_e = _this.options) === null || _e === void 0 ? void 0 : _e.ddnet_version.version);
436
- client_version.AddString("DDNet ".concat((_f = _this.options) === null || _f === void 0 ? void 0 : _f.ddnet_version.release_version, "; https://www.npmjs.com/package/teeworlds/v/").concat(version));
437
- }
438
- else {
439
- client_version.AddInt(16050);
440
- client_version.AddString("DDNet 16.5.0; https://www.npmjs.com/package/teeworlds/v/".concat(version));
392
+ }, 500);
393
+ if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight)) {
394
+ inputInterval_1 = setInterval(function () {
395
+ if (_this.State == protocol_1.States.STATE_OFFLINE) {
396
+ clearInterval(inputInterval_1);
397
+ // console.log("???");
441
398
  }
442
- var i_am_npm_package = new MsgPacker_1.MsgPacker(0, true, 1);
443
- i_am_npm_package.AddBuffer(_this.UUIDManager.LookupType(NETMSG_Sys.NETMSG_I_AM_NPM_PACKAGE).hash);
444
- i_am_npm_package.AddString("https://www.npmjs.com/package/teeworlds/v/".concat(version));
445
- _this.SendMsgEx([i_am_npm_package, client_version, info]);
446
- }
447
- else if (packet[3] == 0x4) {
448
- // disconnected
449
- _this.State = States.STATE_OFFLINE;
450
- var reason = ((0, MsgUnpacker_1.unpackString)(packet.slice(4)).result);
451
- _this.emit("disconnect", reason);
452
- }
453
- if (packet[3] !== 0x0) { // keepalive
454
- _this.lastRecvTime = new Date().getTime();
455
- }
399
+ if (_this.State != protocol_1.States.STATE_ONLINE)
400
+ return;
401
+ _this.time = new Date().getTime();
402
+ _this.sendInput();
403
+ }, 50);
456
404
  }
457
- else {
458
- _this.lastRecvTime = new Date().getTime();
459
- }
460
- var unpacked = _this.Unpack(packet);
461
- unpacked.chunks = unpacked.chunks.filter(function (chunk) { return ((chunk.flags & 2) && (chunk.flags & 1)) ? chunk.seq > _this.ack : true; }); // filter out already received chunks
462
- unpacked.chunks.forEach(function (chunk) {
463
- if (chunk.flags & 1 && (chunk.flags !== 15)) { // vital and not connless
464
- if (chunk.seq === (_this.ack + 1) % (1 << 10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
465
- _this.ack = chunk.seq;
466
- _this.requestResend = false;
467
- }
468
- else { //IsSeqInBackroom (old packet that we already got)
469
- var Bottom = (_this.ack - (1 << 10) / 2);
470
- if (Bottom < 0) {
471
- if ((chunk.seq <= _this.ack) || (chunk.seq >= (Bottom + (1 << 10))))
472
- return;
473
- }
474
- else {
475
- if (chunk.seq <= _this.ack && chunk.seq >= Bottom)
476
- return;
477
- }
478
- _this.requestResend = true;
405
+ resendTimeout = setInterval(function () {
406
+ if (_this.State != protocol_1.States.STATE_OFFLINE) {
407
+ if (((new Date().getTime()) - _this.lastSendTime) > 900 && _this.sentChunkQueue.length > 0) {
408
+ _this.SendMsgRaw([_this.sentChunkQueue[0]]);
479
409
  }
480
410
  }
481
- });
482
- _this.sentChunkQueue.forEach(function (buff, i) {
483
- var chunkFlags = (buff[0] >> 6) & 3;
484
- if (chunkFlags & 1) {
485
- var chunk = _this.MsgToChunk(buff);
486
- if (chunk.seq && chunk.seq >= _this.ack)
487
- _this.sentChunkQueue.splice(i, 1);
488
- }
489
- });
490
- unpacked.chunks.forEach(function (chunk, index) {
411
+ else
412
+ clearInterval(resendTimeout);
413
+ }, 1000);
414
+ Timeout = setInterval(function () {
491
415
  var _a;
492
- var _b;
493
- if (chunk.sys) {
494
- // system messages
495
- if (chunk.msgid == NETMSG_Sys.NETMSG_PING) { // ping
496
- var packer = new MsgPacker_1.MsgPacker(NETMSG_Sys.NETMSG_PING_REPLY, true, 0);
497
- _this.SendMsgEx(packer); // send ping reply
498
- }
499
- else if (chunk.msgid == NETMSG_Sys.NETMSG_PING_REPLY) { // Ping reply
500
- _this.game._ping_resolve(new Date().getTime());
501
- }
502
- // packets neccessary for connection
503
- // https://ddnet.org/docs/libtw2/connection/
504
- if (chunk.msgid == NETMSG_Sys.NETMSG_MAP_CHANGE) {
505
- var Msg = new MsgPacker_1.MsgPacker(NETMSG_Sys.NETMSG_READY, true, 1); /* ready */
506
- _this.SendMsgEx(Msg);
507
- }
508
- else if (chunk.msgid == NETMSG_Sys.NETMSG_CON_READY) {
509
- var info = new MsgPacker_1.MsgPacker(NETMSG_Game.CL_STARTINFO, false, 1);
510
- if ((_b = _this.options) === null || _b === void 0 ? void 0 : _b.identity) {
511
- info.AddString(_this.options.identity.name);
512
- info.AddString(_this.options.identity.clan);
513
- info.AddInt(_this.options.identity.country);
514
- info.AddString(_this.options.identity.skin);
515
- info.AddInt(_this.options.identity.use_custom_color);
516
- info.AddInt(_this.options.identity.color_body);
517
- info.AddInt(_this.options.identity.color_feet);
416
+ var timeoutTime = ((_a = _this.options) === null || _a === void 0 ? void 0 : _a.timeout) ? _this.options.timeout : 15000;
417
+ if ((new Date().getTime() - _this.lastRecvTime) > timeoutTime) {
418
+ _this.State = protocol_1.States.STATE_OFFLINE;
419
+ _this.emit("disconnect", "Timed Out. (no packets received for " + (new Date().getTime() - _this.lastRecvTime) + "ms)");
420
+ clearInterval(Timeout);
421
+ }
422
+ }, 5000);
423
+ this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
424
+ if (this.socket)
425
+ this.socket.on("message", function (packet, rinfo) {
426
+ var _a, _b, _c, _d, _e, _f;
427
+ if (_this.State == 0 || rinfo.address != _this.host || rinfo.port != _this.port)
428
+ return;
429
+ clearInterval(connectInterval);
430
+ if (packet[0] == 0x10) {
431
+ if (packet.toString().includes("TKEN") || packet[3] == 0x2) {
432
+ clearInterval(connectInterval);
433
+ _this.TKEN = packet.slice(-4);
434
+ _this.SendControlMsg(3);
435
+ _this.State = protocol_1.States.STATE_LOADING; // loading state
436
+ _this.receivedSnaps = 0;
437
+ var info = new MsgPacker_1.MsgPacker(1, true, 1);
438
+ info.AddString(((_a = _this.options) === null || _a === void 0 ? void 0 : _a.NET_VERSION) ? _this.options.NET_VERSION : "0.6 626fce9a778df4d4");
439
+ info.AddString(((_b = _this.options) === null || _b === void 0 ? void 0 : _b.password) === undefined ? "" : (_c = _this.options) === null || _c === void 0 ? void 0 : _c.password); // password
440
+ var client_version = new MsgPacker_1.MsgPacker(0, true, 1);
441
+ client_version.AddBuffer(Buffer.from("8c00130484613e478787f672b3835bd4", 'hex'));
442
+ var randomUuid = (0, crypto_1.randomBytes)(16);
443
+ client_version.AddBuffer(randomUuid);
444
+ if (((_d = _this.options) === null || _d === void 0 ? void 0 : _d.ddnet_version) !== undefined) {
445
+ client_version.AddInt((_e = _this.options) === null || _e === void 0 ? void 0 : _e.ddnet_version.version);
446
+ client_version.AddString("DDNet ".concat((_f = _this.options) === null || _f === void 0 ? void 0 : _f.ddnet_version.release_version, "; https://www.npmjs.com/package/teeworlds/v/").concat(version));
447
+ }
448
+ else {
449
+ client_version.AddInt(16050);
450
+ client_version.AddString("DDNet 16.5.0; https://www.npmjs.com/package/teeworlds/v/".concat(version));
451
+ }
452
+ var i_am_npm_package = new MsgPacker_1.MsgPacker(0, true, 1);
453
+ i_am_npm_package.AddBuffer(_this.UUIDManager.LookupType(65549 /* NETMSG.System.NETMSG_I_AM_NPM_PACKAGE */).hash);
454
+ i_am_npm_package.AddString("https://www.npmjs.com/package/teeworlds/v/".concat(version));
455
+ _this.SendMsgEx([i_am_npm_package, client_version, info]);
518
456
  }
519
- else {
520
- info.AddString(_this.name); /* name */
521
- info.AddString(""); /* clan */
522
- info.AddInt(-1); /* country */
523
- info.AddString("greyfox"); /* skin */
524
- info.AddInt(1); /* use custom color */
525
- info.AddInt(10346103); /* color body */
526
- info.AddInt(65535); /* color feet */
457
+ else if (packet[3] == 0x4) {
458
+ // disconnected
459
+ _this.State = protocol_1.States.STATE_OFFLINE;
460
+ var reason = ((0, MsgUnpacker_1.unpackString)(packet.slice(4)).result);
461
+ _this.emit("disconnect", reason);
527
462
  }
528
- var crashmeplx = new MsgPacker_1.MsgPacker(17, true, 1); // rcon
529
- crashmeplx.AddString("crashmeplx"); // 64 player support message
530
- _this.SendMsgEx([info, crashmeplx]);
531
- }
532
- if (chunk.msgid >= NETMSG_Sys.NETMSG_SNAP && chunk.msgid <= NETMSG_Sys.NETMSG_SNAPSINGLE) {
533
- _this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
534
- if (_this.receivedSnaps == 2) {
535
- if (_this.State != States.STATE_ONLINE)
536
- _this.emit('connected');
537
- _this.State = States.STATE_ONLINE;
463
+ if (packet[3] !== 0x0) { // keepalive
464
+ _this.lastRecvTime = new Date().getTime();
538
465
  }
539
- if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
540
- _this.PredGameTick = _this.AckGameTick + 1;
541
- // snapChunks.forEach(chunk => {
542
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
543
- var NumParts = 1;
544
- var Part = 0;
545
- var GameTick = unpacker.unpackInt();
546
- var DeltaTick = GameTick - unpacker.unpackInt();
547
- var PartSize = 0;
548
- var Crc = 0;
549
- var CompleteSize = 0;
550
- if (chunk.msgid == NETMSG_Sys.NETMSG_SNAP) {
551
- NumParts = unpacker.unpackInt();
552
- Part = unpacker.unpackInt();
466
+ }
467
+ else {
468
+ _this.lastRecvTime = new Date().getTime();
469
+ }
470
+ var unpacked = _this.Unpack(packet);
471
+ // unpacked.chunks = unpacked.chunks.filter(chunk => ((chunk.flags & 2) && (chunk.flags & 1)) ? chunk.seq! > this.ack : true); // filter out already received chunks
472
+ _this.sentChunkQueue.forEach(function (buff, i) {
473
+ var chunkFlags = (buff[0] >> 6) & 3;
474
+ if (chunkFlags & 1) {
475
+ var chunk = _this.MsgToChunk(buff);
476
+ if (chunk.seq && chunk.seq >= _this.ack)
477
+ _this.sentChunkQueue.splice(i, 1);
553
478
  }
554
- if (chunk.msgid != NETMSG_Sys.NETMSG_SNAPEMPTY) {
555
- Crc = unpacker.unpackInt();
556
- PartSize = unpacker.unpackInt();
479
+ });
480
+ unpacked.chunks.forEach(function (chunk) {
481
+ var _a;
482
+ var _b;
483
+ if (!(((chunk.flags & 2) && (chunk.flags & 1)) ? chunk.seq > _this.ack : true))
484
+ return; // filter out already received chunks
485
+ if (chunk.flags & 1 && (chunk.flags !== 15)) { // vital and not connless
486
+ _this.lastCheckedChunkAck = chunk.seq;
487
+ if (chunk.seq === (_this.ack + 1) % (1 << 10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
488
+ _this.ack = chunk.seq;
489
+ _this.requestResend = false;
490
+ }
491
+ else { //IsSeqInBackroom (old packet that we already got)
492
+ var Bottom = (_this.ack - (1 << 10) / 2);
493
+ if (Bottom < 0) {
494
+ if ((chunk.seq <= _this.ack) || (chunk.seq >= (Bottom + (1 << 10)))) { }
495
+ else
496
+ _this.requestResend = true;
497
+ }
498
+ else {
499
+ if (chunk.seq <= _this.ack && chunk.seq >= Bottom) { }
500
+ else
501
+ _this.requestResend = true;
502
+ }
503
+ }
557
504
  }
558
- if (NumParts < 1 || NumParts > 64 || Part < 0 || Part >= NumParts || PartSize < 0 || PartSize > 900)
559
- return;
560
- if (GameTick >= _this.currentSnapshotGameTick) {
561
- if (GameTick != _this.currentSnapshotGameTick) {
562
- _this.snaps = [];
563
- _this.SnapshotParts = 0;
564
- _this.currentSnapshotGameTick = GameTick;
505
+ if (chunk.sys) {
506
+ // system messages
507
+ if (chunk.msgid == 22 /* NETMSG.System.NETMSG_PING */) { // ping
508
+ var packer = new MsgPacker_1.MsgPacker(23 /* NETMSG.System.NETMSG_PING_REPLY */, true, 0);
509
+ _this.SendMsgEx(packer); // send ping reply
565
510
  }
566
- // chunk.raw = Buffer.from(unpacker.remaining);
567
- _this.snaps[Part] = unpacker.remaining;
568
- _this.SnapshotParts |= 1 << Part;
569
- if (_this.SnapshotParts == ((1 << NumParts) - 1)) {
570
- var mergedSnaps = Buffer.concat(_this.snaps);
571
- _this.SnapshotParts = 0;
572
- var snapUnpacked = _this.SnapUnpacker.unpackSnapshot(mergedSnaps, DeltaTick, GameTick, Crc);
573
- _this.emit("snapshot", snapUnpacked.items);
574
- _this.AckGameTick = snapUnpacked.recvTick;
575
- if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10) {
511
+ else if (chunk.msgid == 23 /* NETMSG.System.NETMSG_PING_REPLY */) { // Ping reply
512
+ _this.game._ping_resolve(new Date().getTime());
513
+ }
514
+ else if (_this.rcon._checkChunks(chunk)) { }
515
+ // packets neccessary for connection
516
+ // https://ddnet.org/docs/libtw2/connection/
517
+ if (chunk.msgid == 2 /* NETMSG.System.NETMSG_MAP_CHANGE */) {
518
+ _this.Flush();
519
+ var Msg = new MsgPacker_1.MsgPacker(14 /* NETMSG.System.NETMSG_READY */, true, 1); /* ready */
520
+ _this.SendMsgEx(Msg);
521
+ }
522
+ else if (chunk.msgid == 4 /* NETMSG.System.NETMSG_CON_READY */) {
523
+ var info = new MsgPacker_1.MsgPacker(20 /* NETMSG.Game.CL_STARTINFO */, false, 1);
524
+ if ((_b = _this.options) === null || _b === void 0 ? void 0 : _b.identity) {
525
+ info.AddString(_this.options.identity.name);
526
+ info.AddString(_this.options.identity.clan);
527
+ info.AddInt(_this.options.identity.country);
528
+ info.AddString(_this.options.identity.skin);
529
+ info.AddInt(_this.options.identity.use_custom_color);
530
+ info.AddInt(_this.options.identity.color_body);
531
+ info.AddInt(_this.options.identity.color_feet);
532
+ }
533
+ else {
534
+ info.AddString(_this.name); /* name */
535
+ info.AddString(""); /* clan */
536
+ info.AddInt(-1); /* country */
537
+ info.AddString("greyfox"); /* skin */
538
+ info.AddInt(1); /* use custom color */
539
+ info.AddInt(10346103); /* color body */
540
+ info.AddInt(65535); /* color feet */
541
+ }
542
+ var crashmeplx = new MsgPacker_1.MsgPacker(17, true, 1); // rcon
543
+ crashmeplx.AddString("crashmeplx"); // 64 player support message
544
+ _this.SendMsgEx([info, crashmeplx]);
545
+ }
546
+ if (chunk.msgid >= 5 /* NETMSG.System.NETMSG_SNAP */ && chunk.msgid <= 7 /* NETMSG.System.NETMSG_SNAPSINGLE */) {
547
+ _this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
548
+ if (_this.receivedSnaps == 2) {
549
+ if (_this.State != protocol_1.States.STATE_ONLINE)
550
+ _this.emit('connected');
551
+ _this.State = protocol_1.States.STATE_ONLINE;
552
+ }
553
+ if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
576
554
  _this.PredGameTick = _this.AckGameTick + 1;
577
- _this.sendInput();
555
+ // snapChunks.forEach(chunk => {
556
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
557
+ var NumParts = 1;
558
+ var Part = 0;
559
+ var GameTick = unpacker.unpackInt();
560
+ var DeltaTick = GameTick - unpacker.unpackInt();
561
+ var PartSize = 0;
562
+ var Crc = 0;
563
+ var CompleteSize = 0;
564
+ if (chunk.msgid == 5 /* NETMSG.System.NETMSG_SNAP */) {
565
+ NumParts = unpacker.unpackInt();
566
+ Part = unpacker.unpackInt();
567
+ }
568
+ if (chunk.msgid != 6 /* NETMSG.System.NETMSG_SNAPEMPTY */) {
569
+ Crc = unpacker.unpackInt();
570
+ PartSize = unpacker.unpackInt();
571
+ }
572
+ if (NumParts < 1 || NumParts > 64 || Part < 0 || Part >= NumParts || PartSize < 0 || PartSize > 900)
573
+ return;
574
+ if (GameTick >= _this.currentSnapshotGameTick) {
575
+ if (GameTick != _this.currentSnapshotGameTick) {
576
+ _this.snaps = [];
577
+ _this.SnapshotParts = 0;
578
+ _this.currentSnapshotGameTick = GameTick;
579
+ }
580
+ // chunk.raw = Buffer.from(unpacker.remaining);
581
+ _this.snaps[Part] = unpacker.remaining;
582
+ _this.SnapshotParts |= 1 << Part;
583
+ if (_this.SnapshotParts == ((1 << NumParts) - 1)) {
584
+ var mergedSnaps = Buffer.concat(_this.snaps);
585
+ _this.SnapshotParts = 0;
586
+ var snapUnpacked = _this.SnapUnpacker.unpackSnapshot(mergedSnaps, DeltaTick, GameTick, Crc);
587
+ _this.emit("snapshot", snapUnpacked.items);
588
+ _this.AckGameTick = snapUnpacked.recvTick;
589
+ if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10) {
590
+ _this.PredGameTick = _this.AckGameTick + 1;
591
+ _this.sendInput();
592
+ }
593
+ }
594
+ }
595
+ // })
596
+ }
597
+ if (chunk.msgid >= 65536 /* NETMSG.System.NETMSG_WHATIS */ && chunk.msgid <= 65547 /* NETMSG.System.NETMSG_CHECKSUM_ERROR */) {
598
+ if (chunk.msgid == 65536 /* NETMSG.System.NETMSG_WHATIS */) {
599
+ var Uuid = chunk.raw.slice(0, 16);
600
+ var uuid = _this.UUIDManager.LookupUUID(Uuid);
601
+ var packer = new MsgPacker_1.MsgPacker(0, true, 1);
602
+ if (uuid !== undefined) {
603
+ // IT_IS msg
604
+ packer.AddBuffer(_this.UUIDManager.LookupType(65537 /* NETMSG.System.NETMSG_ITIS */).hash);
605
+ packer.AddBuffer(Uuid);
606
+ packer.AddString(uuid.name);
607
+ }
608
+ else {
609
+ // dont_know msg
610
+ packer.AddBuffer(_this.UUIDManager.LookupType(65538 /* NETMSG.System.NETMSG_IDONTKNOW */).hash);
611
+ packer.AddBuffer(Uuid);
612
+ }
613
+ _this.QueueChunkEx(packer);
614
+ }
615
+ if (chunk.msgid == 65540 /* NETMSG.System.NETMSG_MAP_DETAILS */) { // TODO: option for downloading maps
616
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
617
+ var map_name = unpacker.unpackString();
618
+ var map_sha256 = Buffer.alloc(32);
619
+ if (unpacker.remaining.length >= 32)
620
+ map_sha256 = unpacker.unpackRaw(32);
621
+ var map_crc = unpacker.unpackInt();
622
+ var map_size = unpacker.unpackInt();
623
+ var map_url = "";
624
+ if (unpacker.remaining.length)
625
+ map_url = unpacker.unpackString();
626
+ _this.emit("map_details", { map_name: map_name, map_sha256: map_sha256, map_crc: map_crc, map_size: map_size, map_url: map_url });
627
+ // unpacker.unpack
628
+ }
629
+ else if (chunk.msgid == 65541 /* NETMSG.System.NETMSG_CAPABILITIES */) {
630
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
631
+ var Version = unpacker.unpackInt();
632
+ var Flags = unpacker.unpackInt();
633
+ if (Version <= 0)
634
+ return;
635
+ var DDNet = false;
636
+ if (Version >= 1) {
637
+ DDNet = Boolean(Flags & 1);
638
+ }
639
+ var ChatTimeoutCode = DDNet;
640
+ var AnyPlayerFlag = DDNet;
641
+ var PingEx = false;
642
+ var AllowDummy = true;
643
+ var SyncWeaponInput = false;
644
+ if (Version >= 1) {
645
+ ChatTimeoutCode = Boolean(Flags & 2);
646
+ }
647
+ if (Version >= 2) {
648
+ AnyPlayerFlag = Boolean(Flags & 4);
649
+ }
650
+ if (Version >= 3) {
651
+ PingEx = Boolean(Flags & 8);
652
+ }
653
+ if (Version >= 4) {
654
+ AllowDummy = Boolean(Flags & 16);
655
+ }
656
+ if (Version >= 5) {
657
+ SyncWeaponInput = Boolean(Flags & 32);
658
+ }
659
+ _this.emit("capabilities", { ChatTimeoutCode: ChatTimeoutCode, AnyPlayerFlag: AnyPlayerFlag, PingEx: PingEx, AllowDummy: AllowDummy, SyncWeaponInput: SyncWeaponInput });
660
+ // https://github.com/ddnet/ddnet/blob/06e3eb564150e9ab81b3a5595c48e9fe5952ed32/src/engine/client/client.cpp#L1565
661
+ }
662
+ else if (chunk.msgid == 65543 /* NETMSG.System.NETMSG_PINGEX */) {
663
+ var packer = new MsgPacker_1.MsgPacker(0, true, 2);
664
+ packer.AddBuffer(_this.UUIDManager.LookupType(65544 /* NETMSG.System.NETMSG_PONGEX */).hash);
665
+ _this.SendMsgEx(packer, 2);
578
666
  }
579
667
  }
580
668
  }
581
- // })
582
- }
583
- if (chunk.msgid >= NETMSG_Sys.NETMSG_WHATIS && chunk.msgid <= NETMSG_Sys.NETMSG_CHECKSUM_ERROR) {
584
- if (chunk.msgid == NETMSG_Sys.NETMSG_WHATIS) {
585
- var Uuid = chunk.raw.slice(0, 16);
586
- var uuid = _this.UUIDManager.LookupUUID(Uuid);
587
- var packer = new MsgPacker_1.MsgPacker(0, true, 1);
588
- if (uuid !== undefined) {
589
- // IT_IS msg
590
- packer.AddBuffer(_this.UUIDManager.LookupType(NETMSG_Sys.NETMSG_ITIS).hash);
591
- packer.AddBuffer(Uuid);
592
- packer.AddString(uuid.name);
669
+ else {
670
+ // game messages
671
+ // vote list:
672
+ if (chunk.msgid == 11 /* NETMSG.Game.SV_VOTECLEAROPTIONS */) {
673
+ _this.VoteList = [];
593
674
  }
594
- else {
595
- // dont_know msg
596
- packer.AddBuffer(_this.UUIDManager.LookupType(NETMSG_Sys.NETMSG_IDONTKNOW).hash);
597
- packer.AddBuffer(Uuid);
675
+ else if (chunk.msgid == 12 /* NETMSG.Game.SV_VOTEOPTIONLISTADD */) {
676
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
677
+ var NumOptions = unpacker.unpackInt();
678
+ var list = [];
679
+ for (var i = 0; i < 15; i++) {
680
+ list.push(unpacker.unpackString());
681
+ }
682
+ list = list.slice(0, NumOptions);
683
+ (_a = _this.VoteList).push.apply(_a, list);
598
684
  }
599
- _this.QueueChunkEx(packer);
600
- }
601
- if (chunk.msgid == NETMSG_Sys.NETMSG_MAP_DETAILS) { // TODO: option for downloading maps
602
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
603
- var map_name = unpacker.unpackString();
604
- var map_sha256 = Buffer.alloc(32);
605
- if (unpacker.remaining.length >= 32)
606
- map_sha256 = unpacker.unpackRaw(32);
607
- var map_crc = unpacker.unpackInt();
608
- var map_size = unpacker.unpackInt();
609
- var map_url = "";
610
- if (unpacker.remaining.length)
611
- map_url = unpacker.unpackString();
612
- _this.emit("map_details", { map_name: map_name, map_sha256: map_sha256, map_crc: map_crc, map_size: map_size, map_url: map_url });
613
- // unpacker.unpack
614
- }
615
- else if (chunk.msgid == NETMSG_Sys.NETMSG_CAPABILITIES) {
616
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
617
- var Version = unpacker.unpackInt();
618
- var Flags = unpacker.unpackInt();
619
- if (Version <= 0)
620
- return;
621
- var DDNet = false;
622
- if (Version >= 1) {
623
- DDNet = Boolean(Flags & 1);
685
+ else if (chunk.msgid == 13 /* NETMSG.Game.SV_VOTEOPTIONADD */) {
686
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
687
+ _this.VoteList.push(unpacker.unpackString());
624
688
  }
625
- var ChatTimeoutCode = DDNet;
626
- var AnyPlayerFlag = DDNet;
627
- var PingEx = false;
628
- var AllowDummy = true;
629
- var SyncWeaponInput = false;
630
- if (Version >= 1) {
631
- ChatTimeoutCode = Boolean(Flags & 2);
689
+ else if (chunk.msgid == 14 /* NETMSG.Game.SV_VOTEOPTIONREMOVE */) {
690
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
691
+ var index = _this.VoteList.indexOf(unpacker.unpackString());
692
+ if (index > -1)
693
+ _this.VoteList = _this.VoteList.splice(index, 1);
632
694
  }
633
- if (Version >= 2) {
634
- AnyPlayerFlag = Boolean(Flags & 4);
695
+ // events
696
+ if (chunk.msgid == 10 /* NETMSG.Game.SV_EMOTICON */) {
697
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
698
+ var unpacked_1 = {
699
+ client_id: unpacker.unpackInt(),
700
+ emoticon: unpacker.unpackInt()
701
+ };
702
+ if (unpacked_1.client_id != -1) {
703
+ unpacked_1.author = {
704
+ ClientInfo: _this.SnapshotUnpacker.getObjClientInfo(unpacked_1.client_id),
705
+ PlayerInfo: _this.SnapshotUnpacker.getObjPlayerInfo(unpacked_1.client_id)
706
+ };
707
+ }
708
+ _this.emit("emote", unpacked_1);
635
709
  }
636
- if (Version >= 3) {
637
- PingEx = Boolean(Flags & 8);
710
+ else if (chunk.msgid == 2 /* NETMSG.Game.SV_BROADCAST */) {
711
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
712
+ _this.emit("broadcast", unpacker.unpackString());
638
713
  }
639
- if (Version >= 4) {
640
- AllowDummy = Boolean(Flags & 16);
714
+ if (chunk.msgid == 3 /* NETMSG.Game.SV_CHAT */) {
715
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
716
+ var unpacked_2 = {
717
+ team: unpacker.unpackInt(),
718
+ client_id: unpacker.unpackInt(),
719
+ message: unpacker.unpackString()
720
+ };
721
+ if (unpacked_2.client_id != -1) {
722
+ unpacked_2.author = {
723
+ ClientInfo: _this.SnapshotUnpacker.getObjClientInfo(unpacked_2.client_id),
724
+ PlayerInfo: _this.SnapshotUnpacker.getObjPlayerInfo(unpacked_2.client_id)
725
+ };
726
+ }
727
+ _this.emit("message", unpacked_2);
641
728
  }
642
- if (Version >= 5) {
643
- SyncWeaponInput = Boolean(Flags & 32);
729
+ else if (chunk.msgid == 4 /* NETMSG.Game.SV_KILLMSG */) {
730
+ var unpacked_3 = {};
731
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
732
+ unpacked_3.killer_id = unpacker.unpackInt();
733
+ unpacked_3.victim_id = unpacker.unpackInt();
734
+ unpacked_3.weapon = unpacker.unpackInt();
735
+ unpacked_3.special_mode = unpacker.unpackInt();
736
+ if (unpacked_3.victim_id != -1 && unpacked_3.victim_id < 64) {
737
+ unpacked_3.victim = { ClientInfo: _this.SnapshotUnpacker.getObjClientInfo(unpacked_3.victim_id), PlayerInfo: _this.SnapshotUnpacker.getObjPlayerInfo(unpacked_3.victim_id) };
738
+ }
739
+ if (unpacked_3.killer_id != -1 && unpacked_3.killer_id < 64)
740
+ unpacked_3.killer = { ClientInfo: _this.SnapshotUnpacker.getObjClientInfo(unpacked_3.killer_id), PlayerInfo: _this.SnapshotUnpacker.getObjPlayerInfo(unpacked_3.killer_id) };
741
+ _this.emit("kill", unpacked_3);
742
+ }
743
+ else if (chunk.msgid == 1 /* NETMSG.Game.SV_MOTD */) {
744
+ var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
745
+ var message = unpacker.unpackString();
746
+ _this.emit("motd", message);
747
+ }
748
+ // packets neccessary for connection
749
+ // https://ddnet.org/docs/libtw2/connection/
750
+ if (chunk.msgid == 8 /* NETMSG.Game.SV_READYTOENTER */) {
751
+ var Msg = new MsgPacker_1.MsgPacker(15 /* NETMSG.System.NETMSG_ENTERGAME */, true, 1); /* entergame */
752
+ _this.SendMsgEx(Msg);
753
+ _this.OnEnterGame();
644
754
  }
645
- _this.emit("capabilities", { ChatTimeoutCode: ChatTimeoutCode, AnyPlayerFlag: AnyPlayerFlag, PingEx: PingEx, AllowDummy: AllowDummy, SyncWeaponInput: SyncWeaponInput });
646
- // https://github.com/ddnet/ddnet/blob/06e3eb564150e9ab81b3a5595c48e9fe5952ed32/src/engine/client/client.cpp#L1565
647
- }
648
- else if (chunk.msgid == NETMSG_Sys.NETMSG_PINGEX) {
649
- var packer = new MsgPacker_1.MsgPacker(0, true, 2);
650
- packer.AddBuffer(_this.UUIDManager.LookupType(NETMSG_Sys.NETMSG_PONGEX).hash);
651
- _this.SendMsgEx(packer, 2);
652
- }
653
- }
654
- }
655
- else {
656
- // game messages
657
- // vote list:
658
- if (chunk.msgid == NETMSG_Game.SV_VOTECLEAROPTIONS) {
659
- _this.VoteList = [];
660
- }
661
- else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONLISTADD) {
662
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
663
- var NumOptions = unpacker.unpackInt();
664
- var list = [];
665
- for (var i = 0; i < 15; i++) {
666
- list.push(unpacker.unpackString());
667
- }
668
- list = list.slice(0, NumOptions);
669
- (_a = _this.VoteList).push.apply(_a, list);
670
- }
671
- else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONADD) {
672
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
673
- _this.VoteList.push(unpacker.unpackString());
674
- }
675
- else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONREMOVE) {
676
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
677
- var index_1 = _this.VoteList.indexOf(unpacker.unpackString());
678
- if (index_1 > -1)
679
- _this.VoteList = _this.VoteList.splice(index_1, 1);
680
- }
681
- // events
682
- if (chunk.msgid == NETMSG_Game.SV_EMOTICON) {
683
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
684
- var unpacked_1 = {
685
- client_id: unpacker.unpackInt(),
686
- emoticon: unpacker.unpackInt()
687
- };
688
- if (unpacked_1.client_id != -1) {
689
- unpacked_1.author = {
690
- ClientInfo: _this.SnapshotUnpacker.getObjClientInfo(unpacked_1.client_id),
691
- PlayerInfo: _this.SnapshotUnpacker.getObjPlayerInfo(unpacked_1.client_id)
692
- };
693
755
  }
694
- _this.emit("emote", unpacked_1);
695
- }
696
- else if (chunk.msgid == NETMSG_Game.SV_BROADCAST) {
697
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
698
- _this.emit("broadcast", unpacker.unpackString());
699
- }
700
- if (chunk.msgid == NETMSG_Game.SV_CHAT) {
701
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
702
- var unpacked_2 = {
703
- team: unpacker.unpackInt(),
704
- client_id: unpacker.unpackInt(),
705
- message: unpacker.unpackString()
706
- };
707
- if (unpacked_2.client_id != -1) {
708
- unpacked_2.author = {
709
- ClientInfo: _this.SnapshotUnpacker.getObjClientInfo(unpacked_2.client_id),
710
- PlayerInfo: _this.SnapshotUnpacker.getObjPlayerInfo(unpacked_2.client_id)
711
- };
756
+ });
757
+ if (_this.State == protocol_1.States.STATE_ONLINE) {
758
+ if (new Date().getTime() - _this.time >= 500) {
759
+ _this.Flush();
712
760
  }
713
- _this.emit("message", unpacked_2);
714
- }
715
- else if (chunk.msgid == NETMSG_Game.SV_KILLMSG) {
716
- var unpacked_3 = {};
717
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
718
- unpacked_3.killer_id = unpacker.unpackInt();
719
- unpacked_3.victim_id = unpacker.unpackInt();
720
- unpacked_3.weapon = unpacker.unpackInt();
721
- unpacked_3.special_mode = unpacker.unpackInt();
722
- if (unpacked_3.victim_id != -1 && unpacked_3.victim_id < 64) {
723
- unpacked_3.victim = { ClientInfo: _this.SnapshotUnpacker.getObjClientInfo(unpacked_3.victim_id), PlayerInfo: _this.SnapshotUnpacker.getObjPlayerInfo(unpacked_3.victim_id) };
761
+ if (new Date().getTime() - _this.time >= 1000) {
762
+ _this.time = new Date().getTime();
763
+ _this.SendControlMsg(0);
724
764
  }
725
- if (unpacked_3.killer_id != -1 && unpacked_3.killer_id < 64)
726
- unpacked_3.killer = { ClientInfo: _this.SnapshotUnpacker.getObjClientInfo(unpacked_3.killer_id), PlayerInfo: _this.SnapshotUnpacker.getObjPlayerInfo(unpacked_3.killer_id) };
727
- _this.emit("kill", unpacked_3);
728
765
  }
729
- else if (chunk.msgid == NETMSG_Game.SV_MOTD) {
730
- var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw);
731
- var message = unpacker.unpackString();
732
- _this.emit("motd", message);
733
- }
734
- // packets neccessary for connection
735
- // https://ddnet.org/docs/libtw2/connection/
736
- if (chunk.msgid == NETMSG_Game.SV_READYTOENTER) {
737
- var Msg = new MsgPacker_1.MsgPacker(15, true, 1); /* entergame */
738
- _this.SendMsgEx(Msg);
739
- }
740
- }
741
- });
742
- if (new Date().getTime() - _this.time >= 1000 && _this.State == States.STATE_ONLINE) {
743
- _this.time = new Date().getTime();
744
- _this.SendControlMsg(0);
745
- }
766
+ });
767
+ return [2 /*return*/];
746
768
  });
769
+ });
747
770
  };
748
771
  /** Sending the input. (automatically done unless options.lightweight is on) */
749
772
  Client.prototype.sendInput = function (input) {
750
773
  if (input === void 0) { input = this.movement.input; }
751
- if (this.State != States.STATE_ONLINE)
774
+ if (this.State != protocol_1.States.STATE_ONLINE)
752
775
  return;
753
776
  var inputMsg = new MsgPacker_1.MsgPacker(16, true, 0);
754
777
  inputMsg.AddInt(this.AckGameTick);
@@ -783,7 +806,7 @@ var Client = /** @class */ (function (_super) {
783
806
  if (_this.socket)
784
807
  _this.socket.close();
785
808
  _this.socket = undefined;
786
- _this.State = States.STATE_OFFLINE;
809
+ _this.State = protocol_1.States.STATE_OFFLINE;
787
810
  });
788
811
  });
789
812
  };