teeworlds 2.0.8 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/MsgUnpacker.js +32 -13
- package/lib/MsgUnpacker.ts +32 -16
- package/lib/client.js +22 -24
- package/lib/client.ts +25 -24
- package/lib/snapshot.js +36 -88
- package/lib/snapshot.ts +44 -95
- package/package.json +1 -1
package/lib/MsgUnpacker.js
CHANGED
|
@@ -1,37 +1,56 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MsgUnpacker = exports.unpackString = exports.unpackInt = void 0;
|
|
2
4
|
var decoder = new TextDecoder('utf-8');
|
|
3
5
|
function unpackInt(pSrc) {
|
|
4
6
|
var result = 0;
|
|
5
7
|
var len = 1;
|
|
6
8
|
var iter = pSrc[Symbol.iterator]();
|
|
7
9
|
var src = iter.next();
|
|
8
|
-
// if (src.done)
|
|
9
|
-
// console.warn("Unexpected end", src)
|
|
10
10
|
src = src.value;
|
|
11
11
|
var sign = ((src >> 6) & 1);
|
|
12
12
|
result |= (src & 63);
|
|
13
13
|
for (var i = 0; i < 4; i++) {
|
|
14
|
-
if ((src & 128)
|
|
14
|
+
if ((src & 128) === 0)
|
|
15
15
|
break;
|
|
16
16
|
src = iter.next();
|
|
17
|
-
// console.log(src & 0b1000_0000)
|
|
18
|
-
// if (src.done)
|
|
19
|
-
// console.warn("Unexpected end", src);
|
|
20
17
|
src = src.value;
|
|
21
|
-
len
|
|
22
|
-
if (i == 3 && (src & 240) != 0)
|
|
23
|
-
console.warn("NonZeroIntPadding");
|
|
18
|
+
len++;
|
|
24
19
|
result |= ((src & 127)) << (6 + 7 * i);
|
|
25
20
|
}
|
|
26
|
-
if (len > 1 && src == 0) {
|
|
27
|
-
console.warn("OverlongIntEncoding");
|
|
28
|
-
}
|
|
29
21
|
result ^= -sign;
|
|
30
22
|
return { result: result, remaining: Array.from(iter) };
|
|
31
23
|
}
|
|
24
|
+
exports.unpackInt = unpackInt;
|
|
32
25
|
function unpackString(pSrc) {
|
|
33
26
|
var result = pSrc.slice(0, pSrc.indexOf(0));
|
|
34
27
|
pSrc = pSrc.slice(pSrc.indexOf(0), pSrc.length);
|
|
35
28
|
return { result: decoder.decode(new Uint8Array(result)), remaining: pSrc };
|
|
36
29
|
}
|
|
37
|
-
|
|
30
|
+
exports.unpackString = unpackString;
|
|
31
|
+
var MsgUnpacker = /** @class */ (function () {
|
|
32
|
+
function MsgUnpacker(pSrc) {
|
|
33
|
+
this.remaining = pSrc;
|
|
34
|
+
}
|
|
35
|
+
MsgUnpacker.prototype.unpackInt = function (_unpacked) {
|
|
36
|
+
if (_unpacked === void 0) { _unpacked = false; }
|
|
37
|
+
var unpacked;
|
|
38
|
+
if (!_unpacked) {
|
|
39
|
+
unpacked = unpackInt(this.remaining);
|
|
40
|
+
this.remaining = unpacked.remaining;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
unpacked = { result: this.remaining[0] };
|
|
44
|
+
this.remaining = this.remaining.slice(1);
|
|
45
|
+
}
|
|
46
|
+
return unpacked.result;
|
|
47
|
+
};
|
|
48
|
+
MsgUnpacker.prototype.unpackString = function () {
|
|
49
|
+
var unpacked = unpackString(this.remaining);
|
|
50
|
+
this.remaining = unpacked.remaining;
|
|
51
|
+
return unpacked.result;
|
|
52
|
+
};
|
|
53
|
+
return MsgUnpacker;
|
|
54
|
+
}());
|
|
55
|
+
exports.MsgUnpacker = MsgUnpacker;
|
|
56
|
+
// export = {MsgUnpacker, unpackInt, unpackString}
|
package/lib/MsgUnpacker.ts
CHANGED
|
@@ -1,44 +1,60 @@
|
|
|
1
1
|
var decoder = new TextDecoder('utf-8');
|
|
2
|
-
function unpackInt(pSrc: number[]): {result: number, remaining: number[]} {
|
|
2
|
+
export function unpackInt(pSrc: number[]): {result: number, remaining: number[]} {
|
|
3
3
|
var result = 0;
|
|
4
4
|
var len = 1;
|
|
5
5
|
|
|
6
6
|
var iter = pSrc[Symbol.iterator]()
|
|
7
7
|
var src: any = iter.next()
|
|
8
|
-
// if (src.done)
|
|
9
|
-
// console.warn("Unexpected end", src)
|
|
10
8
|
src = src.value
|
|
11
9
|
var sign = ((src >> 6) & 1)
|
|
12
10
|
|
|
13
11
|
result |= (src & 0b0011_1111)
|
|
14
12
|
for (let i = 0; i < 4; i++) {
|
|
15
13
|
|
|
16
|
-
if ((src & 0b1000_0000)
|
|
14
|
+
if ((src & 0b1000_0000) === 0)
|
|
17
15
|
break;
|
|
18
16
|
src = iter.next()
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// console.warn("Unexpected end", src);
|
|
23
|
-
src = src.value
|
|
24
|
-
len += 1;
|
|
25
|
-
if (i == 3 && (src & 0b1111_0000) != 0)
|
|
26
|
-
console.warn("NonZeroIntPadding")
|
|
18
|
+
src = src.value;
|
|
19
|
+
len++;
|
|
27
20
|
result |= ((src & 0b0111_1111)) << (6+7*i)
|
|
28
21
|
|
|
29
22
|
}
|
|
30
|
-
if (len > 1 && src == 0b0000_0000) {
|
|
31
|
-
console.warn("OverlongIntEncoding")
|
|
32
|
-
}
|
|
33
23
|
result ^= -sign;
|
|
34
24
|
|
|
35
25
|
return {result, remaining: Array.from(iter)};
|
|
36
26
|
}
|
|
37
|
-
function unpackString(pSrc: number[]): {result: string, remaining: number[]} {
|
|
27
|
+
export function unpackString(pSrc: number[]): {result: string, remaining: number[]} {
|
|
38
28
|
var result = pSrc.slice(0, pSrc.indexOf(0))
|
|
39
29
|
pSrc = pSrc.slice(pSrc.indexOf(0), pSrc.length)
|
|
40
30
|
return {result: decoder.decode(new Uint8Array(result)), remaining: pSrc}
|
|
41
31
|
}
|
|
42
32
|
|
|
33
|
+
export class MsgUnpacker {
|
|
34
|
+
remaining: number[];
|
|
35
|
+
constructor(pSrc: number[]) {
|
|
36
|
+
this.remaining = pSrc;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
unpackInt(_unpacked = false): number {
|
|
40
|
+
let unpacked;
|
|
41
|
+
if (!_unpacked) {
|
|
42
|
+
unpacked = unpackInt(this.remaining);
|
|
43
|
+
this.remaining = unpacked.remaining;
|
|
44
|
+
} else {
|
|
45
|
+
unpacked = {result: this.remaining[0]};
|
|
46
|
+
this.remaining = this.remaining.slice(1);
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
return unpacked.result;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
unpackString(): string {
|
|
53
|
+
let unpacked = unpackString(this.remaining);
|
|
54
|
+
this.remaining = unpacked.remaining;
|
|
55
|
+
return unpacked.result;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
43
59
|
|
|
44
|
-
export = {unpackInt, unpackString}
|
|
60
|
+
// export = {MsgUnpacker, unpackInt, unpackString}
|
package/lib/client.js
CHANGED
|
@@ -54,7 +54,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
54
54
|
var crypto_1 = require("crypto");
|
|
55
55
|
var dgram_1 = __importDefault(require("dgram"));
|
|
56
56
|
var stream_1 = require("stream");
|
|
57
|
-
var MsgUnpacker_1 =
|
|
57
|
+
var MsgUnpacker_1 = require("./MsgUnpacker");
|
|
58
58
|
var MsgPacker_1 = __importDefault(require("./MsgPacker"));
|
|
59
59
|
var snapshot_1 = require("./snapshot");
|
|
60
60
|
var huffman_1 = __importDefault(require("./huffman"));
|
|
@@ -306,11 +306,11 @@ var Client = /** @class */ (function (_super) {
|
|
|
306
306
|
chat.forEach(function (a) {
|
|
307
307
|
if (a.msg == "SV_CHAT") {
|
|
308
308
|
var unpacked = {};
|
|
309
|
-
unpacked.team = MsgUnpacker_1.
|
|
310
|
-
var remaining = MsgUnpacker_1.
|
|
311
|
-
unpacked.client_id = MsgUnpacker_1.
|
|
312
|
-
remaining = MsgUnpacker_1.
|
|
313
|
-
unpacked.message = MsgUnpacker_1.
|
|
309
|
+
unpacked.team = MsgUnpacker_1.unpackInt(a.raw.toJSON().data).result;
|
|
310
|
+
var remaining = MsgUnpacker_1.unpackInt(a.raw.toJSON().data).remaining;
|
|
311
|
+
unpacked.client_id = MsgUnpacker_1.unpackInt(remaining).result;
|
|
312
|
+
remaining = MsgUnpacker_1.unpackInt(remaining).remaining;
|
|
313
|
+
unpacked.message = MsgUnpacker_1.unpackString(remaining).result;
|
|
314
314
|
if (unpacked.client_id != -1)
|
|
315
315
|
unpacked.author = { ClientInfo: _this.client_infos[unpacked.client_id], PlayerInfo: _this.player_infos[unpacked.client_id] };
|
|
316
316
|
// console.log(unpacked)
|
|
@@ -323,13 +323,11 @@ var Client = /** @class */ (function (_super) {
|
|
|
323
323
|
chat.forEach(function (a) {
|
|
324
324
|
if (a.msg == "SV_KILL_MSG") {
|
|
325
325
|
var unpacked = {};
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
unpacked.victim_id =
|
|
329
|
-
|
|
330
|
-
unpacked.
|
|
331
|
-
remaining = MsgUnpacker_1.default.unpackInt(remaining).remaining;
|
|
332
|
-
unpacked.special_mode = MsgUnpacker_1.default.unpackInt(remaining).result;
|
|
326
|
+
var unpacker = new MsgUnpacker_1.MsgUnpacker(a.raw.toJSON().data);
|
|
327
|
+
unpacked.killer_id = unpacker.unpackInt();
|
|
328
|
+
unpacked.victim_id = unpacker.unpackInt();
|
|
329
|
+
unpacked.weapon = unpacker.unpackInt();
|
|
330
|
+
unpacked.special_mode = unpacker.unpackInt();
|
|
333
331
|
if (unpacked.victim_id != -1)
|
|
334
332
|
unpacked.victim = { ClientInfo: _this.client_infos[unpacked.victim_id], PlayerInfo: _this.player_infos[unpacked.victim_id] };
|
|
335
333
|
if (unpacked.killer_id != -1)
|
|
@@ -360,7 +358,7 @@ var Client = /** @class */ (function (_super) {
|
|
|
360
358
|
else if (a.toJSON().data[3] == 0x4) {
|
|
361
359
|
// disconnected
|
|
362
360
|
this.State = 0;
|
|
363
|
-
reason = (MsgUnpacker_1.
|
|
361
|
+
reason = (MsgUnpacker_1.unpackString(a.toJSON().data.slice(4)).result);
|
|
364
362
|
this.State = -1;
|
|
365
363
|
this.emit("disconnect", reason);
|
|
366
364
|
}
|
|
@@ -407,19 +405,19 @@ var Client = /** @class */ (function (_super) {
|
|
|
407
405
|
num_parts_1 = 1;
|
|
408
406
|
chunks.forEach(function (chunk) {
|
|
409
407
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
410
|
-
var AckGameTick = (MsgUnpacker_1.
|
|
411
|
-
chunk.raw = Buffer.from(MsgUnpacker_1.
|
|
412
|
-
var DeltaTick = MsgUnpacker_1.
|
|
408
|
+
var AckGameTick = (MsgUnpacker_1.unpackInt(chunk.raw.toJSON().data).result);
|
|
409
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.unpackInt((_a = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _a === void 0 ? void 0 : _a.toJSON().data).remaining);
|
|
410
|
+
var DeltaTick = MsgUnpacker_1.unpackInt((_b = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _b === void 0 ? void 0 : _b.toJSON().data).result;
|
|
413
411
|
if (chunk.msg == "SNAP") {
|
|
414
|
-
chunk.raw = Buffer.from(MsgUnpacker_1.
|
|
415
|
-
num_parts_1 = (MsgUnpacker_1.
|
|
416
|
-
chunk.raw = Buffer.from(MsgUnpacker_1.
|
|
417
|
-
part_1 = (MsgUnpacker_1.
|
|
412
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.unpackInt((_c = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _c === void 0 ? void 0 : _c.toJSON().data).remaining); // delta tick
|
|
413
|
+
num_parts_1 = (MsgUnpacker_1.unpackInt((_d = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _d === void 0 ? void 0 : _d.toJSON().data).result);
|
|
414
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.unpackInt((_e = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _e === void 0 ? void 0 : _e.toJSON().data).remaining); // num parts
|
|
415
|
+
part_1 = (MsgUnpacker_1.unpackInt((_f = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _f === void 0 ? void 0 : _f.toJSON().data).result);
|
|
418
416
|
}
|
|
419
|
-
chunk.raw = Buffer.from(MsgUnpacker_1.
|
|
417
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.unpackInt((_g = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _g === void 0 ? void 0 : _g.toJSON().data).remaining); // part
|
|
420
418
|
if (chunk.msg != "SNAP_EMPTY")
|
|
421
|
-
chunk.raw = Buffer.from(MsgUnpacker_1.
|
|
422
|
-
chunk.raw = Buffer.from(MsgUnpacker_1.
|
|
419
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.unpackInt((_h = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _h === void 0 ? void 0 : _h.toJSON().data).remaining); // crc
|
|
420
|
+
chunk.raw = Buffer.from(MsgUnpacker_1.unpackInt((_j = chunk === null || chunk === void 0 ? void 0 : chunk.raw) === null || _j === void 0 ? void 0 : _j.toJSON().data).remaining); // crc
|
|
423
421
|
if (part_1 == 0 || _this.snaps.length > 30) {
|
|
424
422
|
_this.snaps = [];
|
|
425
423
|
}
|
package/lib/client.ts
CHANGED
|
@@ -4,7 +4,10 @@ import net from 'dgram';
|
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import { EventEmitter } from 'stream';
|
|
6
6
|
import { spawn } from 'child_process';
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
import { unpackInt, unpackString, MsgUnpacker } from "./MsgUnpacker";
|
|
9
|
+
|
|
10
|
+
|
|
8
11
|
import MsgPacker from './MsgPacker';
|
|
9
12
|
import { Snapshot } from './snapshot';
|
|
10
13
|
import Huffman from "./huffman";
|
|
@@ -312,11 +315,11 @@ class Client extends EventEmitter {
|
|
|
312
315
|
chat.forEach(a => {
|
|
313
316
|
if (a.msg == "SV_CHAT") {
|
|
314
317
|
var unpacked: iMessage = {} as iMessage;
|
|
315
|
-
unpacked.team =
|
|
316
|
-
var remaining: number[] =
|
|
317
|
-
unpacked.client_id =
|
|
318
|
-
remaining =
|
|
319
|
-
unpacked.message =
|
|
318
|
+
unpacked.team = unpackInt(a.raw.toJSON().data).result;
|
|
319
|
+
var remaining: number[] = unpackInt(a.raw.toJSON().data).remaining;
|
|
320
|
+
unpacked.client_id = unpackInt(remaining).result;
|
|
321
|
+
remaining = unpackInt(remaining).remaining;
|
|
322
|
+
unpacked.message = unpackString(remaining).result;
|
|
320
323
|
if (unpacked.client_id != -1)
|
|
321
324
|
unpacked.author = { ClientInfo: this.client_infos[unpacked.client_id], PlayerInfo: this.player_infos[unpacked.client_id] }
|
|
322
325
|
// console.log(unpacked)
|
|
@@ -329,13 +332,11 @@ class Client extends EventEmitter {
|
|
|
329
332
|
chat.forEach(a => {
|
|
330
333
|
if (a.msg == "SV_KILL_MSG") {
|
|
331
334
|
var unpacked: iKillMsg = {} as iKillMsg;
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
unpacked.victim_id =
|
|
335
|
-
|
|
336
|
-
unpacked.
|
|
337
|
-
remaining = MsgUnpacker.unpackInt(remaining).remaining;
|
|
338
|
-
unpacked.special_mode = MsgUnpacker.unpackInt(remaining).result;
|
|
335
|
+
let unpacker = new MsgUnpacker(a.raw.toJSON().data);
|
|
336
|
+
unpacked.killer_id = unpacker.unpackInt();
|
|
337
|
+
unpacked.victim_id = unpacker.unpackInt();
|
|
338
|
+
unpacked.weapon = unpacker.unpackInt();
|
|
339
|
+
unpacked.special_mode = unpacker.unpackInt();
|
|
339
340
|
if (unpacked.victim_id != -1)
|
|
340
341
|
unpacked.victim = { ClientInfo: this.client_infos[unpacked.victim_id], PlayerInfo: this.player_infos[unpacked.victim_id] }
|
|
341
342
|
if (unpacked.killer_id != -1)
|
|
@@ -369,7 +370,7 @@ class Client extends EventEmitter {
|
|
|
369
370
|
} else if (a.toJSON().data[3] == 0x4) {
|
|
370
371
|
// disconnected
|
|
371
372
|
this.State = 0;
|
|
372
|
-
let reason: string = (
|
|
373
|
+
let reason: string = (unpackString(a.toJSON().data.slice(4)).result);
|
|
373
374
|
this.State = -1;
|
|
374
375
|
this.emit("disconnect", reason);
|
|
375
376
|
}
|
|
@@ -417,19 +418,19 @@ class Client extends EventEmitter {
|
|
|
417
418
|
let part = 0;
|
|
418
419
|
let num_parts = 1;
|
|
419
420
|
chunks.forEach(chunk => {
|
|
420
|
-
let AckGameTick = (
|
|
421
|
-
chunk.raw = Buffer.from(
|
|
422
|
-
let DeltaTick =
|
|
421
|
+
let AckGameTick = (unpackInt(chunk.raw.toJSON().data).result);
|
|
422
|
+
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining);
|
|
423
|
+
let DeltaTick = unpackInt(chunk?.raw?.toJSON().data).result
|
|
423
424
|
if (chunk.msg == "SNAP") {
|
|
424
|
-
chunk.raw = Buffer.from(
|
|
425
|
-
num_parts = (
|
|
426
|
-
chunk.raw = Buffer.from(
|
|
427
|
-
part = (
|
|
425
|
+
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // delta tick
|
|
426
|
+
num_parts = (unpackInt(chunk?.raw?.toJSON().data).result)
|
|
427
|
+
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // num parts
|
|
428
|
+
part = (unpackInt(chunk?.raw?.toJSON().data).result)
|
|
428
429
|
}
|
|
429
|
-
chunk.raw = Buffer.from(
|
|
430
|
+
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // part
|
|
430
431
|
if (chunk.msg != "SNAP_EMPTY")
|
|
431
|
-
chunk.raw = Buffer.from(
|
|
432
|
-
chunk.raw = Buffer.from(
|
|
432
|
+
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // crc
|
|
433
|
+
chunk.raw = Buffer.from(unpackInt(chunk?.raw?.toJSON().data).remaining); // crc
|
|
433
434
|
if (part == 0 || this.snaps.length > 30) {
|
|
434
435
|
this.snaps = [];
|
|
435
436
|
}
|
package/lib/snapshot.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Snapshot = void 0;
|
|
4
|
-
var
|
|
4
|
+
var MsgUnpacker_1 = require("./MsgUnpacker");
|
|
5
5
|
var decoder = new TextDecoder('utf-8');
|
|
6
6
|
var itemAppendix = [
|
|
7
7
|
{ "type_id": 0, "size": 0, "name": "obj_ex" },
|
|
@@ -289,111 +289,59 @@ var Snapshot = /** @class */ (function () {
|
|
|
289
289
|
return _item;
|
|
290
290
|
};
|
|
291
291
|
Snapshot.prototype.unpackSnapshot = function (snap, lost) {
|
|
292
|
-
// var size = MsgUnpacker.unpackInt(snap).result;
|
|
293
292
|
if (lost === void 0) { lost = 0; }
|
|
294
|
-
|
|
293
|
+
// var size = unpackInt(snap).result;
|
|
294
|
+
var unpacker = new MsgUnpacker_1.MsgUnpacker(snap);
|
|
295
|
+
// snap = unpackInt(snap).remaining; // size
|
|
295
296
|
/* key = (((type_id) << 16) | (id))
|
|
296
297
|
* key_to_id = ((key) & 0xffff)
|
|
297
298
|
* key_to_type_id = ((key >> 16) & 0xffff)
|
|
298
299
|
* https://github.com/heinrich5991/libtw2/blob/master/snapshot/src/
|
|
299
300
|
* https://github.com/heinrich5991/libtw2/blob/master/doc/snapshot.md
|
|
300
301
|
*/
|
|
301
|
-
// snap =
|
|
302
|
-
// console.log(
|
|
303
|
-
// snap =
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
302
|
+
// snap = unpackInt(snap).remaining;
|
|
303
|
+
// console.log(unpackInt(snap).result, "tick?") // key?
|
|
304
|
+
// snap = unpackInt(snap).remaining;
|
|
305
|
+
var num_removed_items = unpacker.unpackInt();
|
|
306
|
+
var num_item_deltas = unpacker.unpackInt();
|
|
307
|
+
unpacker.unpackInt(); // _zero padding
|
|
308
|
+
/*snapshot_delta:
|
|
309
|
+
[ 4] num_removed_items
|
|
310
|
+
[ 4] num_item_deltas
|
|
311
|
+
[ 4] _zero
|
|
312
|
+
[*4] removed_item_keys
|
|
313
|
+
[ ] item_deltas
|
|
314
|
+
*/
|
|
315
|
+
for (var i = 0; i < num_removed_items; i++) {
|
|
316
|
+
unpacker.unpackInt(); // removed_item_keys
|
|
317
|
+
}
|
|
318
|
+
/*item_delta:
|
|
319
|
+
[ 4] type_id
|
|
320
|
+
[ 4] id
|
|
321
|
+
[ 4] _size
|
|
322
|
+
[*4] data_delta*/
|
|
310
323
|
var items = { items: [], /* client_infos: client_infos, player_infos: player_infos,*/ lost: 0 };
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
var
|
|
314
|
-
// console.log(type_id, "type_id");
|
|
315
|
-
snap = MsgUnpacker.unpackInt(snap).remaining;
|
|
316
|
-
var id = MsgUnpacker.unpackInt(snap).result;
|
|
317
|
-
// console.log(id, "id");
|
|
324
|
+
for (var i = 0; i < num_item_deltas; i++) {
|
|
325
|
+
var type_id = unpacker.unpackInt();
|
|
326
|
+
var id = unpacker.unpackInt();
|
|
318
327
|
var key = (((type_id) << 16) | (id));
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
if (itemAppendix[type_id] && type_id > 0) {
|
|
322
|
-
// console.log("_size is not set")
|
|
323
|
-
// type_id is in itemAppendix -> _size is not set!
|
|
328
|
+
var _size = void 0;
|
|
329
|
+
if (type_id > 0 && type_id < itemAppendix.length) {
|
|
324
330
|
_size = itemAppendix[type_id].size;
|
|
325
331
|
}
|
|
326
|
-
else
|
|
327
|
-
|
|
328
|
-
// _size is set.
|
|
329
|
-
snap = MsgUnpacker.unpackInt(snap).remaining;
|
|
330
|
-
_size = (MsgUnpacker.unpackInt(snap).result);
|
|
331
|
-
}
|
|
332
|
-
// console.log(_size, "size!")
|
|
332
|
+
else
|
|
333
|
+
_size = unpacker.unpackInt();
|
|
333
334
|
var data = [];
|
|
334
|
-
for (var
|
|
335
|
-
if (
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
if (snap[0]) {
|
|
339
|
-
snap = MsgUnpacker.unpackInt(snap).remaining;
|
|
340
|
-
data.push(MsgUnpacker.unpackInt(snap).result);
|
|
341
|
-
}
|
|
342
|
-
else
|
|
343
|
-
break;
|
|
344
|
-
}
|
|
345
|
-
if (type_id > 0x4000 || type_id == 0) {
|
|
346
|
-
if (_size == 5 && id == 0) {
|
|
347
|
-
// console.log("DdnetCharacter???")
|
|
348
|
-
var Ddnet_Character = {
|
|
349
|
-
flags: data[0],
|
|
350
|
-
freeze_end: data[1],
|
|
351
|
-
jumps: data[2],
|
|
352
|
-
tele_checkpoint: data[3],
|
|
353
|
-
strong_weak_id: data[4]
|
|
354
|
-
// score: (!players[id] == undefined || typeof players[id].score == 'undefined') ? -1 : players[id].score
|
|
355
|
-
};
|
|
356
|
-
// console.log(Ddnet_Character)
|
|
357
|
-
if (Ddnet_Character.freeze_end > 0 || Ddnet_Character.freeze_end == -1) // freezed or deepfreezed
|
|
358
|
-
console.log(Ddnet_Character);
|
|
359
|
-
} // else
|
|
360
|
-
// console.log("lolol uuid??", _size, type_id, id, data)
|
|
361
|
-
}
|
|
362
|
-
if (type_id == 11) {
|
|
363
|
-
// obj_client_info!
|
|
364
|
-
var client_info = {
|
|
365
|
-
name: this.IntsToStr(data.slice(0, 4)),
|
|
366
|
-
clan: this.IntsToStr(data.slice(4, 7)),
|
|
367
|
-
country: Number(data.slice(7, 8)),
|
|
368
|
-
skin: this.IntsToStr(data.slice(8, 14)),
|
|
369
|
-
use_custom_color: Number(data.slice(14, 15)),
|
|
370
|
-
color_body: Number(data.slice(15, 16)),
|
|
371
|
-
color_feet: Number(data.slice(16, 17)),
|
|
372
|
-
};
|
|
373
|
-
client_infos[id] = client_info;
|
|
374
|
-
// console.log(client_info.name, client_info.clan, client_info.skin)
|
|
375
|
-
}
|
|
376
|
-
else if (type_id == 10) {
|
|
377
|
-
var player_info = {
|
|
378
|
-
local: Number(data.slice(0, 1)),
|
|
379
|
-
client_id: Number(data.slice(1, 2)),
|
|
380
|
-
team: Number(data.slice(2, 3)),
|
|
381
|
-
score: Number(data.slice(3, 4)),
|
|
382
|
-
latency: Number(data.slice(4, 5))
|
|
383
|
-
};
|
|
384
|
-
player_infos[player_info.client_id] = player_info;
|
|
385
|
-
// players[id].score = player_info.score
|
|
386
|
-
// console.log(player_info, client_infos[player_info.client_id], data)
|
|
335
|
+
for (var j = 0; j < _size; j++) {
|
|
336
|
+
if (unpacker.remaining.length > 0)
|
|
337
|
+
data.push(unpacker.unpackInt());
|
|
387
338
|
}
|
|
388
|
-
//
|
|
389
|
-
// console.log(this.parseItem(data, type_id), itemAppendix[type_id].name, type_id)
|
|
339
|
+
// console.log(type_id, id, _size, data);
|
|
390
340
|
var parsed = this.parseItem(data, type_id);
|
|
391
341
|
// console.log(data)
|
|
392
342
|
// console.log('')
|
|
393
343
|
items.items.push({ data: data, parsed: parsed, type_id: type_id, id: id, key: key });
|
|
394
344
|
}
|
|
395
|
-
// items.client_infos = client_infos;
|
|
396
|
-
// items.player_infos = player_infos;
|
|
397
345
|
return items;
|
|
398
346
|
};
|
|
399
347
|
return Snapshot;
|
package/lib/snapshot.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { MsgUnpacker } from "./MsgUnpacker";
|
|
2
2
|
var decoder = new TextDecoder('utf-8');
|
|
3
3
|
|
|
4
4
|
const itemAppendix: {"type_id": number, "size": number, "name": string}[] = [
|
|
@@ -287,11 +287,11 @@ class Snapshot {
|
|
|
287
287
|
|
|
288
288
|
return _item;
|
|
289
289
|
}
|
|
290
|
-
unpackSnapshot(snap: number[], lost = 0) {
|
|
291
|
-
// var size =
|
|
292
|
-
|
|
293
|
-
snap = MsgUnpacker.unpackInt(snap).remaining;
|
|
290
|
+
unpackSnapshot(snap: number[], lost = 0) {
|
|
291
|
+
// var size = unpackInt(snap).result;
|
|
292
|
+
let unpacker = new MsgUnpacker(snap);
|
|
294
293
|
|
|
294
|
+
// snap = unpackInt(snap).remaining; // size
|
|
295
295
|
|
|
296
296
|
/* key = (((type_id) << 16) | (id))
|
|
297
297
|
* key_to_id = ((key) & 0xffff)
|
|
@@ -300,106 +300,55 @@ class Snapshot {
|
|
|
300
300
|
* https://github.com/heinrich5991/libtw2/blob/master/doc/snapshot.md
|
|
301
301
|
*/
|
|
302
302
|
|
|
303
|
-
// snap =
|
|
304
|
-
// console.log(
|
|
305
|
-
// snap =
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
303
|
+
// snap = unpackInt(snap).remaining;
|
|
304
|
+
// console.log(unpackInt(snap).result, "tick?") // key?
|
|
305
|
+
// snap = unpackInt(snap).remaining;
|
|
306
|
+
let num_removed_items = unpacker.unpackInt();
|
|
307
|
+
let num_item_deltas = unpacker.unpackInt();
|
|
308
|
+
unpacker.unpackInt(); // _zero padding
|
|
309
|
+
/*snapshot_delta:
|
|
310
|
+
[ 4] num_removed_items
|
|
311
|
+
[ 4] num_item_deltas
|
|
312
|
+
[ 4] _zero
|
|
313
|
+
[*4] removed_item_keys
|
|
314
|
+
[ ] item_deltas
|
|
315
|
+
*/
|
|
316
|
+
|
|
317
|
+
for (let i = 0; i < num_removed_items; i++) {
|
|
318
|
+
unpacker.unpackInt(); // removed_item_keys
|
|
319
|
+
}
|
|
320
|
+
/*item_delta:
|
|
321
|
+
[ 4] type_id
|
|
322
|
+
[ 4] id
|
|
323
|
+
[ 4] _size
|
|
324
|
+
[*4] data_delta*/
|
|
325
|
+
let items: {'items': {'data': number[], 'parsed': Item, 'type_id': number, 'id': number, 'key': number}[]/*, 'client_infos': client_info[], 'player_infos': player_info[]*/, lost: number} = {items: [],/* client_infos: client_infos, player_infos: player_infos,*/ lost: 0};
|
|
326
|
+
|
|
327
|
+
for (let i = 0; i < num_item_deltas; i++) {
|
|
328
|
+
let type_id = unpacker.unpackInt();
|
|
329
|
+
let id = unpacker.unpackInt();
|
|
321
330
|
const key = (((type_id) << 16) | (id))
|
|
322
331
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if (itemAppendix[type_id] && type_id > 0) {
|
|
326
|
-
// console.log("_size is not set")
|
|
327
|
-
// type_id is in itemAppendix -> _size is not set!
|
|
332
|
+
let _size;
|
|
333
|
+
if (type_id > 0 && type_id < itemAppendix.length) {
|
|
328
334
|
_size = itemAppendix[type_id].size;
|
|
329
|
-
} else
|
|
330
|
-
|
|
331
|
-
// _size is set.
|
|
332
|
-
snap = MsgUnpacker.unpackInt(snap).remaining;
|
|
333
|
-
_size = (MsgUnpacker.unpackInt(snap).result);
|
|
334
|
-
}
|
|
335
|
-
// console.log(_size, "size!")
|
|
336
|
-
|
|
337
|
-
var data: number[] = []
|
|
338
|
-
for (let i = 0; i < _size; i++) {
|
|
339
|
-
if (snap.length == 0) {
|
|
340
|
-
items.lost++;
|
|
341
|
-
}
|
|
342
|
-
if (snap[0]) {
|
|
343
|
-
snap = MsgUnpacker.unpackInt(snap).remaining;
|
|
344
|
-
data.push(MsgUnpacker.unpackInt(snap).result);
|
|
345
|
-
} else
|
|
346
|
-
break;
|
|
335
|
+
} else
|
|
336
|
+
_size = unpacker.unpackInt();
|
|
347
337
|
|
|
338
|
+
let data = [];
|
|
339
|
+
for (let j = 0; j < _size; j++) {
|
|
340
|
+
if (unpacker.remaining.length > 0)
|
|
341
|
+
data.push(unpacker.unpackInt());
|
|
348
342
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
// console.log("DdnetCharacter???")
|
|
352
|
-
var Ddnet_Character: DdnetCharacter = {
|
|
353
|
-
flags: data[0],
|
|
354
|
-
freeze_end: data[1],
|
|
355
|
-
jumps: data[2],
|
|
356
|
-
tele_checkpoint: data[3],
|
|
357
|
-
strong_weak_id: data[4]
|
|
358
|
-
// score: (!players[id] == undefined || typeof players[id].score == 'undefined') ? -1 : players[id].score
|
|
359
|
-
}
|
|
360
|
-
// console.log(Ddnet_Character)
|
|
361
|
-
if (Ddnet_Character.freeze_end > 0 || Ddnet_Character.freeze_end == -1) // freezed or deepfreezed
|
|
362
|
-
|
|
363
|
-
console.log(Ddnet_Character)
|
|
364
|
-
} // else
|
|
365
|
-
// console.log("lolol uuid??", _size, type_id, id, data)
|
|
366
|
-
}
|
|
367
|
-
if (type_id == 11) {
|
|
368
|
-
// obj_client_info!
|
|
369
|
-
var client_info: ClientInfo = {
|
|
370
|
-
name: this.IntsToStr(data.slice(0, 4)),
|
|
371
|
-
clan: this.IntsToStr(data.slice(4, 7)),
|
|
372
|
-
country: Number(data.slice(7, 8)),
|
|
373
|
-
skin: this.IntsToStr(data.slice(8, 14)),
|
|
374
|
-
use_custom_color: Number(data.slice(14, 15)),
|
|
375
|
-
color_body: Number(data.slice(15, 16)),
|
|
376
|
-
color_feet: Number(data.slice(16, 17)),
|
|
377
|
-
// score: (!players[id] == undefined || typeof players[id].score == 'undefined') ? -1 : players[id].score
|
|
378
|
-
}
|
|
379
|
-
client_infos[id] = client_info;
|
|
380
|
-
// console.log(client_info.name, client_info.clan, client_info.skin)
|
|
381
|
-
} else if (type_id == 10) {
|
|
382
|
-
var player_info: PlayerInfo = {
|
|
383
|
-
local: Number(data.slice(0, 1)),
|
|
384
|
-
client_id: Number(data.slice(1, 2)),
|
|
385
|
-
team: Number(data.slice(2, 3)),
|
|
386
|
-
score: Number(data.slice(3, 4)),
|
|
387
|
-
latency: Number(data.slice(4, 5))
|
|
388
|
-
}
|
|
389
|
-
player_infos[player_info.client_id] = player_info;
|
|
390
|
-
// players[id].score = player_info.score
|
|
391
|
-
// console.log(player_info, client_infos[player_info.client_id], data)
|
|
392
|
-
}
|
|
393
|
-
// if (type_id == 10 || type_id == 11)
|
|
394
|
-
// console.log(this.parseItem(data, type_id), itemAppendix[type_id].name, type_id)
|
|
395
|
-
var parsed = this.parseItem(data, type_id)
|
|
343
|
+
// console.log(type_id, id, _size, data);
|
|
344
|
+
let parsed = this.parseItem(data, type_id)
|
|
396
345
|
|
|
397
346
|
// console.log(data)
|
|
398
347
|
// console.log('')
|
|
399
348
|
items.items.push({data, parsed, type_id, id, key})
|
|
400
349
|
}
|
|
401
|
-
|
|
402
|
-
|
|
350
|
+
|
|
351
|
+
|
|
403
352
|
return items;
|
|
404
353
|
}}
|
|
405
354
|
// module.exports = MsgPacker;
|