teeworlds 2.1.5 → 2.1.9
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/index.js +16 -9
- package/index.ts +5 -9
- package/lib/MsgPacker.js +54 -0
- package/lib/MsgPacker.ts +2 -6
- package/lib/MsgUnpacker.js +53 -0
- package/lib/MsgUnpacker.ts +1 -6
- package/lib/client.js +588 -0
- package/lib/client.ts +114 -171
- package/lib/huffman.js +190 -0
- package/lib/movement.js +54 -0
- package/lib/snapshot.js +341 -0
- package/lib/snapshot.ts +9 -15
- package/package.json +1 -1
package/lib/client.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { randomBytes } from "crypto";
|
|
2
2
|
|
|
3
3
|
import net from 'dgram';
|
|
4
|
-
import fs, { stat } from 'fs';
|
|
5
4
|
import { EventEmitter } from 'stream';
|
|
6
|
-
import { spawn } from 'child_process';
|
|
7
5
|
|
|
8
|
-
import {
|
|
6
|
+
import { unpackString, MsgUnpacker } from "./MsgUnpacker";
|
|
9
7
|
|
|
10
8
|
import Movement from './movement';
|
|
11
9
|
|
|
12
|
-
import MsgPacker from './MsgPacker';
|
|
10
|
+
import { MsgPacker } from './MsgPacker';
|
|
13
11
|
import { Snapshot } from './snapshot';
|
|
14
12
|
import Huffman from "./huffman";
|
|
15
13
|
|
|
@@ -174,7 +172,13 @@ declare interface iKillMsg {
|
|
|
174
172
|
special_mode: number
|
|
175
173
|
}
|
|
176
174
|
|
|
177
|
-
declare interface
|
|
175
|
+
declare interface iOptions {
|
|
176
|
+
identity?: ClientInfo,
|
|
177
|
+
password?: string,
|
|
178
|
+
ddnet_version?: {version: number, release_version: string},
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export declare interface Client {
|
|
178
182
|
host: string;
|
|
179
183
|
port: number;
|
|
180
184
|
name: string;
|
|
@@ -201,6 +205,7 @@ declare interface Client {
|
|
|
201
205
|
|
|
202
206
|
lastSendTime: number;
|
|
203
207
|
|
|
208
|
+
options?: iOptions;
|
|
204
209
|
|
|
205
210
|
on(event: 'connected', listener: () => void): this;
|
|
206
211
|
on(event: 'disconnect', listener: (reason: string) => void): this;
|
|
@@ -209,17 +214,23 @@ declare interface Client {
|
|
|
209
214
|
on(event: 'kill', listener: (kill: iKillMsg) => void): this;
|
|
210
215
|
|
|
211
216
|
}
|
|
212
|
-
class Client extends EventEmitter {
|
|
213
217
|
|
|
214
218
|
|
|
215
219
|
|
|
216
|
-
|
|
220
|
+
export class Client extends EventEmitter {
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
constructor(ip: string, port: number, nickname: string, options?: iOptions) {
|
|
217
225
|
super();
|
|
218
226
|
this.host = ip;
|
|
219
227
|
this.port = port;
|
|
220
228
|
this.name = nickname;
|
|
221
229
|
this.AckGameTick = 0;
|
|
222
230
|
this.PredGameTick = 0;
|
|
231
|
+
|
|
232
|
+
if (options)
|
|
233
|
+
this.options = options;
|
|
223
234
|
|
|
224
235
|
this.timer = 0;
|
|
225
236
|
|
|
@@ -257,10 +268,10 @@ class Client extends EventEmitter {
|
|
|
257
268
|
if (packet.length == 1 && packet[0] == -1)
|
|
258
269
|
return unpacked
|
|
259
270
|
}
|
|
260
|
-
|
|
271
|
+
|
|
261
272
|
for (let i = 0; i < unpacked.twprotocol.chunkAmount; i++) {
|
|
262
273
|
var chunk: chunk = {} as chunk;
|
|
263
|
-
chunk.bytes = ((packet[0] & 0x3f) << 4) | (packet[1] & ((1 << 4) - 1));
|
|
274
|
+
chunk.bytes = ((packet[0] & 0x3f) << 4) | (packet[1] & ((1 << 4) - 1));
|
|
264
275
|
chunk.flags = (packet[0] >> 6) & 3;
|
|
265
276
|
chunk.sequence = -1;
|
|
266
277
|
|
|
@@ -276,12 +287,11 @@ class Client extends EventEmitter {
|
|
|
276
287
|
Object.values(messageUUIDs).forEach((a, i) => {
|
|
277
288
|
if (a.compare(packet.slice(0, 16)) == 0) {
|
|
278
289
|
chunk.extended_msgid = a;
|
|
279
|
-
// chunk.type = 'sys';
|
|
280
290
|
chunk.msg = Object.keys(messageUUIDs)[i];
|
|
281
291
|
}
|
|
282
292
|
})
|
|
283
293
|
|
|
284
|
-
packet = packet.slice(chunk.bytes)
|
|
294
|
+
packet = packet.slice(chunk.bytes)
|
|
285
295
|
unpacked.chunks.push(chunk)
|
|
286
296
|
}
|
|
287
297
|
return unpacked
|
|
@@ -304,39 +314,20 @@ class Client extends EventEmitter {
|
|
|
304
314
|
*/
|
|
305
315
|
})
|
|
306
316
|
}
|
|
307
|
-
SendMsgEx(Msg: MsgPacker, Flags: number) {
|
|
308
|
-
if (this.State == States.STATE_OFFLINE)
|
|
309
|
-
throw new Error("Client is not connected");
|
|
310
|
-
if (!this.socket)
|
|
311
|
-
return;
|
|
312
|
-
this.lastSendTime = new Date().getTime();
|
|
313
|
-
var header = []
|
|
314
|
-
header[0] = ((Flags & 3) << 6) | ((Msg.size >> 4) & 0x3f);
|
|
315
|
-
header[1] = (Msg.size & 0xf);
|
|
316
|
-
if (Flags & 1) {
|
|
317
|
-
this.clientAck = (this.clientAck + 1) % (1 << 10);
|
|
318
|
-
header[1] |= (this.clientAck >> 2) & 0xf0;
|
|
319
|
-
header[2] = this.clientAck & 0xff;
|
|
320
|
-
|
|
321
|
-
this.sentChunkQueue.push(Buffer.concat([Buffer.from(header), Msg.buffer]));
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
let latestBuf = Buffer.from([0x0 + (((16 << 4) & 0xf0) | ((this.ack >> 8) & 0xf)), this.ack & 0xff, 0x1, header[0], header[1]]);
|
|
325
|
-
if (Flags & 1)
|
|
326
|
-
latestBuf = Buffer.concat([latestBuf, Buffer.from([this.clientAck])]);
|
|
327
|
-
latestBuf = Buffer.concat([latestBuf, Msg.buffer, this.TKEN]);
|
|
328
|
-
this.socket.send(latestBuf, 0, latestBuf.length, this.port, this.host);
|
|
329
317
|
|
|
330
|
-
|
|
331
|
-
SendMsgExWithChunks(Msgs: MsgPacker[], Flags: number) {
|
|
318
|
+
SendMsgEx(Msgs: MsgPacker[] | MsgPacker, Flags: number) {
|
|
332
319
|
if (this.State == States.STATE_OFFLINE)
|
|
333
|
-
|
|
320
|
+
return;
|
|
334
321
|
if (!this.socket)
|
|
335
322
|
return;
|
|
323
|
+
let _Msgs: MsgPacker[];
|
|
324
|
+
if (Msgs instanceof Array)
|
|
325
|
+
_Msgs = Msgs;
|
|
326
|
+
else
|
|
327
|
+
_Msgs = [Msgs];
|
|
336
328
|
this.lastSendTime = new Date().getTime();
|
|
337
329
|
var header: Buffer[] = [];
|
|
338
|
-
|
|
339
|
-
Msgs.forEach((Msg: MsgPacker, index) => {
|
|
330
|
+
_Msgs.forEach((Msg: MsgPacker, index) => {
|
|
340
331
|
header[index] = Buffer.alloc((Flags & 1 ? 3 : 2));
|
|
341
332
|
header[index][0] = ((Flags & 3) << 6) | ((Msg.size >> 4) & 0x3f);
|
|
342
333
|
header[index][1] = (Msg.size & 0xf);
|
|
@@ -344,19 +335,15 @@ class Client extends EventEmitter {
|
|
|
344
335
|
this.clientAck = (this.clientAck + 1) % (1 << 10);
|
|
345
336
|
header[index][1] |= (this.clientAck >> 2) & 0xf0;
|
|
346
337
|
header[index][2] = this.clientAck & 0xff;
|
|
347
|
-
|
|
348
338
|
header[index][0] = (((Flags | 2)&3)<<6)|((Msg.size>>4)&0x3f); // 2 is resend flag (ugly hack for queue)
|
|
349
339
|
|
|
350
340
|
this.sentChunkQueue.push(Buffer.concat([header[index], Msg.buffer]));
|
|
351
|
-
|
|
352
341
|
header[index][0] = (((Flags)&3)<<6)|((Msg.size>>4)&0x3f);
|
|
353
|
-
|
|
354
|
-
|
|
355
342
|
}
|
|
356
343
|
})
|
|
357
|
-
var packetHeader = Buffer.from([0x0 + (((16 << 4) & 0xf0) | ((this.ack >> 8) & 0xf)), this.ack & 0xff,
|
|
344
|
+
var packetHeader = Buffer.from([0x0 + (((16 << 4) & 0xf0) | ((this.ack >> 8) & 0xf)), this.ack & 0xff, _Msgs.length]);
|
|
358
345
|
var chunks = Buffer.from([]);
|
|
359
|
-
|
|
346
|
+
_Msgs.forEach((Msg: MsgPacker, index) => {
|
|
360
347
|
chunks = Buffer.concat([chunks, Buffer.from(header[index]), Msg.buffer]);
|
|
361
348
|
})
|
|
362
349
|
var packet = Buffer.concat([(packetHeader), chunks, this.TKEN]);
|
|
@@ -365,7 +352,7 @@ class Client extends EventEmitter {
|
|
|
365
352
|
}
|
|
366
353
|
SendMsgRaw(chunks: Buffer[]) {
|
|
367
354
|
if (this.State == States.STATE_OFFLINE)
|
|
368
|
-
|
|
355
|
+
return;
|
|
369
356
|
if (!this.socket)
|
|
370
357
|
return;
|
|
371
358
|
|
|
@@ -380,7 +367,6 @@ class Client extends EventEmitter {
|
|
|
380
367
|
|
|
381
368
|
MsgToChunk(packet: Buffer) {
|
|
382
369
|
var chunk: chunk = {} as chunk;
|
|
383
|
-
// let packet = Msg.buffer;
|
|
384
370
|
chunk.bytes = ((packet[0] & 0x3f) << 4) | (packet[1] & ((1 << 4) - 1));
|
|
385
371
|
chunk.flags = (packet[0] >> 6) & 3;
|
|
386
372
|
chunk.sequence = -1;
|
|
@@ -393,13 +379,10 @@ class Client extends EventEmitter {
|
|
|
393
379
|
chunk.type = packet[0] & 1 ? "sys" : "game"; // & 1 = binary, ****_***1. e.g 0001_0111 sys, 0001_0110 game
|
|
394
380
|
chunk.msgid = (packet[0]-(packet[0]&1))/2;
|
|
395
381
|
chunk.msg = messageTypes[packet[0]&1][chunk.msgid];
|
|
396
|
-
// if (chunk.msg == undefined)
|
|
397
|
-
// console.log(packet)
|
|
398
382
|
chunk.raw = packet.slice(1, chunk.bytes)
|
|
399
383
|
Object.values(messageUUIDs).forEach((a, i) => {
|
|
400
384
|
if (a.compare(packet.slice(0, 16)) === 0) {
|
|
401
385
|
chunk.extended_msgid = a;
|
|
402
|
-
// chunk.type = 'sys';
|
|
403
386
|
chunk.msg = Object.keys(messageUUIDs)[i];
|
|
404
387
|
}
|
|
405
388
|
})
|
|
@@ -411,10 +394,12 @@ class Client extends EventEmitter {
|
|
|
411
394
|
this.State = States.STATE_CONNECTING;
|
|
412
395
|
|
|
413
396
|
let predTimer = setInterval(() => {
|
|
414
|
-
if (this.State == States.STATE_ONLINE
|
|
415
|
-
this.
|
|
416
|
-
|
|
417
|
-
}
|
|
397
|
+
if (this.State == States.STATE_ONLINE) {
|
|
398
|
+
if (this.AckGameTick > 0)
|
|
399
|
+
this.PredGameTick++;
|
|
400
|
+
} else if (this.State == States.STATE_OFFLINE)
|
|
401
|
+
clearInterval(predTimer);
|
|
402
|
+
|
|
418
403
|
}, 20);
|
|
419
404
|
|
|
420
405
|
this.SendControlMsg(1, "TKEN")
|
|
@@ -425,35 +410,31 @@ class Client extends EventEmitter {
|
|
|
425
410
|
clearInterval(connectInterval)
|
|
426
411
|
}, 500);
|
|
427
412
|
|
|
428
|
-
setInterval(() => {
|
|
429
|
-
|
|
413
|
+
let inputInterval = setInterval(() => {
|
|
414
|
+
if (this.State == States.STATE_OFFLINE)
|
|
415
|
+
clearInterval(inputInterval)
|
|
430
416
|
if (this.State != States.STATE_ONLINE)
|
|
431
417
|
return;
|
|
432
418
|
this.time = new Date().getTime();
|
|
433
|
-
// this.SendControlMsg(0);
|
|
434
|
-
// console.log("sending with " + this.AckGameTick)
|
|
435
419
|
this.sendInput();
|
|
436
|
-
// }
|
|
437
420
|
}, 500)
|
|
438
421
|
|
|
439
422
|
let resendTimeout = setInterval(() => {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
// return;
|
|
443
|
-
if (this.State != 0) {
|
|
444
|
-
if (((new Date().getTime()) - this.lastSendTime) > 900) {
|
|
423
|
+
if (this.State != States.STATE_OFFLINE) {
|
|
424
|
+
if (((new Date().getTime()) - this.lastSendTime) > 900 && this.sentChunkQueue.length > 0) {
|
|
445
425
|
this.SendMsgRaw([this.sentChunkQueue[0]]);
|
|
446
|
-
console.log(this.sentChunkQueue);
|
|
447
426
|
}
|
|
448
|
-
}
|
|
449
|
-
|
|
427
|
+
} else
|
|
428
|
+
clearInterval(resendTimeout)
|
|
450
429
|
}, 1000)
|
|
451
430
|
|
|
452
431
|
|
|
453
432
|
this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
|
|
454
433
|
|
|
455
434
|
if (this.socket)
|
|
456
|
-
this.socket.on("message", (a) => {
|
|
435
|
+
this.socket.on("message", (a, rinfo) => {
|
|
436
|
+
if (this.State == 0 || rinfo.address != this.host || rinfo.port != this.port)
|
|
437
|
+
return;
|
|
457
438
|
clearInterval(connectInterval)
|
|
458
439
|
if (a.toJSON().data[0] == 0x10) {
|
|
459
440
|
if (a.toString().includes("TKEN") || a.toJSON().data[3] == 0x2) {
|
|
@@ -461,9 +442,11 @@ class Client extends EventEmitter {
|
|
|
461
442
|
this.TKEN = Buffer.from(a.toJSON().data.slice(a.toJSON().data.length - 4, a.toJSON().data.length))
|
|
462
443
|
this.SendControlMsg(3);
|
|
463
444
|
this.State = States.STATE_LOADING; // loading state
|
|
445
|
+
this.receivedSnaps = 0;
|
|
446
|
+
|
|
464
447
|
var info = new MsgPacker(1, true);
|
|
465
448
|
info.AddString("0.6 626fce9a778df4d4");
|
|
466
|
-
info.AddString(""); // password
|
|
449
|
+
info.AddString(this.options?.password === undefined ? "" : this.options?.password); // password
|
|
467
450
|
|
|
468
451
|
var client_version = new MsgPacker(0, true);
|
|
469
452
|
client_version.AddBuffer(Buffer.from("8c00130484613e478787f672b3835bd4", 'hex'));
|
|
@@ -472,15 +455,19 @@ class Client extends EventEmitter {
|
|
|
472
455
|
randomBytes(16).copy(randomUuid);
|
|
473
456
|
|
|
474
457
|
client_version.AddBuffer(randomUuid);
|
|
475
|
-
|
|
476
|
-
|
|
458
|
+
if (this.options?.ddnet_version !== undefined) {
|
|
459
|
+
client_version.AddInt(this.options?.ddnet_version.version);
|
|
460
|
+
client_version.AddString("DDNet " + this.options?.ddnet_version.release_version);
|
|
461
|
+
} else {
|
|
462
|
+
client_version.AddInt(16003);
|
|
463
|
+
client_version.AddString("DDNet 16.0.3");
|
|
464
|
+
}
|
|
477
465
|
|
|
478
|
-
this.
|
|
466
|
+
this.SendMsgEx([client_version, info], 1)
|
|
479
467
|
} else if (a.toJSON().data[3] == 0x4) {
|
|
480
468
|
// disconnected
|
|
481
469
|
this.State = States.STATE_OFFLINE;
|
|
482
470
|
let reason: string = (unpackString(a.toJSON().data.slice(4)).result);
|
|
483
|
-
// this.State = -1;
|
|
484
471
|
this.emit("disconnect", reason);
|
|
485
472
|
}
|
|
486
473
|
|
|
@@ -491,8 +478,6 @@ class Client extends EventEmitter {
|
|
|
491
478
|
if (a.flags & 1) { // vital
|
|
492
479
|
if (a.seq != undefined && a.seq != -1)
|
|
493
480
|
this.ack = a.seq
|
|
494
|
-
else
|
|
495
|
-
console.log("no seq", a)
|
|
496
481
|
}
|
|
497
482
|
})
|
|
498
483
|
this.sentChunkQueue.forEach((buff, i) => {
|
|
@@ -500,63 +485,60 @@ class Client extends EventEmitter {
|
|
|
500
485
|
if (chunk.flags & 1) {
|
|
501
486
|
if (chunk.seq && chunk.seq < this.ack) {
|
|
502
487
|
this.sentChunkQueue.splice(i, 1);
|
|
503
|
-
// this.ack = (this.ack + 1) % (1 << 10);
|
|
504
488
|
}
|
|
505
489
|
}
|
|
506
490
|
})
|
|
507
491
|
var snapChunks = unpacked.chunks.filter(a => a.msg === "SNAP" || a.msg === "SNAP_SINGLE" || a.msg === "SNAP_EMPTY");
|
|
508
|
-
// console.log(unpacked.chunks.length, unpacked)
|
|
509
492
|
if (snapChunks.length > 0) {
|
|
510
493
|
let part = 0;
|
|
511
494
|
let num_parts = 1;
|
|
512
495
|
snapChunks.forEach(chunk => {
|
|
513
|
-
let
|
|
514
|
-
|
|
515
|
-
|
|
496
|
+
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
|
|
497
|
+
|
|
498
|
+
let AckGameTick = unpacker.unpackInt();
|
|
516
499
|
if (AckGameTick > this.AckGameTick) {
|
|
517
500
|
this.AckGameTick = AckGameTick;
|
|
518
501
|
if (Math.abs(this.PredGameTick - this.AckGameTick) > 10)
|
|
519
502
|
this.PredGameTick = AckGameTick + 1;
|
|
520
|
-
// console.log(this.AckGameTick)
|
|
521
503
|
}
|
|
522
|
-
// })
|
|
523
504
|
|
|
524
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining);
|
|
525
|
-
let DeltaTick = unpackInt(
|
|
505
|
+
// chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining);
|
|
506
|
+
let DeltaTick = AckGameTick - unpacker.unpackInt();
|
|
507
|
+
let num_parts = 1;
|
|
508
|
+
let part = 0;
|
|
509
|
+
|
|
526
510
|
if (chunk.msg === "SNAP") {
|
|
527
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // delta tick
|
|
528
|
-
num_parts =
|
|
529
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // num parts
|
|
530
|
-
part =
|
|
511
|
+
// chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // delta tick
|
|
512
|
+
num_parts = unpacker.unpackInt();
|
|
513
|
+
// chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // num parts
|
|
514
|
+
part = unpacker.unpackInt();
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
let crc = 0;
|
|
518
|
+
let part_size = 0;
|
|
519
|
+
if (chunk.msg != "SNAP_EMPTY") {
|
|
520
|
+
crc = unpacker.unpackInt(); // crc
|
|
521
|
+
part_size = unpacker.unpackInt();
|
|
531
522
|
}
|
|
532
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // part
|
|
533
|
-
if (chunk.msg != "SNAP_EMPTY")
|
|
534
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // crc
|
|
535
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // crc
|
|
536
523
|
if (part === 0 || this.snaps.length > 30) {
|
|
537
524
|
this.snaps = [];
|
|
538
525
|
}
|
|
539
|
-
chunk.raw = Buffer.from(
|
|
526
|
+
chunk.raw = Buffer.from(unpacker.remaining);
|
|
540
527
|
this.snaps.push(chunk.raw)
|
|
541
|
-
// console.log(this.PredGameTick - this.AckGameTick, this.PredGameTick, this.AckGameTick)
|
|
542
528
|
|
|
543
529
|
if ((num_parts - 1) === part && this.snaps.length === num_parts) {
|
|
544
530
|
let mergedSnaps = Buffer.concat(this.snaps);
|
|
531
|
+
// mergedSnaps = Buffer.from(unpackInt(mergedSnaps.toJSON().data).remaining);
|
|
545
532
|
let snapUnpacked = SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, 1)
|
|
546
|
-
// console.log(snapUnpacked)
|
|
547
|
-
|
|
533
|
+
// console.log(snapUnpacked.items, toHexStream(mergedSnaps));
|
|
548
534
|
snapUnpacked.items.forEach((a, i) => {
|
|
549
535
|
if (a.type_id === items.OBJ_CLIENT_INFO) {
|
|
550
|
-
// console.log(a.parsed, i)
|
|
551
536
|
this.client_infos[a.id] = a.parsed as ClientInfo;
|
|
552
|
-
if (
|
|
553
|
-
console.log(
|
|
554
|
-
}
|
|
555
|
-
console.log(this.client_infos[a.id]
|
|
537
|
+
// if (this.client_infos[a.id].name.includes("�") || this.client_infos[a.id].clan.includes("�")) {
|
|
538
|
+
// console.log("bad name", this.client_infos[a.id], toHexStream(mergedSnaps), chunk, AckGameTick, DeltaTick, crc, part_size);
|
|
539
|
+
// }
|
|
540
|
+
// console.log(this.client_infos[a.id])
|
|
556
541
|
}
|
|
557
|
-
// else if (a.type_id === items.OBJ_PLAYER_INFO) {
|
|
558
|
-
// this.player_infos[a.id] = a.parsed as PlayerInfo;
|
|
559
|
-
// }
|
|
560
542
|
})
|
|
561
543
|
}
|
|
562
544
|
|
|
@@ -568,15 +550,18 @@ class Client extends EventEmitter {
|
|
|
568
550
|
var chat = unpacked.chunks.filter(a => a.msg == "SV_CHAT");
|
|
569
551
|
chat.forEach(a => {
|
|
570
552
|
if (a.msg == "SV_CHAT") {
|
|
571
|
-
|
|
572
|
-
unpacked
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
553
|
+
let unpacker = new MsgUnpacker(a.raw.toJSON().data);
|
|
554
|
+
var unpacked: iMessage = {
|
|
555
|
+
team: unpacker.unpackInt(),
|
|
556
|
+
client_id: unpacker.unpackInt(),
|
|
557
|
+
message: unpacker.unpackString()
|
|
558
|
+
} as iMessage;
|
|
559
|
+
|
|
577
560
|
if (unpacked.client_id != -1)
|
|
578
|
-
unpacked.author = {
|
|
579
|
-
|
|
561
|
+
unpacked.author = {
|
|
562
|
+
ClientInfo: this.client_infos[unpacked.client_id],
|
|
563
|
+
PlayerInfo: this.player_infos[unpacked.client_id]
|
|
564
|
+
}
|
|
580
565
|
this.emit("message", unpacked)
|
|
581
566
|
}
|
|
582
567
|
})
|
|
@@ -595,7 +580,6 @@ class Client extends EventEmitter {
|
|
|
595
580
|
unpacked.victim = { ClientInfo: this.client_infos[unpacked.victim_id], PlayerInfo: this.player_infos[unpacked.victim_id] }
|
|
596
581
|
if (unpacked.killer_id != -1)
|
|
597
582
|
unpacked.killer = { ClientInfo: this.client_infos[unpacked.killer_id], PlayerInfo: this.player_infos[unpacked.killer_id] }
|
|
598
|
-
// console.log(unpacked)
|
|
599
583
|
this.emit("kill", unpacked)
|
|
600
584
|
}
|
|
601
585
|
})
|
|
@@ -610,13 +594,24 @@ class Client extends EventEmitter {
|
|
|
610
594
|
this.SendMsgEx(Msg, 1);
|
|
611
595
|
} else if ((unpacked.chunks[0] && chunkMessages.includes("CON_READY") || unpacked.chunks[0] && chunkMessages.includes("SV_MOTD"))) {
|
|
612
596
|
var info = new MsgPacker(20, false);
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
597
|
+
if (this.options?.identity) {
|
|
598
|
+
info.AddString(this.options.identity.name);
|
|
599
|
+
info.AddString(this.options.identity.clan);
|
|
600
|
+
info.AddInt(this.options.identity.country);
|
|
601
|
+
info.AddString(this.options.identity.skin);
|
|
602
|
+
info.AddInt(this.options.identity.use_custom_color);
|
|
603
|
+
info.AddInt(this.options.identity.color_body);
|
|
604
|
+
info.AddInt(this.options.identity.color_feet);
|
|
605
|
+
} else {
|
|
606
|
+
info.AddString(this.name); /* name */
|
|
607
|
+
info.AddString(""); /* clan */
|
|
608
|
+
info.AddInt(-1); /* country */
|
|
609
|
+
info.AddString("greyfox"); /* skin */
|
|
610
|
+
info.AddInt(1); /* use custom color */
|
|
611
|
+
info.AddInt(10346103); /* color body */
|
|
612
|
+
info.AddInt(65535); /* color feet */
|
|
613
|
+
|
|
614
|
+
}
|
|
620
615
|
this.SendMsgEx(info, 1);
|
|
621
616
|
|
|
622
617
|
|
|
@@ -632,52 +627,6 @@ class Client extends EventEmitter {
|
|
|
632
627
|
this.State = States.STATE_ONLINE;
|
|
633
628
|
}
|
|
634
629
|
|
|
635
|
-
var chunks = unpacked.chunks.filter(a => a.msg == "SNAP" || a.msg == "SNAP_SINGLE" || a.msg == "SNAP_EMPTY");
|
|
636
|
-
if (chunks.length > 0) {
|
|
637
|
-
let part = 0;
|
|
638
|
-
let num_parts = 1;
|
|
639
|
-
chunks.forEach(chunk => {
|
|
640
|
-
let AckGameTick = (unpackInt(chunk.raw.toJSON().data).result);
|
|
641
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining);
|
|
642
|
-
let DeltaTick = unpackInt(chunk?.raw?.toJSON().data).result
|
|
643
|
-
if (chunk.msg == "SNAP") {
|
|
644
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // delta tick
|
|
645
|
-
num_parts = (unpackInt(chunk?.raw?.toJSON().data).result)
|
|
646
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // num parts
|
|
647
|
-
part = (unpackInt(chunk?.raw?.toJSON().data).result)
|
|
648
|
-
}
|
|
649
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // part
|
|
650
|
-
if (chunk.msg != "SNAP_EMPTY")
|
|
651
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // crc
|
|
652
|
-
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // crc
|
|
653
|
-
if (part == 0 || this.snaps.length > 30) {
|
|
654
|
-
this.snaps = [];
|
|
655
|
-
}
|
|
656
|
-
this.snaps.push(chunk.raw)
|
|
657
|
-
|
|
658
|
-
if ((num_parts - 1) == part && this.snaps.length == num_parts) {
|
|
659
|
-
let mergedSnaps = Buffer.concat(this.snaps);
|
|
660
|
-
let snapUnpacked = SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, 1)
|
|
661
|
-
|
|
662
|
-
snapUnpacked.items.forEach((a, i) => {
|
|
663
|
-
if (a.type_id == items.OBJ_CLIENT_INFO) {
|
|
664
|
-
this.client_infos[a.id] = a.parsed as ClientInfo;
|
|
665
|
-
// console.log(a.parsed, i)
|
|
666
|
-
// console.log(this.client_infos[a.id])
|
|
667
|
-
} else if (a.type_id == items.OBJ_PLAYER_INFO) {
|
|
668
|
-
this.player_infos[i] = a.parsed as PlayerInfo;
|
|
669
|
-
} else if (a.type_id == items.OBJ_EX || a.type_id > 0x4000) {
|
|
670
|
-
if (a.data.length == 5 && ((a.parsed as DdnetCharacter).freeze_end > 0 || (a.parsed as DdnetCharacter).freeze_end == -1)) {
|
|
671
|
-
// var packer = new MsgPacker(22, false)
|
|
672
|
-
// this.SendMsgEx(packer, 1)
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
})
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
})
|
|
679
|
-
}
|
|
680
|
-
|
|
681
630
|
}
|
|
682
631
|
if (new Date().getTime() - this.time >= 1000 && this.State == States.STATE_ONLINE) {
|
|
683
632
|
this.time = new Date().getTime();
|
|
@@ -694,9 +643,6 @@ class Client extends EventEmitter {
|
|
|
694
643
|
inputMsg.AddInt(this.AckGameTick);
|
|
695
644
|
inputMsg.AddInt(this.PredGameTick);
|
|
696
645
|
inputMsg.AddInt(40);
|
|
697
|
-
// let playerflags = 2;
|
|
698
|
-
// playerflags |= 8; // scoreboard
|
|
699
|
-
// playerflags |= 16; // aimline
|
|
700
646
|
|
|
701
647
|
let input_data = [
|
|
702
648
|
|
|
@@ -711,7 +657,6 @@ class Client extends EventEmitter {
|
|
|
711
657
|
input.m_NextWeapon,
|
|
712
658
|
input.m_PrevWeapon
|
|
713
659
|
]
|
|
714
|
-
// console.log(this.player_infos, this.client_infos)
|
|
715
660
|
input_data.forEach(a => {
|
|
716
661
|
inputMsg.AddInt(a);
|
|
717
662
|
});
|
|
@@ -772,5 +717,3 @@ class Client extends EventEmitter {
|
|
|
772
717
|
|
|
773
718
|
|
|
774
719
|
}
|
|
775
|
-
export = Client;
|
|
776
|
-
// module.exports = Client;
|