teeworlds 2.5.3 → 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 +464 -479
- package/lib/client.ts +102 -213
- package/lib/components/game.js +9 -46
- package/lib/components/game.ts +12 -13
- package/lib/components/rcon.js +122 -0
- package/lib/components/rcon.ts +114 -0
- package/lib/components/snapshot.js +24 -48
- package/lib/components/snapshot.ts +68 -100
- package/lib/enums_types/protocol.js +13 -0
- package/lib/enums_types/protocol.ts +137 -0
- package/lib/enums_types/types.d.ts +236 -0
- package/lib/snapshot.ts +36 -38
- package/package.json +1 -1
- package/lib/snapshots.d.ts +0 -233
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 {
|
|
12
|
+
import { _Packet, Chunk, DeltaItem, SnapshotItemTypes } from './enums_types/types';
|
|
13
13
|
|
|
14
14
|
import { MsgPacker } from './MsgPacker';
|
|
15
|
-
import {
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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,22 @@ export class Client extends EventEmitter {
|
|
|
298
176
|
|
|
299
177
|
this.UUIDManager = new UUIDManager();
|
|
300
178
|
|
|
301
|
-
this.UUIDManager.RegisterName("what-is@ddnet.tw",
|
|
302
|
-
this.UUIDManager.RegisterName("it-is@ddnet.tw",
|
|
303
|
-
this.UUIDManager.RegisterName("i-dont-know@ddnet.tw",
|
|
304
|
-
|
|
305
|
-
this.UUIDManager.RegisterName("rcon-type@ddnet.tw",
|
|
306
|
-
this.UUIDManager.RegisterName("map-details@ddnet.tw",
|
|
307
|
-
this.UUIDManager.RegisterName("capabilities@ddnet.tw",
|
|
308
|
-
this.UUIDManager.RegisterName("clientver@ddnet.tw",
|
|
309
|
-
this.UUIDManager.RegisterName("ping@ddnet.tw",
|
|
310
|
-
this.UUIDManager.RegisterName("pong@ddnet.tw",
|
|
311
|
-
this.UUIDManager.RegisterName("checksum-request@ddnet.tw",
|
|
312
|
-
this.UUIDManager.RegisterName("checksum-response@ddnet.tw",
|
|
313
|
-
this.UUIDManager.RegisterName("checksum-error@ddnet.tw",
|
|
314
|
-
this.UUIDManager.RegisterName("redirect@ddnet.org",
|
|
315
|
-
|
|
316
|
-
this.UUIDManager.RegisterName("i-am-npm-package@swarfey.gitlab.io",
|
|
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
|
+
this.UUIDManager.RegisterName("i-am-npm-package@swarfey.gitlab.io", NETMSG.System.NETMSG_I_AM_NPM_PACKAGE);
|
|
317
195
|
|
|
318
196
|
}
|
|
319
197
|
|
|
@@ -340,8 +218,8 @@ export class Client extends EventEmitter {
|
|
|
340
218
|
this.SendMsgEx(toResend);
|
|
341
219
|
}
|
|
342
220
|
|
|
343
|
-
private Unpack(packet: Buffer):
|
|
344
|
-
var unpacked:
|
|
221
|
+
private Unpack(packet: Buffer): _Packet {
|
|
222
|
+
var unpacked: _Packet = { twprotocol: { flags: packet[0] >> 4, ack: ((packet[0]&0xf)<<8) | packet[1], chunkAmount: packet[2], size: packet.byteLength - 3 }, chunks: [] }
|
|
345
223
|
|
|
346
224
|
|
|
347
225
|
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 +237,7 @@ export class Client extends EventEmitter {
|
|
|
359
237
|
|
|
360
238
|
|
|
361
239
|
for (let i = 0; i < unpacked.twprotocol.chunkAmount; i++) {
|
|
362
|
-
var chunk:
|
|
240
|
+
var chunk: Chunk = {} as Chunk;
|
|
363
241
|
chunk.bytes = ((packet[0] & 0x3f) << 4) | (packet[1] & ((1 << 4) - 1));
|
|
364
242
|
chunk.flags = (packet[0] >> 6) & 3;
|
|
365
243
|
|
|
@@ -472,7 +350,12 @@ export class Client extends EventEmitter {
|
|
|
472
350
|
}
|
|
473
351
|
|
|
474
352
|
/** Queue a chunk (instantly sent if flush flag is set - otherwise it will be sent in the next packet). */
|
|
475
|
-
QueueChunkEx(Msg: MsgPacker) {
|
|
353
|
+
QueueChunkEx(Msg: MsgPacker | MsgPacker[]) {
|
|
354
|
+
if (Msg instanceof Array) {
|
|
355
|
+
for (let chunk of Msg)
|
|
356
|
+
this.QueueChunkEx(chunk);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
476
359
|
if (this.queueChunkEx.length > 0) {
|
|
477
360
|
let total_size = 0;
|
|
478
361
|
for (let chunk of this.queueChunkEx)
|
|
@@ -503,7 +386,7 @@ export class Client extends EventEmitter {
|
|
|
503
386
|
}
|
|
504
387
|
|
|
505
388
|
private MsgToChunk(packet: Buffer) {
|
|
506
|
-
var chunk:
|
|
389
|
+
var chunk: Chunk = {} as Chunk;
|
|
507
390
|
chunk.bytes = ((packet[0] & 0x3f) << 4) | (packet[1] & ((1 << 4) - 1));
|
|
508
391
|
chunk.flags = (packet[0] >> 6) & 3;
|
|
509
392
|
|
|
@@ -539,7 +422,17 @@ export class Client extends EventEmitter {
|
|
|
539
422
|
}
|
|
540
423
|
|
|
541
424
|
/** Connect the client to the server. */
|
|
542
|
-
connect() {
|
|
425
|
+
async connect() {
|
|
426
|
+
// test via regex whether or not this.host is a domain or an ip
|
|
427
|
+
// if not, resolve it
|
|
428
|
+
if (!this.host.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) {
|
|
429
|
+
dnsLookup(this.host, 4, (err, address, family) => {
|
|
430
|
+
if (err) throw err;
|
|
431
|
+
this.host = address;
|
|
432
|
+
console.log(err, address, family)
|
|
433
|
+
})
|
|
434
|
+
}
|
|
435
|
+
|
|
543
436
|
this.State = States.STATE_CONNECTING;
|
|
544
437
|
|
|
545
438
|
let predTimer = setInterval(() => {
|
|
@@ -562,7 +455,7 @@ export class Client extends EventEmitter {
|
|
|
562
455
|
let inputInterval = setInterval(() => {
|
|
563
456
|
if (this.State == States.STATE_OFFLINE) {
|
|
564
457
|
clearInterval(inputInterval)
|
|
565
|
-
console.log("???");
|
|
458
|
+
// console.log("???");
|
|
566
459
|
}
|
|
567
460
|
if (this.State != States.STATE_ONLINE)
|
|
568
461
|
return;
|
|
@@ -584,7 +477,6 @@ export class Client extends EventEmitter {
|
|
|
584
477
|
let timeoutTime = this.options?.timeout ? this.options.timeout : 15000;
|
|
585
478
|
if ((new Date().getTime() - this.lastRecvTime) > timeoutTime) {
|
|
586
479
|
this.State = States.STATE_OFFLINE;
|
|
587
|
-
this.emit("timeout");
|
|
588
480
|
this.emit("disconnect", "Timed Out. (no packets received for " + (new Date().getTime() - this.lastRecvTime) + "ms)");
|
|
589
481
|
clearInterval(Timeout);
|
|
590
482
|
}
|
|
@@ -624,7 +516,7 @@ export class Client extends EventEmitter {
|
|
|
624
516
|
}
|
|
625
517
|
|
|
626
518
|
var i_am_npm_package = new MsgPacker(0, true, 1);
|
|
627
|
-
i_am_npm_package.AddBuffer(this.UUIDManager.LookupType(
|
|
519
|
+
i_am_npm_package.AddBuffer(this.UUIDManager.LookupType(NETMSG.System.NETMSG_I_AM_NPM_PACKAGE)!.hash);
|
|
628
520
|
|
|
629
521
|
i_am_npm_package.AddString(`https://www.npmjs.com/package/teeworlds/v/${version}`);
|
|
630
522
|
|
|
@@ -643,7 +535,7 @@ export class Client extends EventEmitter {
|
|
|
643
535
|
this.lastRecvTime = new Date().getTime();
|
|
644
536
|
}
|
|
645
537
|
|
|
646
|
-
var unpacked:
|
|
538
|
+
var unpacked: _Packet = this.Unpack(packet);
|
|
647
539
|
// unpacked.chunks = unpacked.chunks.filter(chunk => ((chunk.flags & 2) && (chunk.flags & 1)) ? chunk.seq! > this.ack : true); // filter out already received chunks
|
|
648
540
|
this.sentChunkQueue.forEach((buff, i) => {
|
|
649
541
|
let chunkFlags = (buff[0] >> 6) & 3;
|
|
@@ -680,23 +572,22 @@ export class Client extends EventEmitter {
|
|
|
680
572
|
|
|
681
573
|
if (chunk.sys) {
|
|
682
574
|
// system messages
|
|
683
|
-
if (chunk.msgid ==
|
|
684
|
-
let packer = new MsgPacker(
|
|
575
|
+
if (chunk.msgid == NETMSG.System.NETMSG_PING) { // ping
|
|
576
|
+
let packer = new MsgPacker(NETMSG.System.NETMSG_PING_REPLY, true, 0);
|
|
685
577
|
|
|
686
578
|
this.SendMsgEx(packer); // send ping reply
|
|
687
|
-
} else if (chunk.msgid ==
|
|
579
|
+
} else if (chunk.msgid == NETMSG.System.NETMSG_PING_REPLY) { // Ping reply
|
|
688
580
|
this.game._ping_resolve(new Date().getTime())
|
|
689
|
-
}
|
|
690
|
-
|
|
581
|
+
} else if (this.rcon._checkChunks(chunk)) {}
|
|
691
582
|
// packets neccessary for connection
|
|
692
583
|
// https://ddnet.org/docs/libtw2/connection/
|
|
693
584
|
|
|
694
|
-
if (chunk.msgid ==
|
|
585
|
+
if (chunk.msgid == NETMSG.System.NETMSG_MAP_CHANGE) {
|
|
695
586
|
this.Flush();
|
|
696
|
-
var Msg = new MsgPacker(
|
|
587
|
+
var Msg = new MsgPacker(NETMSG.System.NETMSG_READY, true, 1); /* ready */
|
|
697
588
|
this.SendMsgEx(Msg);
|
|
698
|
-
} else if (chunk.msgid ==
|
|
699
|
-
var info = new MsgPacker(
|
|
589
|
+
} else if (chunk.msgid == NETMSG.System.NETMSG_CON_READY) {
|
|
590
|
+
var info = new MsgPacker(NETMSG.Game.CL_STARTINFO, false, 1);
|
|
700
591
|
if (this.options?.identity) {
|
|
701
592
|
info.AddString(this.options.identity.name);
|
|
702
593
|
info.AddString(this.options.identity.clan);
|
|
@@ -720,7 +611,7 @@ export class Client extends EventEmitter {
|
|
|
720
611
|
this.SendMsgEx([info, crashmeplx]);
|
|
721
612
|
}
|
|
722
613
|
|
|
723
|
-
if (chunk.msgid >=
|
|
614
|
+
if (chunk.msgid >= NETMSG.System.NETMSG_SNAP && chunk.msgid <= NETMSG.System.NETMSG_SNAPSINGLE) {
|
|
724
615
|
this.receivedSnaps++; /* wait for 2 ss before seeing self as connected */
|
|
725
616
|
if (this.receivedSnaps == 2) {
|
|
726
617
|
if (this.State != States.STATE_ONLINE)
|
|
@@ -741,12 +632,12 @@ export class Client extends EventEmitter {
|
|
|
741
632
|
let Crc = 0;
|
|
742
633
|
let CompleteSize = 0;
|
|
743
634
|
|
|
744
|
-
if (chunk.msgid ==
|
|
635
|
+
if (chunk.msgid == NETMSG.System.NETMSG_SNAP) {
|
|
745
636
|
NumParts = unpacker.unpackInt();
|
|
746
637
|
Part = unpacker.unpackInt();
|
|
747
638
|
}
|
|
748
639
|
|
|
749
|
-
if (chunk.msgid !=
|
|
640
|
+
if (chunk.msgid != NETMSG.System.NETMSG_SNAPEMPTY) {
|
|
750
641
|
Crc = unpacker.unpackInt();
|
|
751
642
|
PartSize = unpacker.unpackInt();
|
|
752
643
|
}
|
|
@@ -789,28 +680,28 @@ export class Client extends EventEmitter {
|
|
|
789
680
|
|
|
790
681
|
}
|
|
791
682
|
|
|
792
|
-
if (chunk.msgid >=
|
|
793
|
-
if (chunk.msgid ==
|
|
683
|
+
if (chunk.msgid >= NETMSG.System.NETMSG_WHATIS && chunk.msgid <= NETMSG.System.NETMSG_CHECKSUM_ERROR) {
|
|
684
|
+
if (chunk.msgid == NETMSG.System.NETMSG_WHATIS) {
|
|
794
685
|
let Uuid = chunk.raw.slice(0, 16);
|
|
795
686
|
|
|
796
687
|
let uuid = this.UUIDManager.LookupUUID(Uuid);
|
|
797
688
|
let packer = new MsgPacker(0, true, 1);
|
|
798
689
|
if (uuid !== undefined) {
|
|
799
690
|
// IT_IS msg
|
|
800
|
-
packer.AddBuffer(this.UUIDManager.LookupType(
|
|
691
|
+
packer.AddBuffer(this.UUIDManager.LookupType(NETMSG.System.NETMSG_ITIS)!.hash);
|
|
801
692
|
|
|
802
693
|
packer.AddBuffer(Uuid);
|
|
803
694
|
packer.AddString(uuid.name);
|
|
804
695
|
} else {
|
|
805
696
|
// dont_know msg
|
|
806
|
-
packer.AddBuffer(this.UUIDManager.LookupType(
|
|
697
|
+
packer.AddBuffer(this.UUIDManager.LookupType(NETMSG.System.NETMSG_IDONTKNOW)!.hash);
|
|
807
698
|
|
|
808
699
|
packer.AddBuffer(Uuid);
|
|
809
700
|
}
|
|
810
701
|
this.QueueChunkEx(packer)
|
|
811
702
|
}
|
|
812
703
|
|
|
813
|
-
if (chunk.msgid ==
|
|
704
|
+
if (chunk.msgid == NETMSG.System.NETMSG_MAP_DETAILS) { // TODO: option for downloading maps
|
|
814
705
|
let unpacker = new MsgUnpacker(chunk.raw);
|
|
815
706
|
|
|
816
707
|
let map_name = unpacker.unpackString();
|
|
@@ -827,7 +718,7 @@ export class Client extends EventEmitter {
|
|
|
827
718
|
this.emit("map_details", {map_name, map_sha256, map_crc, map_size, map_url})
|
|
828
719
|
// unpacker.unpack
|
|
829
720
|
|
|
830
|
-
} else if (chunk.msgid ==
|
|
721
|
+
} else if (chunk.msgid == NETMSG.System.NETMSG_CAPABILITIES) {
|
|
831
722
|
let unpacker = new MsgUnpacker(chunk.raw);
|
|
832
723
|
let Version = unpacker.unpackInt();
|
|
833
724
|
let Flags = unpacker.unpackInt();
|
|
@@ -865,9 +756,9 @@ export class Client extends EventEmitter {
|
|
|
865
756
|
}
|
|
866
757
|
this.emit("capabilities", {ChatTimeoutCode, AnyPlayerFlag, PingEx, AllowDummy, SyncWeaponInput});
|
|
867
758
|
// https://github.com/ddnet/ddnet/blob/06e3eb564150e9ab81b3a5595c48e9fe5952ed32/src/engine/client/client.cpp#L1565
|
|
868
|
-
} else if (chunk.msgid ==
|
|
759
|
+
} else if (chunk.msgid == NETMSG.System.NETMSG_PINGEX) {
|
|
869
760
|
let packer = new MsgPacker(0, true, 2);
|
|
870
|
-
packer.AddBuffer(this.UUIDManager.LookupType(
|
|
761
|
+
packer.AddBuffer(this.UUIDManager.LookupType(NETMSG.System.NETMSG_PONGEX)!.hash);
|
|
871
762
|
|
|
872
763
|
this.SendMsgEx(packer, 2);
|
|
873
764
|
}
|
|
@@ -878,9 +769,9 @@ export class Client extends EventEmitter {
|
|
|
878
769
|
// game messages
|
|
879
770
|
|
|
880
771
|
// vote list:
|
|
881
|
-
if (chunk.msgid ==
|
|
772
|
+
if (chunk.msgid == NETMSG.Game.SV_VOTECLEAROPTIONS) {
|
|
882
773
|
this.VoteList = [];
|
|
883
|
-
} else if (chunk.msgid ==
|
|
774
|
+
} else if (chunk.msgid == NETMSG.Game.SV_VOTEOPTIONLISTADD) {
|
|
884
775
|
let unpacker = new MsgUnpacker(chunk.raw)
|
|
885
776
|
let NumOptions = unpacker.unpackInt()
|
|
886
777
|
let list: string[] = [];
|
|
@@ -890,11 +781,11 @@ export class Client extends EventEmitter {
|
|
|
890
781
|
list = list.slice(0, NumOptions);
|
|
891
782
|
|
|
892
783
|
this.VoteList.push(...list);
|
|
893
|
-
} else if (chunk.msgid ==
|
|
784
|
+
} else if (chunk.msgid == NETMSG.Game.SV_VOTEOPTIONADD) {
|
|
894
785
|
let unpacker = new MsgUnpacker(chunk.raw)
|
|
895
786
|
|
|
896
787
|
this.VoteList.push(unpacker.unpackString());
|
|
897
|
-
} else if (chunk.msgid ==
|
|
788
|
+
} else if (chunk.msgid == NETMSG.Game.SV_VOTEOPTIONREMOVE) {
|
|
898
789
|
let unpacker = new MsgUnpacker(chunk.raw)
|
|
899
790
|
|
|
900
791
|
let index = this.VoteList.indexOf(unpacker.unpackString());
|
|
@@ -905,7 +796,7 @@ export class Client extends EventEmitter {
|
|
|
905
796
|
}
|
|
906
797
|
|
|
907
798
|
// events
|
|
908
|
-
if (chunk.msgid ==
|
|
799
|
+
if (chunk.msgid == NETMSG.Game.SV_EMOTICON) {
|
|
909
800
|
let unpacker = new MsgUnpacker(chunk.raw);
|
|
910
801
|
let unpacked = {
|
|
911
802
|
client_id: unpacker.unpackInt(),
|
|
@@ -922,11 +813,11 @@ export class Client extends EventEmitter {
|
|
|
922
813
|
|
|
923
814
|
|
|
924
815
|
|
|
925
|
-
} else if (chunk.msgid ==
|
|
816
|
+
} else if (chunk.msgid == NETMSG.Game.SV_BROADCAST) {
|
|
926
817
|
let unpacker = new MsgUnpacker(chunk.raw);
|
|
927
818
|
|
|
928
819
|
this.emit("broadcast", unpacker.unpackString());
|
|
929
|
-
} if (chunk.msgid ==
|
|
820
|
+
} if (chunk.msgid == NETMSG.Game.SV_CHAT) {
|
|
930
821
|
let unpacker = new MsgUnpacker(chunk.raw);
|
|
931
822
|
let unpacked: iMessage = {
|
|
932
823
|
team: unpacker.unpackInt(),
|
|
@@ -941,7 +832,7 @@ export class Client extends EventEmitter {
|
|
|
941
832
|
}
|
|
942
833
|
}
|
|
943
834
|
this.emit("message", unpacked)
|
|
944
|
-
} else if (chunk.msgid ==
|
|
835
|
+
} else if (chunk.msgid == NETMSG.Game.SV_KILLMSG) {
|
|
945
836
|
let unpacked: iKillMsg = {} as iKillMsg;
|
|
946
837
|
let unpacker = new MsgUnpacker(chunk.raw);
|
|
947
838
|
unpacked.killer_id = unpacker.unpackInt();
|
|
@@ -955,7 +846,7 @@ export class Client extends EventEmitter {
|
|
|
955
846
|
if (unpacked.killer_id != -1 && unpacked.killer_id < 64)
|
|
956
847
|
unpacked.killer = { ClientInfo: this.SnapshotUnpacker.getObjClientInfo(unpacked.killer_id), PlayerInfo: this.SnapshotUnpacker.getObjPlayerInfo(unpacked.killer_id) }
|
|
957
848
|
this.emit("kill", unpacked)
|
|
958
|
-
} else if (chunk.msgid ==
|
|
849
|
+
} else if (chunk.msgid == NETMSG.Game.SV_MOTD) {
|
|
959
850
|
let unpacker = new MsgUnpacker(chunk.raw);
|
|
960
851
|
let message = unpacker.unpackString();
|
|
961
852
|
this.emit("motd", message);
|
|
@@ -963,8 +854,8 @@ export class Client extends EventEmitter {
|
|
|
963
854
|
|
|
964
855
|
// packets neccessary for connection
|
|
965
856
|
// https://ddnet.org/docs/libtw2/connection/
|
|
966
|
-
if (chunk.msgid ==
|
|
967
|
-
var Msg = new MsgPacker(
|
|
857
|
+
if (chunk.msgid == NETMSG.Game.SV_READYTOENTER) {
|
|
858
|
+
var Msg = new MsgPacker(NETMSG.System.NETMSG_ENTERGAME, true, 1); /* entergame */
|
|
968
859
|
this.SendMsgEx(Msg);
|
|
969
860
|
this.OnEnterGame();
|
|
970
861
|
}
|
|
@@ -983,8 +874,6 @@ export class Client extends EventEmitter {
|
|
|
983
874
|
}
|
|
984
875
|
})
|
|
985
876
|
}
|
|
986
|
-
|
|
987
|
-
|
|
988
877
|
/** Sending the input. (automatically done unless options.lightweight is on) */
|
|
989
878
|
sendInput(input = this.movement.input) {
|
|
990
879
|
if (this.State != States.STATE_ONLINE)
|