teeworlds 2.5.3 → 2.5.5

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.ts CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
 
3
3
  import { randomBytes } from "crypto";
4
-
4
+ import { lookup as dnsLookup } from 'dns';
5
5
  import net from 'dgram';
6
6
  import { EventEmitter } from 'stream';
7
7
 
@@ -9,146 +9,20 @@ import { unpackString, MsgUnpacker } from "./MsgUnpacker";
9
9
  let { version } = require('../package.json');
10
10
 
11
11
  import Movement from './components/movement';
12
- import { PlayerInput, PlayerInfo, Projectile, Laser, Pickup, Flag, GameInfo, GameData, CharacterCore, Character, ClientInfo, SpectatorInfo, Common, Explosion, Spawn, HammerHit, Death, SoundGlobal, SoundWorld, DamageInd } from "./snapshots";
12
+ import { _Packet, Chunk, DeltaItem, SnapshotItemTypes } from './enums_types/types';
13
13
 
14
14
  import { MsgPacker } from './MsgPacker';
15
- import { Item, Snapshot } from './snapshot';
15
+ import { Snapshot } from './snapshot';
16
16
  import { Huffman } from "./huffman";
17
17
  import { Game } from "./components/game";
18
18
  import { SnapshotWrapper } from "./components/snapshot";
19
19
 
20
20
  import { UUIDManager } from "./UUIDManager";
21
+ import { NETMSG, States } from "./enums_types/protocol";
22
+ import { Rcon } from "./components/rcon";
21
23
 
22
24
  const huff = new Huffman();
23
25
 
24
- enum States {
25
- STATE_OFFLINE = 0,
26
- STATE_CONNECTING,
27
- STATE_LOADING,
28
- STATE_ONLINE,
29
- STATE_DEMOPLAYBACK,
30
- STATE_QUITTING,
31
- STATE_RESTARTING
32
- }
33
-
34
-
35
- enum NETMSG_Game {
36
- EX,
37
- SV_MOTD,
38
- SV_BROADCAST,
39
- SV_CHAT,
40
- SV_KILLMSG,
41
- SV_SOUNDGLOBAL,
42
- SV_TUNEPARAMS,
43
- SV_EXTRAPROJECTILE,
44
- SV_READYTOENTER,
45
- SV_WEAPONPICKUP,
46
- SV_EMOTICON,
47
- SV_VOTECLEAROPTIONS,
48
- SV_VOTEOPTIONLISTADD,
49
- SV_VOTEOPTIONADD,
50
- SV_VOTEOPTIONREMOVE,
51
- SV_VOTESET,
52
- SV_VOTESTATUS,
53
- CL_SAY,
54
- CL_SETTEAM,
55
- CL_SETSPECTATORMODE,
56
- CL_STARTINFO,
57
- CL_CHANGEINFO,
58
- CL_KILL,
59
- CL_EMOTICON,
60
- CL_VOTE,
61
- CL_CALLVOTE,
62
- CL_ISDDNETLEGACY,
63
- SV_DDRACETIMELEGACY,
64
- SV_RECORDLEGACY,
65
- UNUSED,
66
- SV_TEAMSSTATELEGACY,
67
- CL_SHOWOTHERSLEGACY,
68
- NUM
69
- }
70
-
71
- enum NETMSG_Sys {
72
- NETMSG_EX = 0,
73
-
74
- // the first thing sent by the client
75
- // contains the version info for the client
76
- NETMSG_INFO = 1,
77
-
78
- // sent by server
79
- NETMSG_MAP_CHANGE, // sent when client should switch map
80
- NETMSG_MAP_DATA, // map transfer, contains a chunk of the map file
81
- NETMSG_CON_READY, // connection is ready, client should send start info
82
- NETMSG_SNAP, // normal snapshot, multiple parts
83
- NETMSG_SNAPEMPTY, // empty snapshot
84
- NETMSG_SNAPSINGLE, // ?
85
- NETMSG_SNAPSMALL, //
86
- NETMSG_INPUTTIMING, // reports how off the input was
87
- NETMSG_RCON_AUTH_STATUS, // result of the authentication
88
- NETMSG_RCON_LINE, // line that should be printed to the remote console
89
-
90
- NETMSG_AUTH_CHALLANGE, //
91
- NETMSG_AUTH_RESULT, //
92
-
93
- // sent by client
94
- NETMSG_READY, //
95
- NETMSG_ENTERGAME,
96
- NETMSG_INPUT, // contains the inputdata from the client
97
- NETMSG_RCON_CMD, //
98
- NETMSG_RCON_AUTH, //
99
- NETMSG_REQUEST_MAP_DATA, //
100
-
101
- NETMSG_AUTH_START, //
102
- NETMSG_AUTH_RESPONSE, //
103
-
104
- // sent by both
105
- NETMSG_PING,
106
- NETMSG_PING_REPLY,
107
- NETMSG_ERROR,
108
-
109
- // sent by server (todo: move it up)
110
- NETMSG_RCON_CMD_ADD,
111
- NETMSG_RCON_CMD_REM,
112
-
113
- NUM_NETMSGS,
114
-
115
- NETMSG_WHATIS = 65536,
116
- NETMSG_ITIS,
117
- NETMSG_IDONTKNOW,
118
-
119
- NETMSG_RCONTYPE,
120
- NETMSG_MAP_DETAILS,
121
- NETMSG_CAPABILITIES,
122
- NETMSG_CLIENTVER,
123
- NETMSG_PINGEX,
124
- NETMSG_PONGEX,
125
- NETMSG_CHECKSUM_REQUEST,
126
- NETMSG_CHECKSUM_RESPONSE,
127
- NETMSG_CHECKSUM_ERROR,
128
-
129
- NETMSG_REDIRECT,
130
-
131
- NETMSG_I_AM_NPM_PACKAGE
132
-
133
- }
134
-
135
- interface chunk {
136
- bytes: number,
137
- flags: number,
138
- seq?: number,
139
- // type: 'sys' | 'game',
140
- sys: Boolean,
141
- msgid: number,
142
- msg: string,
143
- raw: Buffer,
144
- extended_msgid?: Buffer;
145
- }
146
-
147
- interface _packet {
148
- twprotocol: { flags: number, ack: number, chunkAmount: number, size: number },
149
- chunks: chunk[]
150
- }
151
-
152
26
  var messageTypes = [
153
27
  ["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"],
154
28
  ["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"]
@@ -158,27 +32,27 @@ var messageTypes = [
158
32
  declare interface iMessage {
159
33
  team: number,
160
34
  client_id: number,
161
- author?: { ClientInfo?: ClientInfo, PlayerInfo?: PlayerInfo },
35
+ author?: { ClientInfo?: SnapshotItemTypes.ClientInfo, PlayerInfo?: SnapshotItemTypes.PlayerInfo },
162
36
  message: string
163
37
  }
164
38
 
165
39
  declare interface iEmoticon {
166
40
  client_id: number,
167
41
  emoticon: number,
168
- author?: { ClientInfo?: ClientInfo, PlayerInfo?: PlayerInfo }
42
+ author?: { ClientInfo?: SnapshotItemTypes.ClientInfo, PlayerInfo?: SnapshotItemTypes.PlayerInfo }
169
43
  }
170
44
 
171
45
  declare interface iKillMsg {
172
46
  killer_id: number,
173
- killer?: { ClientInfo?: ClientInfo, PlayerInfo?: PlayerInfo },
47
+ killer?: { ClientInfo?: SnapshotItemTypes.ClientInfo, PlayerInfo?: SnapshotItemTypes.PlayerInfo },
174
48
  victim_id: number,
175
- victim?: { ClientInfo?: ClientInfo, PlayerInfo?: PlayerInfo },
49
+ victim?: { ClientInfo?: SnapshotItemTypes.ClientInfo, PlayerInfo?: SnapshotItemTypes.PlayerInfo },
176
50
  weapon: number,
177
51
  special_mode: number
178
52
  }
179
53
 
180
54
  declare interface iOptions {
181
- identity?: ClientInfo,
55
+ identity?: SnapshotItemTypes.ClientInfo,
182
56
  password?: string,
183
57
  ddnet_version?: {version: number, release_version: string},
184
58
  timeout?: number, // in ms
@@ -186,26 +60,30 @@ declare interface iOptions {
186
60
  lightweight?: boolean // experimental, only sends keepalive's (sendinput has to be called manually)
187
61
  }
188
62
 
189
- export declare interface Client {
190
-
191
-
192
- on(event: 'connected', listener: () => void): this;
193
- on(event: 'disconnect', listener: (reason: string) => void): this;
194
-
195
- on(event: 'emote', listener: (message: iEmoticon) => void): this;
196
- on(event: 'message', listener: (message: iMessage) => void): this;
197
- on(event: 'broadcast', listener: (message: string) => void): this;
198
- on(event: 'kill', listener: (kill: iKillMsg) => void): this;
199
- on(event: 'motd', listener: (message: string) => void): this;
200
-
201
- on(event: 'map_details', listener: (message: {map_name: string, map_sha256: Buffer, map_crc: number, map_size: number, map_url: string}) => void): this;
202
- on(event: 'capabilities', listener: (message: {ChatTimeoutCode: boolean, AnyPlayerFlag: boolean, PingEx: boolean, AllowDummy: boolean, SyncWeaponInput: boolean}) => void): this;
203
-
204
- on(event: 'snapshot', listener: (items: Item[]) => void): this;
63
+ interface ClientEvents {
64
+ connected: () => void;
65
+ disconnect: (reason: string) => void;
66
+ emote: (message: iEmoticon) => void;
67
+ message: (message: iMessage) => void;
68
+ broadcast: (message: string) => void;
69
+ kill: (kill: iKillMsg) => void;
70
+ motd: (message: string) => void;
71
+ map_details: (message: { map_name: string, map_sha256: Buffer, map_crc: number, map_size: number, map_url: string }) => void;
72
+ capabilities: (message: { ChatTimeoutCode: boolean, AnyPlayerFlag: boolean, PingEx: boolean, AllowDummy: boolean, SyncWeaponInput: boolean }) => void;
73
+ snapshot: (items: DeltaItem[]) => void;
74
+ rcon_line: (line: string) => void;
205
75
  }
206
76
 
207
77
  export class Client extends EventEmitter {
208
-
78
+ on<K extends keyof ClientEvents>(event: K, listener: ClientEvents[K]): this {
79
+ return super.on(event, listener);
80
+ }
81
+
82
+ emit<K extends keyof ClientEvents>(event: K, ...args: Parameters<ClientEvents[K]>): boolean {
83
+ return super.emit(event, ...args);
84
+ }
85
+
86
+ public rcon: Rcon;
209
87
  private host: string;
210
88
  private port: number;
211
89
  private name: string;
@@ -260,7 +138,7 @@ export class Client extends EventEmitter {
260
138
  this.currentSnapshotGameTick = 0;
261
139
 
262
140
  this.SnapshotParts = 0;
263
-
141
+ this.rcon = new Rcon(this);
264
142
  this.SnapUnpacker = new Snapshot(this);
265
143
  // this.eSnapHolder = [];
266
144
  this.requestResend = false;
@@ -298,22 +176,32 @@ export class Client extends EventEmitter {
298
176
 
299
177
  this.UUIDManager = new UUIDManager();
300
178
 
301
- this.UUIDManager.RegisterName("what-is@ddnet.tw", NETMSG_Sys.NETMSG_WHATIS);
302
- this.UUIDManager.RegisterName("it-is@ddnet.tw", NETMSG_Sys.NETMSG_ITIS);
303
- this.UUIDManager.RegisterName("i-dont-know@ddnet.tw", NETMSG_Sys.NETMSG_IDONTKNOW);
304
-
305
- this.UUIDManager.RegisterName("rcon-type@ddnet.tw", NETMSG_Sys.NETMSG_RCONTYPE);
306
- this.UUIDManager.RegisterName("map-details@ddnet.tw", NETMSG_Sys.NETMSG_MAP_DETAILS);
307
- this.UUIDManager.RegisterName("capabilities@ddnet.tw", NETMSG_Sys.NETMSG_CAPABILITIES);
308
- this.UUIDManager.RegisterName("clientver@ddnet.tw", NETMSG_Sys.NETMSG_CLIENTVER);
309
- this.UUIDManager.RegisterName("ping@ddnet.tw", NETMSG_Sys.NETMSG_PING);
310
- this.UUIDManager.RegisterName("pong@ddnet.tw", NETMSG_Sys.NETMSG_PONGEX);
311
- this.UUIDManager.RegisterName("checksum-request@ddnet.tw", NETMSG_Sys.NETMSG_CHECKSUM_REQUEST);
312
- this.UUIDManager.RegisterName("checksum-response@ddnet.tw", NETMSG_Sys.NETMSG_CHECKSUM_RESPONSE);
313
- this.UUIDManager.RegisterName("checksum-error@ddnet.tw", NETMSG_Sys.NETMSG_CHECKSUM_ERROR);
314
- this.UUIDManager.RegisterName("redirect@ddnet.org", NETMSG_Sys.NETMSG_REDIRECT);
315
-
316
- this.UUIDManager.RegisterName("i-am-npm-package@swarfey.gitlab.io", NETMSG_Sys.NETMSG_I_AM_NPM_PACKAGE);
179
+ this.UUIDManager.RegisterName("what-is@ddnet.tw", NETMSG.System.NETMSG_WHATIS);
180
+ this.UUIDManager.RegisterName("it-is@ddnet.tw", NETMSG.System.NETMSG_ITIS);
181
+ this.UUIDManager.RegisterName("i-dont-know@ddnet.tw", NETMSG.System.NETMSG_IDONTKNOW);
182
+
183
+ this.UUIDManager.RegisterName("rcon-type@ddnet.tw", NETMSG.System.NETMSG_RCONTYPE);
184
+ this.UUIDManager.RegisterName("map-details@ddnet.tw", NETMSG.System.NETMSG_MAP_DETAILS);
185
+ this.UUIDManager.RegisterName("capabilities@ddnet.tw", NETMSG.System.NETMSG_CAPABILITIES);
186
+ this.UUIDManager.RegisterName("clientver@ddnet.tw", NETMSG.System.NETMSG_CLIENTVER);
187
+ this.UUIDManager.RegisterName("ping@ddnet.tw", NETMSG.System.NETMSG_PING);
188
+ this.UUIDManager.RegisterName("pong@ddnet.tw", NETMSG.System.NETMSG_PONGEX);
189
+ this.UUIDManager.RegisterName("checksum-request@ddnet.tw", NETMSG.System.NETMSG_CHECKSUM_REQUEST);
190
+ this.UUIDManager.RegisterName("checksum-response@ddnet.tw", NETMSG.System.NETMSG_CHECKSUM_RESPONSE);
191
+ this.UUIDManager.RegisterName("checksum-error@ddnet.tw", NETMSG.System.NETMSG_CHECKSUM_ERROR);
192
+ this.UUIDManager.RegisterName("redirect@ddnet.org", NETMSG.System.NETMSG_REDIRECT);
193
+
194
+
195
+ this.UUIDManager.RegisterName("rcon-cmd-group-start@ddnet.org", NETMSG.System.NETMSG_RCON_CMD_GROUP_START) // not implemented
196
+ this.UUIDManager.RegisterName("rcon-cmd-group-end@ddnet.org", NETMSG.System.NETMSG_RCON_CMD_GROUP_END) // not implemented
197
+ this.UUIDManager.RegisterName("map-reload@ddnet.org", NETMSG.System.NETMSG_MAP_RELOAD) // not implemented
198
+ this.UUIDManager.RegisterName("reconnect@ddnet.org", NETMSG.System.NETMSG_RECONNECT) // implemented
199
+ this.UUIDManager.RegisterName("sv-maplist-add@ddnet.org", NETMSG.System.NETMSG_MAPLIST_ADD) // not implemented
200
+ this.UUIDManager.RegisterName("sv-maplist-start@ddnet.org", NETMSG.System.NETMSG_MAPLIST_GROUP_START) // not implemented
201
+ this.UUIDManager.RegisterName("sv-maplist-end@ddnet.org", NETMSG.System.NETMSG_MAPLIST_GROUP_END) // not implemented
202
+
203
+
204
+ this.UUIDManager.RegisterName("i-am-npm-package@swarfey.gitlab.io", NETMSG.System.NETMSG_I_AM_NPM_PACKAGE);
317
205
 
318
206
  }
319
207
 
@@ -340,8 +228,8 @@ export class Client extends EventEmitter {
340
228
  this.SendMsgEx(toResend);
341
229
  }
342
230
 
343
- private Unpack(packet: Buffer): _packet {
344
- var unpacked: _packet = { twprotocol: { flags: packet[0] >> 4, ack: ((packet[0]&0xf)<<8) | packet[1], chunkAmount: packet[2], size: packet.byteLength - 3 }, chunks: [] }
231
+ private Unpack(packet: Buffer): _Packet {
232
+ var unpacked: _Packet = { twprotocol: { flags: packet[0] >> 4, ack: ((packet[0]&0xf)<<8) | packet[1], chunkAmount: packet[2], size: packet.byteLength - 3 }, chunks: [] }
345
233
 
346
234
 
347
235
  if (packet.indexOf(Buffer.from([0xff, 0xff, 0xff, 0xff])) == 0 )// !(unpacked.twprotocol.flags & 8) || unpacked.twprotocol.flags == 255) // flags == 255 is connectionless (used for sending usernames)
@@ -359,7 +247,7 @@ export class Client extends EventEmitter {
359
247
 
360
248
 
361
249
  for (let i = 0; i < unpacked.twprotocol.chunkAmount; i++) {
362
- var chunk: chunk = {} as chunk;
250
+ var chunk: Chunk = {} as Chunk;
363
251
  chunk.bytes = ((packet[0] & 0x3f) << 4) | (packet[1] & ((1 << 4) - 1));
364
252
  chunk.flags = (packet[0] >> 6) & 3;
365
253
 
@@ -472,7 +360,12 @@ export class Client extends EventEmitter {
472
360
  }
473
361
 
474
362
  /** Queue a chunk (instantly sent if flush flag is set - otherwise it will be sent in the next packet). */
475
- QueueChunkEx(Msg: MsgPacker) {
363
+ QueueChunkEx(Msg: MsgPacker | MsgPacker[]) {
364
+ if (Msg instanceof Array) {
365
+ for (let chunk of Msg)
366
+ this.QueueChunkEx(chunk);
367
+ return;
368
+ }
476
369
  if (this.queueChunkEx.length > 0) {
477
370
  let total_size = 0;
478
371
  for (let chunk of this.queueChunkEx)
@@ -503,7 +396,7 @@ export class Client extends EventEmitter {
503
396
  }
504
397
 
505
398
  private MsgToChunk(packet: Buffer) {
506
- var chunk: chunk = {} as chunk;
399
+ var chunk: Chunk = {} as Chunk;
507
400
  chunk.bytes = ((packet[0] & 0x3f) << 4) | (packet[1] & ((1 << 4) - 1));
508
401
  chunk.flags = (packet[0] >> 6) & 3;
509
402
 
@@ -539,7 +432,16 @@ export class Client extends EventEmitter {
539
432
  }
540
433
 
541
434
  /** Connect the client to the server. */
542
- connect() {
435
+ async connect() {
436
+ // test via regex whether or not this.host is a domain or an ip
437
+ // if not, resolve it
438
+ if (!this.host.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) {
439
+ dnsLookup(this.host, 4, (err, address, family) => {
440
+ if (err) throw err;
441
+ this.host = address;
442
+ })
443
+ }
444
+
543
445
  this.State = States.STATE_CONNECTING;
544
446
 
545
447
  let predTimer = setInterval(() => {
@@ -558,11 +460,12 @@ export class Client extends EventEmitter {
558
460
  else
559
461
  clearInterval(connectInterval)
560
462
  }, 500);
463
+ let inputInterval: NodeJS.Timeout;
561
464
  if (!this.options?.lightweight) {
562
- let inputInterval = setInterval(() => {
465
+ inputInterval = setInterval(() => {
563
466
  if (this.State == States.STATE_OFFLINE) {
564
467
  clearInterval(inputInterval)
565
- console.log("???");
468
+ // console.log("???");
566
469
  }
567
470
  if (this.State != States.STATE_ONLINE)
568
471
  return;
@@ -584,7 +487,6 @@ export class Client extends EventEmitter {
584
487
  let timeoutTime = this.options?.timeout ? this.options.timeout : 15000;
585
488
  if ((new Date().getTime() - this.lastRecvTime) > timeoutTime) {
586
489
  this.State = States.STATE_OFFLINE;
587
- this.emit("timeout");
588
490
  this.emit("disconnect", "Timed Out. (no packets received for " + (new Date().getTime() - this.lastRecvTime) + "ms)");
589
491
  clearInterval(Timeout);
590
492
  }
@@ -624,7 +526,7 @@ export class Client extends EventEmitter {
624
526
  }
625
527
 
626
528
  var i_am_npm_package = new MsgPacker(0, true, 1);
627
- i_am_npm_package.AddBuffer(this.UUIDManager.LookupType(NETMSG_Sys.NETMSG_I_AM_NPM_PACKAGE)!.hash);
529
+ i_am_npm_package.AddBuffer(this.UUIDManager.LookupType(NETMSG.System.NETMSG_I_AM_NPM_PACKAGE)!.hash);
628
530
 
629
531
  i_am_npm_package.AddString(`https://www.npmjs.com/package/teeworlds/v/${version}`);
630
532
 
@@ -643,7 +545,7 @@ export class Client extends EventEmitter {
643
545
  this.lastRecvTime = new Date().getTime();
644
546
  }
645
547
 
646
- var unpacked: _packet = this.Unpack(packet);
548
+ var unpacked: _Packet = this.Unpack(packet);
647
549
  // unpacked.chunks = unpacked.chunks.filter(chunk => ((chunk.flags & 2) && (chunk.flags & 1)) ? chunk.seq! > this.ack : true); // filter out already received chunks
648
550
  this.sentChunkQueue.forEach((buff, i) => {
649
551
  let chunkFlags = (buff[0] >> 6) & 3;
@@ -680,23 +582,22 @@ export class Client extends EventEmitter {
680
582
 
681
583
  if (chunk.sys) {
682
584
  // system messages
683
- if (chunk.msgid == NETMSG_Sys.NETMSG_PING) { // ping
684
- let packer = new MsgPacker(NETMSG_Sys.NETMSG_PING_REPLY, true, 0);
585
+ if (chunk.msgid == NETMSG.System.NETMSG_PING) { // ping
586
+ let packer = new MsgPacker(NETMSG.System.NETMSG_PING_REPLY, true, 0);
685
587
 
686
588
  this.SendMsgEx(packer); // send ping reply
687
- } else if (chunk.msgid == NETMSG_Sys.NETMSG_PING_REPLY) { // Ping reply
589
+ } else if (chunk.msgid == NETMSG.System.NETMSG_PING_REPLY) { // Ping reply
688
590
  this.game._ping_resolve(new Date().getTime())
689
- }
690
-
591
+ } else if (this.rcon._checkChunks(chunk)) {}
691
592
  // packets neccessary for connection
692
593
  // https://ddnet.org/docs/libtw2/connection/
693
594
 
694
- if (chunk.msgid == NETMSG_Sys.NETMSG_MAP_CHANGE) {
595
+ if (chunk.msgid == NETMSG.System.NETMSG_MAP_CHANGE) {
695
596
  this.Flush();
696
- var Msg = new MsgPacker(NETMSG_Sys.NETMSG_READY, true, 1); /* ready */
597
+ var Msg = new MsgPacker(NETMSG.System.NETMSG_READY, true, 1); /* ready */
697
598
  this.SendMsgEx(Msg);
698
- } else if (chunk.msgid == NETMSG_Sys.NETMSG_CON_READY) {
699
- var info = new MsgPacker(NETMSG_Game.CL_STARTINFO, false, 1);
599
+ } else if (chunk.msgid == NETMSG.System.NETMSG_CON_READY) {
600
+ var info = new MsgPacker(NETMSG.Game.CL_STARTINFO, false, 1);
700
601
  if (this.options?.identity) {
701
602
  info.AddString(this.options.identity.name);
702
603
  info.AddString(this.options.identity.clan);
@@ -720,7 +621,7 @@ export class Client extends EventEmitter {
720
621
  this.SendMsgEx([info, crashmeplx]);
721
622
  }
722
623
 
723
- if (chunk.msgid >= NETMSG_Sys.NETMSG_SNAP && chunk.msgid <= NETMSG_Sys.NETMSG_SNAPSINGLE) {
624
+ if (chunk.msgid >= NETMSG.System.NETMSG_SNAP && chunk.msgid <= NETMSG.System.NETMSG_SNAPSINGLE) {
724
625
  this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
725
626
  if (this.receivedSnaps == 2) {
726
627
  if (this.State != States.STATE_ONLINE)
@@ -741,12 +642,12 @@ export class Client extends EventEmitter {
741
642
  let Crc = 0;
742
643
  let CompleteSize = 0;
743
644
 
744
- if (chunk.msgid == NETMSG_Sys.NETMSG_SNAP) {
645
+ if (chunk.msgid == NETMSG.System.NETMSG_SNAP) {
745
646
  NumParts = unpacker.unpackInt();
746
647
  Part = unpacker.unpackInt();
747
648
  }
748
649
 
749
- if (chunk.msgid != NETMSG_Sys.NETMSG_SNAPEMPTY) {
650
+ if (chunk.msgid != NETMSG.System.NETMSG_SNAPEMPTY) {
750
651
  Crc = unpacker.unpackInt();
751
652
  PartSize = unpacker.unpackInt();
752
653
  }
@@ -789,28 +690,28 @@ export class Client extends EventEmitter {
789
690
 
790
691
  }
791
692
 
792
- if (chunk.msgid >= NETMSG_Sys.NETMSG_WHATIS && chunk.msgid <= NETMSG_Sys.NETMSG_CHECKSUM_ERROR) {
793
- if (chunk.msgid == NETMSG_Sys.NETMSG_WHATIS) {
693
+ if (chunk.msgid >= NETMSG.System.NETMSG_WHATIS && chunk.msgid <= NETMSG.System.NETMSG_CHECKSUM_ERROR) {
694
+ if (chunk.msgid == NETMSG.System.NETMSG_WHATIS) {
794
695
  let Uuid = chunk.raw.slice(0, 16);
795
696
 
796
697
  let uuid = this.UUIDManager.LookupUUID(Uuid);
797
698
  let packer = new MsgPacker(0, true, 1);
798
699
  if (uuid !== undefined) {
799
700
  // IT_IS msg
800
- packer.AddBuffer(this.UUIDManager.LookupType(NETMSG_Sys.NETMSG_ITIS)!.hash);
701
+ packer.AddBuffer(this.UUIDManager.LookupType(NETMSG.System.NETMSG_ITIS)!.hash);
801
702
 
802
703
  packer.AddBuffer(Uuid);
803
704
  packer.AddString(uuid.name);
804
705
  } else {
805
706
  // dont_know msg
806
- packer.AddBuffer(this.UUIDManager.LookupType(NETMSG_Sys.NETMSG_IDONTKNOW)!.hash);
707
+ packer.AddBuffer(this.UUIDManager.LookupType(NETMSG.System.NETMSG_IDONTKNOW)!.hash);
807
708
 
808
709
  packer.AddBuffer(Uuid);
809
710
  }
810
711
  this.QueueChunkEx(packer)
811
712
  }
812
713
 
813
- if (chunk.msgid == NETMSG_Sys.NETMSG_MAP_DETAILS) { // TODO: option for downloading maps
714
+ if (chunk.msgid == NETMSG.System.NETMSG_MAP_DETAILS) { // TODO: option for downloading maps
814
715
  let unpacker = new MsgUnpacker(chunk.raw);
815
716
 
816
717
  let map_name = unpacker.unpackString();
@@ -827,7 +728,7 @@ export class Client extends EventEmitter {
827
728
  this.emit("map_details", {map_name, map_sha256, map_crc, map_size, map_url})
828
729
  // unpacker.unpack
829
730
 
830
- } else if (chunk.msgid == NETMSG_Sys.NETMSG_CAPABILITIES) {
731
+ } else if (chunk.msgid == NETMSG.System.NETMSG_CAPABILITIES) {
831
732
  let unpacker = new MsgUnpacker(chunk.raw);
832
733
  let Version = unpacker.unpackInt();
833
734
  let Flags = unpacker.unpackInt();
@@ -865,11 +766,22 @@ export class Client extends EventEmitter {
865
766
  }
866
767
  this.emit("capabilities", {ChatTimeoutCode, AnyPlayerFlag, PingEx, AllowDummy, SyncWeaponInput});
867
768
  // https://github.com/ddnet/ddnet/blob/06e3eb564150e9ab81b3a5595c48e9fe5952ed32/src/engine/client/client.cpp#L1565
868
- } else if (chunk.msgid == NETMSG_Sys.NETMSG_PINGEX) {
769
+ } else if (chunk.msgid == NETMSG.System.NETMSG_PINGEX) {
869
770
  let packer = new MsgPacker(0, true, 2);
870
- packer.AddBuffer(this.UUIDManager.LookupType(NETMSG_Sys.NETMSG_PONGEX)!.hash);
771
+ packer.AddBuffer(this.UUIDManager.LookupType(NETMSG.System.NETMSG_PONGEX)!.hash);
871
772
 
872
773
  this.SendMsgEx(packer, 2);
774
+ } else if (chunk.msgid == NETMSG.System.NETMSG_RECONNECT) {
775
+ this.SendControlMsg(4) // sends disconnect packet
776
+ clearInterval(predTimer);
777
+ clearInterval(inputInterval);
778
+ clearInterval(resendTimeout);
779
+ clearInterval(Timeout);
780
+ this.socket?.removeAllListeners("message");
781
+ this.connect();
782
+
783
+
784
+ return;
873
785
  }
874
786
 
875
787
  }
@@ -878,9 +790,9 @@ export class Client extends EventEmitter {
878
790
  // game messages
879
791
 
880
792
  // vote list:
881
- if (chunk.msgid == NETMSG_Game.SV_VOTECLEAROPTIONS) {
793
+ if (chunk.msgid == NETMSG.Game.SV_VOTECLEAROPTIONS) {
882
794
  this.VoteList = [];
883
- } else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONLISTADD) {
795
+ } else if (chunk.msgid == NETMSG.Game.SV_VOTEOPTIONLISTADD) {
884
796
  let unpacker = new MsgUnpacker(chunk.raw)
885
797
  let NumOptions = unpacker.unpackInt()
886
798
  let list: string[] = [];
@@ -890,11 +802,11 @@ export class Client extends EventEmitter {
890
802
  list = list.slice(0, NumOptions);
891
803
 
892
804
  this.VoteList.push(...list);
893
- } else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONADD) {
805
+ } else if (chunk.msgid == NETMSG.Game.SV_VOTEOPTIONADD) {
894
806
  let unpacker = new MsgUnpacker(chunk.raw)
895
807
 
896
808
  this.VoteList.push(unpacker.unpackString());
897
- } else if (chunk.msgid == NETMSG_Game.SV_VOTEOPTIONREMOVE) {
809
+ } else if (chunk.msgid == NETMSG.Game.SV_VOTEOPTIONREMOVE) {
898
810
  let unpacker = new MsgUnpacker(chunk.raw)
899
811
 
900
812
  let index = this.VoteList.indexOf(unpacker.unpackString());
@@ -905,7 +817,7 @@ export class Client extends EventEmitter {
905
817
  }
906
818
 
907
819
  // events
908
- if (chunk.msgid == NETMSG_Game.SV_EMOTICON) {
820
+ if (chunk.msgid == NETMSG.Game.SV_EMOTICON) {
909
821
  let unpacker = new MsgUnpacker(chunk.raw);
910
822
  let unpacked = {
911
823
  client_id: unpacker.unpackInt(),
@@ -922,11 +834,11 @@ export class Client extends EventEmitter {
922
834
 
923
835
 
924
836
 
925
- } else if (chunk.msgid == NETMSG_Game.SV_BROADCAST) {
837
+ } else if (chunk.msgid == NETMSG.Game.SV_BROADCAST) {
926
838
  let unpacker = new MsgUnpacker(chunk.raw);
927
839
 
928
840
  this.emit("broadcast", unpacker.unpackString());
929
- } if (chunk.msgid == NETMSG_Game.SV_CHAT) {
841
+ } if (chunk.msgid == NETMSG.Game.SV_CHAT) {
930
842
  let unpacker = new MsgUnpacker(chunk.raw);
931
843
  let unpacked: iMessage = {
932
844
  team: unpacker.unpackInt(),
@@ -941,7 +853,7 @@ export class Client extends EventEmitter {
941
853
  }
942
854
  }
943
855
  this.emit("message", unpacked)
944
- } else if (chunk.msgid == NETMSG_Game.SV_KILLMSG) {
856
+ } else if (chunk.msgid == NETMSG.Game.SV_KILLMSG) {
945
857
  let unpacked: iKillMsg = {} as iKillMsg;
946
858
  let unpacker = new MsgUnpacker(chunk.raw);
947
859
  unpacked.killer_id = unpacker.unpackInt();
@@ -955,7 +867,7 @@ export class Client extends EventEmitter {
955
867
  if (unpacked.killer_id != -1 && unpacked.killer_id < 64)
956
868
  unpacked.killer = { ClientInfo: this.SnapshotUnpacker.getObjClientInfo(unpacked.killer_id), PlayerInfo: this.SnapshotUnpacker.getObjPlayerInfo(unpacked.killer_id) }
957
869
  this.emit("kill", unpacked)
958
- } else if (chunk.msgid == NETMSG_Game.SV_MOTD) {
870
+ } else if (chunk.msgid == NETMSG.Game.SV_MOTD) {
959
871
  let unpacker = new MsgUnpacker(chunk.raw);
960
872
  let message = unpacker.unpackString();
961
873
  this.emit("motd", message);
@@ -963,8 +875,8 @@ export class Client extends EventEmitter {
963
875
 
964
876
  // packets neccessary for connection
965
877
  // https://ddnet.org/docs/libtw2/connection/
966
- if (chunk.msgid == NETMSG_Game.SV_READYTOENTER) {
967
- var Msg = new MsgPacker(NETMSG_Sys.NETMSG_ENTERGAME, true, 1); /* entergame */
878
+ if (chunk.msgid == NETMSG.Game.SV_READYTOENTER) {
879
+ var Msg = new MsgPacker(NETMSG.System.NETMSG_ENTERGAME, true, 1); /* entergame */
968
880
  this.SendMsgEx(Msg);
969
881
  this.OnEnterGame();
970
882
  }
@@ -983,8 +895,6 @@ export class Client extends EventEmitter {
983
895
  }
984
896
  })
985
897
  }
986
-
987
-
988
898
  /** Sending the input. (automatically done unless options.lightweight is on) */
989
899
  sendInput(input = this.movement.input) {
990
900
  if (this.State != States.STATE_ONLINE)