teeworlds 2.3.7 → 2.3.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/README.md +51 -60
- package/lib/MsgUnpacker.js +8 -12
- package/lib/MsgUnpacker.ts +8 -12
- package/lib/client.js +81 -47
- package/lib/client.ts +95 -56
- package/lib/snapshot.js +44 -32
- package/lib/snapshot.ts +28 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@ https://www.npmjs.com/package/teeworlds
|
|
|
6
6
|
|
|
7
7
|
# Usage
|
|
8
8
|
Example file:
|
|
9
|
-
```
|
|
9
|
+
```
|
|
10
|
+
const teeworlds = require('teeworlds')
|
|
10
11
|
let client = new teeworlds.Client("127.0.0.1", 8303, "nameless tee");
|
|
11
12
|
|
|
12
13
|
client.connect();
|
|
@@ -16,83 +17,73 @@ client.on("connected", () => {
|
|
|
16
17
|
})
|
|
17
18
|
|
|
18
19
|
client.on("disconnect", reason => {
|
|
19
|
-
//
|
|
20
|
+
// you got kicked from the server
|
|
20
21
|
console.log("Disconnected: " + reason);
|
|
21
22
|
})
|
|
22
23
|
|
|
23
24
|
client.on("message", message => {
|
|
24
25
|
/* {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
26
|
+
team: 0,
|
|
27
|
+
client_id: 14,
|
|
28
|
+
message: 'a',
|
|
29
|
+
author: {
|
|
30
|
+
ClientInfo: {
|
|
31
|
+
name: 'Nudelsaft c:',
|
|
32
|
+
clan: '',
|
|
33
|
+
country: 276,
|
|
34
|
+
skin: 'coala_toptri',
|
|
35
|
+
use_custom_color: 0,
|
|
36
|
+
color_body: 4718592,
|
|
37
|
+
color_feet: 5046016
|
|
38
|
+
},
|
|
39
|
+
PlayerInfo: { local: 0, client_id: 4, team: 0, score: 36, latency: 0 }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
41
42
|
*/
|
|
42
43
|
console.log(message);
|
|
43
44
|
})
|
|
44
45
|
|
|
45
46
|
client.on("kill", info => {
|
|
46
47
|
/* {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
48
|
+
killer_id: 14,
|
|
49
|
+
victim_id: 14,
|
|
50
|
+
weapon: -3,
|
|
51
|
+
special_mode: 0,
|
|
52
|
+
victim: {
|
|
53
|
+
ClientInfo: {
|
|
54
|
+
name: 'Nudelsaft c:',
|
|
55
|
+
clan: '',
|
|
56
|
+
country: 276,
|
|
57
|
+
skin: 'coala_toptri',
|
|
58
|
+
use_custom_color: 0,
|
|
59
|
+
color_body: 4718592,
|
|
60
|
+
color_feet: 5046016
|
|
61
|
+
},
|
|
62
|
+
PlayerInfo: { local: 0, client_id: 4, team: 0, score: 36, latency: 0 }
|
|
63
|
+
},
|
|
64
|
+
killer: {
|
|
65
|
+
ClientInfo: {
|
|
66
|
+
name: 'Nudelsaft c:',
|
|
67
|
+
clan: '',
|
|
68
|
+
country: 276,
|
|
69
|
+
skin: 'coala_toptri',
|
|
70
|
+
use_custom_color: 0,
|
|
71
|
+
color_body: 4718592,
|
|
72
|
+
color_feet: 5046016
|
|
73
|
+
},
|
|
74
|
+
PlayerInfo: { local: 0, client_id: 4, team: 0, score: 36, latency: 0 }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
76
77
|
*/
|
|
77
78
|
console.log(info)
|
|
78
79
|
})
|
|
79
80
|
|
|
80
81
|
process.on("SIGINT", () => {
|
|
81
|
-
client.Disconnect(); // disconnect on ctrl + c
|
|
82
|
+
client.Disconnect().then(() => process.exit(0)); // disconnect on ctrl + c
|
|
83
|
+
// process.exit()
|
|
82
84
|
})
|
|
83
85
|
process.stdin.on("data", data => {
|
|
84
86
|
client.Say(data.toString()); // write input in chat
|
|
85
87
|
|
|
86
88
|
})
|
|
87
|
-
|
|
88
|
-
function change() {
|
|
89
|
-
client.ChangePlayerInfo({
|
|
90
|
-
name: "new name",
|
|
91
|
-
clan: "new clan",
|
|
92
|
-
country: 12,
|
|
93
|
-
skin: "default",
|
|
94
|
-
use_custom_color: true,
|
|
95
|
-
color_body: 12,
|
|
96
|
-
color_feet: 1111
|
|
97
|
-
})
|
|
98
|
-
}```
|
|
89
|
+
```
|
package/lib/MsgUnpacker.js
CHANGED
|
@@ -3,21 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MsgUnpacker = exports.unpackString = exports.unpackInt = void 0;
|
|
4
4
|
var decoder = new TextDecoder('utf-8');
|
|
5
5
|
function unpackInt(pSrc) {
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
result |= (src & 63);
|
|
12
|
-
for (var i = 0; i < 4; i++) {
|
|
13
|
-
if ((src & 128) === 0)
|
|
6
|
+
var srcIndex = 0;
|
|
7
|
+
var sign = ((pSrc[srcIndex] >> 6) & 1);
|
|
8
|
+
var result = (pSrc[srcIndex] & 63);
|
|
9
|
+
while (srcIndex <= 4) {
|
|
10
|
+
if ((pSrc[srcIndex] & 128) === 0)
|
|
14
11
|
break;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
result |= ((src & 127)) << (6 + 7 * i);
|
|
12
|
+
srcIndex++;
|
|
13
|
+
result |= ((pSrc[srcIndex] & 127)) << (6 + 7 * (srcIndex - 1));
|
|
18
14
|
}
|
|
19
15
|
result ^= -sign;
|
|
20
|
-
return { result: result, remaining:
|
|
16
|
+
return { result: result, remaining: pSrc.slice(srcIndex + 1) };
|
|
21
17
|
}
|
|
22
18
|
exports.unpackInt = unpackInt;
|
|
23
19
|
function unpackString(pSrc) {
|
package/lib/MsgUnpacker.ts
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
const decoder = new TextDecoder('utf-8');
|
|
2
2
|
export function unpackInt(pSrc: number[]): {result: number, remaining: number[]} {
|
|
3
|
-
var result = 0;
|
|
4
3
|
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
src = src.value
|
|
8
|
-
var sign = ((src >> 6) & 1)
|
|
4
|
+
var srcIndex = 0;
|
|
5
|
+
const sign = ((pSrc[srcIndex] >> 6) & 1)
|
|
9
6
|
|
|
10
|
-
result
|
|
11
|
-
|
|
7
|
+
var result = (pSrc[srcIndex] & 0b0011_1111)
|
|
8
|
+
while (srcIndex <= 4) {
|
|
12
9
|
|
|
13
|
-
if ((
|
|
10
|
+
if ((pSrc[srcIndex] & 0b1000_0000) === 0)
|
|
14
11
|
break;
|
|
15
|
-
src = iter.next()
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
result |= ((
|
|
13
|
+
srcIndex++;
|
|
14
|
+
result |= ((pSrc[srcIndex] & 0b0111_1111)) << (6+7*(srcIndex-1))
|
|
19
15
|
|
|
20
16
|
}
|
|
21
17
|
result ^= -sign;
|
|
22
18
|
|
|
23
|
-
return {result, remaining:
|
|
19
|
+
return {result, remaining: pSrc.slice(srcIndex+1)};
|
|
24
20
|
}
|
|
25
21
|
export function unpackString(pSrc: number[]): {result: string, remaining: number[]} {
|
|
26
22
|
var result = pSrc.slice(0, pSrc.indexOf(0))
|
package/lib/client.js
CHANGED
|
@@ -108,6 +108,8 @@ var Client = /** @class */ (function (_super) {
|
|
|
108
108
|
_this.name = nickname;
|
|
109
109
|
_this.AckGameTick = 0;
|
|
110
110
|
_this.PredGameTick = 0;
|
|
111
|
+
_this.currentSnapshotGameTick = 0;
|
|
112
|
+
_this.SnapshotParts = 0;
|
|
111
113
|
_this.SnapUnpacker = new snapshot_1.Snapshot();
|
|
112
114
|
// this.eSnapHolder = [];
|
|
113
115
|
_this.requestResend = false;
|
|
@@ -298,6 +300,7 @@ var Client = /** @class */ (function (_super) {
|
|
|
298
300
|
};
|
|
299
301
|
Client.prototype.connect = function () {
|
|
300
302
|
var _this = this;
|
|
303
|
+
var _a;
|
|
301
304
|
this.State = States.STATE_CONNECTING;
|
|
302
305
|
var predTimer = setInterval(function () {
|
|
303
306
|
if (_this.State == States.STATE_ONLINE) {
|
|
@@ -314,14 +317,16 @@ var Client = /** @class */ (function (_super) {
|
|
|
314
317
|
else
|
|
315
318
|
clearInterval(connectInterval);
|
|
316
319
|
}, 500);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
320
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight)) {
|
|
321
|
+
var inputInterval_1 = setInterval(function () {
|
|
322
|
+
if (_this.State == States.STATE_OFFLINE)
|
|
323
|
+
clearInterval(inputInterval_1);
|
|
324
|
+
if (_this.State != States.STATE_ONLINE)
|
|
325
|
+
return;
|
|
326
|
+
_this.time = new Date().getTime();
|
|
327
|
+
_this.sendInput();
|
|
328
|
+
}, 500);
|
|
329
|
+
}
|
|
325
330
|
var resendTimeout = setInterval(function () {
|
|
326
331
|
if (_this.State != States.STATE_OFFLINE) {
|
|
327
332
|
if (((new Date().getTime()) - _this.lastSendTime) > 900 && _this.sentChunkQueue.length > 0) {
|
|
@@ -344,7 +349,7 @@ var Client = /** @class */ (function (_super) {
|
|
|
344
349
|
this.time = new Date().getTime() + 2000; // start sending keepalives after 2s
|
|
345
350
|
if (this.socket)
|
|
346
351
|
this.socket.on("message", function (a, rinfo) {
|
|
347
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
352
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
348
353
|
if (_this.State == 0 || rinfo.address != _this.host || rinfo.port != _this.port)
|
|
349
354
|
return;
|
|
350
355
|
clearInterval(connectInterval);
|
|
@@ -387,6 +392,7 @@ var Client = /** @class */ (function (_super) {
|
|
|
387
392
|
_this.lastRecvTime = new Date().getTime();
|
|
388
393
|
}
|
|
389
394
|
var unpacked = _this.Unpack(a);
|
|
395
|
+
unpacked.chunks = unpacked.chunks.filter(function (a) { return ((a.flags & 2) && (a.flags & 1)) ? a.seq > _this.ack : true; }); // filter out already received chunks
|
|
390
396
|
unpacked.chunks.forEach(function (a) {
|
|
391
397
|
if (a.flags & 1 && (a.flags !== 15)) { // vital and not connless
|
|
392
398
|
if (a.seq === (_this.ack + 1) % (1 << 10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
|
|
@@ -418,46 +424,50 @@ var Client = /** @class */ (function (_super) {
|
|
|
418
424
|
_this.sentChunkQueue.splice(i, 1);
|
|
419
425
|
}
|
|
420
426
|
});
|
|
421
|
-
var snapChunks =
|
|
427
|
+
var snapChunks = [];
|
|
428
|
+
if (((_g = _this.options) === null || _g === void 0 ? void 0 : _g.lightweight) !== true)
|
|
429
|
+
snapChunks = unpacked.chunks.filter(function (a) { return a.msg === "SNAP" || a.msg === "SNAP_SINGLE" || a.msg === "SNAP_EMPTY"; });
|
|
422
430
|
if (snapChunks.length > 0) {
|
|
423
431
|
var part = 0;
|
|
424
432
|
var num_parts = 1;
|
|
433
|
+
if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
|
|
434
|
+
_this.PredGameTick = _this.AckGameTick + 1;
|
|
425
435
|
snapChunks.forEach(function (chunk) {
|
|
426
436
|
var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
|
|
427
|
-
var
|
|
428
|
-
var
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
var part_size = 0;
|
|
447
|
-
if (chunk.msg != "SNAP_EMPTY") {
|
|
448
|
-
crc = unpacker.unpackInt(); // crc
|
|
449
|
-
part_size = unpacker.unpackInt();
|
|
450
|
-
}
|
|
451
|
-
if (part_1 === 0 || _this.snaps.length > 30) {
|
|
437
|
+
var NumParts = 1;
|
|
438
|
+
var Part = 0;
|
|
439
|
+
var GameTick = unpacker.unpackInt();
|
|
440
|
+
var DeltaTick = GameTick - unpacker.unpackInt();
|
|
441
|
+
var PartSize = 0;
|
|
442
|
+
var Crc = 0;
|
|
443
|
+
var CompleteSize = 0;
|
|
444
|
+
if (chunk.msg == "SNAP") {
|
|
445
|
+
NumParts = unpacker.unpackInt();
|
|
446
|
+
Part = unpacker.unpackInt();
|
|
447
|
+
}
|
|
448
|
+
if (chunk.msg != "SNAP_EMPTY") {
|
|
449
|
+
Crc = unpacker.unpackInt();
|
|
450
|
+
PartSize = unpacker.unpackInt();
|
|
451
|
+
}
|
|
452
|
+
if (PartSize < 1 || NumParts > 64 || Part < 0 || Part >= NumParts || PartSize <= 0 || PartSize > 900)
|
|
453
|
+
return;
|
|
454
|
+
if (GameTick >= _this.currentSnapshotGameTick) {
|
|
455
|
+
if (GameTick != _this.currentSnapshotGameTick) {
|
|
452
456
|
_this.snaps = [];
|
|
457
|
+
_this.SnapshotParts = 0;
|
|
458
|
+
_this.currentSnapshotGameTick = GameTick;
|
|
453
459
|
}
|
|
454
|
-
chunk.raw = Buffer.from(unpacker.remaining);
|
|
455
|
-
_this.snaps.
|
|
456
|
-
|
|
460
|
+
// chunk.raw = Buffer.from(unpacker.remaining);
|
|
461
|
+
_this.snaps[Part] = Buffer.from(unpacker.remaining);
|
|
462
|
+
_this.SnapshotParts |= 1 << Part;
|
|
463
|
+
if (_this.SnapshotParts == ((1 << NumParts) - 1)) {
|
|
457
464
|
var mergedSnaps = Buffer.concat(_this.snaps);
|
|
458
|
-
|
|
459
|
-
_this.
|
|
465
|
+
_this.SnapshotParts = 0;
|
|
466
|
+
var snapUnpacked = _this.SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, DeltaTick, GameTick);
|
|
460
467
|
_this.emit("snapshot");
|
|
468
|
+
_this.AckGameTick = snapUnpacked.recvTick;
|
|
469
|
+
if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
|
|
470
|
+
_this.PredGameTick = _this.AckGameTick + 1;
|
|
461
471
|
_this.sendInput();
|
|
462
472
|
}
|
|
463
473
|
}
|
|
@@ -517,7 +527,7 @@ var Client = /** @class */ (function (_super) {
|
|
|
517
527
|
}
|
|
518
528
|
else if ((unpacked.chunks[0] && chunkMessages.includes("CON_READY"))) {
|
|
519
529
|
var info = new MsgPacker_1.MsgPacker(20, false, 1);
|
|
520
|
-
if ((
|
|
530
|
+
if ((_h = _this.options) === null || _h === void 0 ? void 0 : _h.identity) {
|
|
521
531
|
info.AddString(_this.options.identity.name);
|
|
522
532
|
info.AddString(_this.options.identity.clan);
|
|
523
533
|
info.AddInt(_this.options.identity.country);
|
|
@@ -602,18 +612,27 @@ var Client = /** @class */ (function (_super) {
|
|
|
602
612
|
});
|
|
603
613
|
};
|
|
604
614
|
Client.prototype.Say = function (message, team) {
|
|
615
|
+
var _a;
|
|
605
616
|
if (team === void 0) { team = false; }
|
|
606
617
|
var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_SAY, false, 1);
|
|
607
618
|
packer.AddInt(team ? 1 : 0); // team
|
|
608
619
|
packer.AddString(message);
|
|
609
|
-
this.
|
|
620
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
|
|
621
|
+
this.QueueChunkEx(packer);
|
|
622
|
+
else
|
|
623
|
+
this.SendMsgEx(packer);
|
|
610
624
|
};
|
|
611
625
|
Client.prototype.Vote = function (vote) {
|
|
626
|
+
var _a;
|
|
612
627
|
var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_VOTE, false, 1);
|
|
613
628
|
packer.AddInt(vote ? 1 : -1);
|
|
614
|
-
this.
|
|
629
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
|
|
630
|
+
this.QueueChunkEx(packer);
|
|
631
|
+
else
|
|
632
|
+
this.SendMsgEx(packer);
|
|
615
633
|
};
|
|
616
634
|
Client.prototype.ChangePlayerInfo = function (playerInfo) {
|
|
635
|
+
var _a;
|
|
617
636
|
var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_CHANGEINFO, false, 1);
|
|
618
637
|
packer.AddString(playerInfo.name); //m_pName);
|
|
619
638
|
packer.AddString(playerInfo.clan); //m_pClan);
|
|
@@ -622,21 +641,36 @@ var Client = /** @class */ (function (_super) {
|
|
|
622
641
|
packer.AddInt(playerInfo.use_custom_color ? 1 : 0); //m_UseCustomColor);
|
|
623
642
|
packer.AddInt(playerInfo.color_body); //m_ColorBody);
|
|
624
643
|
packer.AddInt(playerInfo.color_feet); //m_ColorFeet);
|
|
625
|
-
this.
|
|
644
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
|
|
645
|
+
this.QueueChunkEx(packer);
|
|
646
|
+
else
|
|
647
|
+
this.SendMsgEx(packer);
|
|
626
648
|
};
|
|
627
649
|
Client.prototype.Kill = function () {
|
|
650
|
+
var _a;
|
|
628
651
|
var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_KILL, false, 1);
|
|
629
|
-
this.
|
|
652
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
|
|
653
|
+
this.QueueChunkEx(packer);
|
|
654
|
+
else
|
|
655
|
+
this.SendMsgEx(packer);
|
|
630
656
|
};
|
|
631
657
|
Client.prototype.ChangeTeam = function (team) {
|
|
658
|
+
var _a;
|
|
632
659
|
var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_SETTEAM, false, 1);
|
|
633
660
|
packer.AddInt(team);
|
|
634
|
-
this.
|
|
661
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
|
|
662
|
+
this.QueueChunkEx(packer);
|
|
663
|
+
else
|
|
664
|
+
this.SendMsgEx(packer);
|
|
635
665
|
};
|
|
636
666
|
Client.prototype.Emote = function (emote) {
|
|
667
|
+
var _a;
|
|
637
668
|
var packer = new MsgPacker_1.MsgPacker(NETMSGTYPE.CL_EMOTICON, false, 1);
|
|
638
669
|
packer.AddInt(emote);
|
|
639
|
-
this.
|
|
670
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.lightweight))
|
|
671
|
+
this.QueueChunkEx(packer);
|
|
672
|
+
else
|
|
673
|
+
this.SendMsgEx(packer);
|
|
640
674
|
};
|
|
641
675
|
Client.prototype.client_info = function (id) {
|
|
642
676
|
var delta = this.SnapUnpacker.deltas.filter(function (a) {
|
package/lib/client.ts
CHANGED
|
@@ -141,7 +141,8 @@ declare interface iOptions {
|
|
|
141
141
|
password?: string,
|
|
142
142
|
ddnet_version?: {version: number, release_version: string},
|
|
143
143
|
timeout?: number, // in ms
|
|
144
|
-
NET_VERSION?: string
|
|
144
|
+
NET_VERSION?: string,
|
|
145
|
+
lightweight?: boolean // experimental, only sends keepalive's (sendinput has to be called manually)
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
export declare interface Client {
|
|
@@ -161,6 +162,9 @@ export declare interface Client {
|
|
|
161
162
|
timer: number;
|
|
162
163
|
PredGameTick: number;
|
|
163
164
|
AckGameTick: number;
|
|
165
|
+
|
|
166
|
+
SnapshotParts: number;
|
|
167
|
+
currentSnapshotGameTick: number;
|
|
164
168
|
|
|
165
169
|
movement: Movement;
|
|
166
170
|
|
|
@@ -202,6 +206,10 @@ export class Client extends EventEmitter {
|
|
|
202
206
|
this.name = nickname;
|
|
203
207
|
this.AckGameTick = 0;
|
|
204
208
|
this.PredGameTick = 0;
|
|
209
|
+
this.currentSnapshotGameTick = 0;
|
|
210
|
+
|
|
211
|
+
this.SnapshotParts = 0;
|
|
212
|
+
|
|
205
213
|
this.SnapUnpacker = new Snapshot();
|
|
206
214
|
// this.eSnapHolder = [];
|
|
207
215
|
this.requestResend = false;
|
|
@@ -434,15 +442,16 @@ export class Client extends EventEmitter {
|
|
|
434
442
|
else
|
|
435
443
|
clearInterval(connectInterval)
|
|
436
444
|
}, 500);
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
445
|
+
if (!this.options?.lightweight) {
|
|
446
|
+
let inputInterval = setInterval(() => {
|
|
447
|
+
if (this.State == States.STATE_OFFLINE)
|
|
448
|
+
clearInterval(inputInterval)
|
|
449
|
+
if (this.State != States.STATE_ONLINE)
|
|
450
|
+
return;
|
|
451
|
+
this.time = new Date().getTime();
|
|
452
|
+
this.sendInput();
|
|
453
|
+
}, 500)
|
|
454
|
+
}
|
|
446
455
|
|
|
447
456
|
let resendTimeout = setInterval(() => {
|
|
448
457
|
if (this.State != States.STATE_OFFLINE) {
|
|
@@ -514,6 +523,8 @@ export class Client extends EventEmitter {
|
|
|
514
523
|
|
|
515
524
|
|
|
516
525
|
var unpacked: _packet = this.Unpack(a);
|
|
526
|
+
unpacked.chunks = unpacked.chunks.filter(a => ((a.flags & 2) && (a.flags & 1)) ? a.seq! > this.ack : true); // filter out already received chunks
|
|
527
|
+
|
|
517
528
|
unpacked.chunks.forEach(a => {
|
|
518
529
|
if (a.flags & 1 && (a.flags !== 15)) { // vital and not connless
|
|
519
530
|
if (a.seq === (this.ack+1)%(1<<10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
|
|
@@ -549,59 +560,69 @@ export class Client extends EventEmitter {
|
|
|
549
560
|
this.sentChunkQueue.splice(i, 1);
|
|
550
561
|
}
|
|
551
562
|
})
|
|
552
|
-
|
|
563
|
+
let snapChunks: chunk[] = [];
|
|
564
|
+
if (this.options?.lightweight !== true)
|
|
565
|
+
snapChunks = unpacked.chunks.filter(a => a.msg === "SNAP" || a.msg === "SNAP_SINGLE" || a.msg === "SNAP_EMPTY");
|
|
553
566
|
if (snapChunks.length > 0) {
|
|
554
567
|
let part = 0;
|
|
555
568
|
let num_parts = 1;
|
|
569
|
+
if (Math.abs(this.PredGameTick - this.AckGameTick) > 10)
|
|
570
|
+
this.PredGameTick = this.AckGameTick + 1;
|
|
571
|
+
|
|
556
572
|
snapChunks.forEach(chunk => {
|
|
557
573
|
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
|
|
558
574
|
|
|
559
|
-
let
|
|
560
|
-
|
|
561
|
-
let
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
let num_parts = 1;
|
|
573
|
-
let part = 0;
|
|
575
|
+
let NumParts = 1;
|
|
576
|
+
let Part = 0;
|
|
577
|
+
let GameTick = unpacker.unpackInt();
|
|
578
|
+
let DeltaTick = GameTick - unpacker.unpackInt();
|
|
579
|
+
let PartSize = 0;
|
|
580
|
+
let Crc = 0;
|
|
581
|
+
let CompleteSize = 0;
|
|
582
|
+
|
|
583
|
+
if (chunk.msg == "SNAP") {
|
|
584
|
+
NumParts = unpacker.unpackInt();
|
|
585
|
+
Part = unpacker.unpackInt();
|
|
586
|
+
}
|
|
574
587
|
|
|
575
|
-
if (chunk.msg === "SNAP") {
|
|
576
|
-
num_parts = unpacker.unpackInt();
|
|
577
|
-
part = unpacker.unpackInt();
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
let crc = 0;
|
|
581
|
-
let part_size = 0;
|
|
582
588
|
if (chunk.msg != "SNAP_EMPTY") {
|
|
583
|
-
|
|
584
|
-
|
|
589
|
+
Crc = unpacker.unpackInt();
|
|
590
|
+
PartSize = unpacker.unpackInt();
|
|
585
591
|
}
|
|
586
|
-
if (part === 0 || this.snaps.length > 30) {
|
|
587
|
-
this.snaps = [];
|
|
588
|
-
}
|
|
589
|
-
chunk.raw = Buffer.from(unpacker.remaining);
|
|
590
|
-
this.snaps.push(chunk.raw)
|
|
591
|
-
|
|
592
|
-
if ((num_parts - 1) === part && this.snaps.length === num_parts) {
|
|
593
592
|
|
|
594
|
-
|
|
593
|
+
if (PartSize < 1 || NumParts > 64 || Part < 0 || Part >= NumParts || PartSize <= 0 || PartSize > 900)
|
|
594
|
+
return;
|
|
595
595
|
|
|
596
|
-
|
|
597
|
-
this.
|
|
598
|
-
|
|
599
|
-
|
|
596
|
+
if (GameTick >= this.currentSnapshotGameTick) {
|
|
597
|
+
if (GameTick != this.currentSnapshotGameTick) {
|
|
598
|
+
this.snaps = [];
|
|
599
|
+
this.SnapshotParts = 0;
|
|
600
|
+
this.currentSnapshotGameTick = GameTick;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// chunk.raw = Buffer.from(unpacker.remaining);
|
|
604
|
+
this.snaps[Part] = Buffer.from(unpacker.remaining);
|
|
605
|
+
|
|
606
|
+
this.SnapshotParts |= 1 << Part;
|
|
600
607
|
|
|
601
|
-
this.
|
|
602
|
-
|
|
608
|
+
if (this.SnapshotParts == ((1 << NumParts) - 1)) {
|
|
609
|
+
let mergedSnaps = Buffer.concat(this.snaps);
|
|
610
|
+
this.SnapshotParts = 0;
|
|
603
611
|
|
|
604
|
-
|
|
612
|
+
let snapUnpacked = this.SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, DeltaTick, GameTick);
|
|
613
|
+
|
|
614
|
+
this.emit("snapshot");
|
|
615
|
+
this.AckGameTick = snapUnpacked.recvTick;
|
|
616
|
+
if (Math.abs(this.PredGameTick - this.AckGameTick) > 10)
|
|
617
|
+
this.PredGameTick = this.AckGameTick + 1;
|
|
618
|
+
|
|
619
|
+
this.sendInput();
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
|
|
605
626
|
})
|
|
606
627
|
}
|
|
607
628
|
var chunkMessages = unpacked.chunks.map(a => a.msg)
|
|
@@ -749,12 +770,18 @@ export class Client extends EventEmitter {
|
|
|
749
770
|
var packer = new MsgPacker(NETMSGTYPE.CL_SAY, false, 1);
|
|
750
771
|
packer.AddInt(team ? 1 : 0); // team
|
|
751
772
|
packer.AddString(message);
|
|
752
|
-
this.
|
|
773
|
+
if (!this.options?.lightweight)
|
|
774
|
+
this.QueueChunkEx(packer);
|
|
775
|
+
else
|
|
776
|
+
this.SendMsgEx(packer);
|
|
753
777
|
}
|
|
754
778
|
Vote(vote: boolean) {
|
|
755
779
|
var packer = new MsgPacker(NETMSGTYPE.CL_VOTE, false, 1);
|
|
756
780
|
packer.AddInt(vote ? 1 : -1);
|
|
757
|
-
this.
|
|
781
|
+
if (!this.options?.lightweight)
|
|
782
|
+
this.QueueChunkEx(packer);
|
|
783
|
+
else
|
|
784
|
+
this.SendMsgEx(packer);
|
|
758
785
|
}
|
|
759
786
|
ChangePlayerInfo(playerInfo: ClientInfo) {
|
|
760
787
|
var packer = new MsgPacker(NETMSGTYPE.CL_CHANGEINFO, false, 1);
|
|
@@ -765,21 +792,33 @@ export class Client extends EventEmitter {
|
|
|
765
792
|
packer.AddInt(playerInfo.use_custom_color ? 1 : 0); //m_UseCustomColor);
|
|
766
793
|
packer.AddInt(playerInfo.color_body); //m_ColorBody);
|
|
767
794
|
packer.AddInt(playerInfo.color_feet); //m_ColorFeet);
|
|
768
|
-
this.
|
|
795
|
+
if (!this.options?.lightweight)
|
|
796
|
+
this.QueueChunkEx(packer);
|
|
797
|
+
else
|
|
798
|
+
this.SendMsgEx(packer);
|
|
769
799
|
}
|
|
770
800
|
Kill() {
|
|
771
801
|
var packer = new MsgPacker(NETMSGTYPE.CL_KILL, false, 1);
|
|
772
|
-
this.
|
|
802
|
+
if (!this.options?.lightweight)
|
|
803
|
+
this.QueueChunkEx(packer);
|
|
804
|
+
else
|
|
805
|
+
this.SendMsgEx(packer);
|
|
773
806
|
}
|
|
774
807
|
ChangeTeam(team: number) {
|
|
775
808
|
var packer = new MsgPacker(NETMSGTYPE.CL_SETTEAM, false, 1);
|
|
776
809
|
packer.AddInt(team);
|
|
777
|
-
this.
|
|
810
|
+
if (!this.options?.lightweight)
|
|
811
|
+
this.QueueChunkEx(packer);
|
|
812
|
+
else
|
|
813
|
+
this.SendMsgEx(packer);
|
|
778
814
|
}
|
|
779
815
|
Emote(emote: number) {
|
|
780
816
|
var packer = new MsgPacker(NETMSGTYPE.CL_EMOTICON, false, 1);
|
|
781
817
|
packer.AddInt(emote);
|
|
782
|
-
this.
|
|
818
|
+
if (!this.options?.lightweight)
|
|
819
|
+
this.QueueChunkEx(packer);
|
|
820
|
+
else
|
|
821
|
+
this.SendMsgEx(packer);
|
|
783
822
|
}
|
|
784
823
|
client_info(id: number) {
|
|
785
824
|
let delta = this.SnapUnpacker.deltas.filter(a =>
|
package/lib/snapshot.js
CHANGED
|
@@ -57,20 +57,20 @@ var Snapshot = /** @class */ (function () {
|
|
|
57
57
|
}
|
|
58
58
|
Snapshot.prototype.IntsToStr = function (pInts) {
|
|
59
59
|
var pIntz = [];
|
|
60
|
-
var pStr = ''
|
|
60
|
+
// var pStr = ''
|
|
61
61
|
for (var _i = 0, pInts_1 = pInts; _i < pInts_1.length; _i++) {
|
|
62
62
|
var x = pInts_1[_i];
|
|
63
|
-
pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
|
|
63
|
+
// pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
|
|
64
64
|
pIntz.push((((x) >> 24) & 0xff) - 128);
|
|
65
|
-
pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
|
|
65
|
+
// pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
|
|
66
66
|
pIntz.push((((x) >> 16) & 0xff) - 128);
|
|
67
|
-
pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
|
|
67
|
+
// pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
|
|
68
68
|
pIntz.push((((x) >> 8) & 0xff) - 128);
|
|
69
|
-
pStr += String.fromCharCode(((x) & 0xff) - 128);
|
|
69
|
+
// pStr += String.fromCharCode(((x) & 0xff) - 128);
|
|
70
70
|
pIntz.push(((x) & 0xff) - 128);
|
|
71
71
|
}
|
|
72
72
|
pIntz.splice(-1, 1);
|
|
73
|
-
pStr = decoder.decode(new Uint8Array(pIntz));
|
|
73
|
+
var pStr = decoder.decode(new Uint8Array(pIntz));
|
|
74
74
|
pStr = pStr.replace(/\0.*/g, ''); // Remove content from first null char to end.
|
|
75
75
|
return pStr;
|
|
76
76
|
};
|
|
@@ -302,8 +302,9 @@ var Snapshot = /** @class */ (function () {
|
|
|
302
302
|
}
|
|
303
303
|
if (snap.length == 0) {
|
|
304
304
|
// empty snap, copy old one into new ack
|
|
305
|
-
this.eSnapHolder.
|
|
306
|
-
|
|
305
|
+
this.eSnapHolder.forEach(function (snap) {
|
|
306
|
+
if (snap.ack == deltatick)
|
|
307
|
+
_this.eSnapHolder.push({ Snapshot: snap.Snapshot, ack: recvTick });
|
|
307
308
|
});
|
|
308
309
|
return { items: [], recvTick: recvTick };
|
|
309
310
|
}
|
|
@@ -316,15 +317,6 @@ var Snapshot = /** @class */ (function () {
|
|
|
316
317
|
var num_removed_items = unpacker.unpackInt();
|
|
317
318
|
var num_item_deltas = unpacker.unpackInt();
|
|
318
319
|
unpacker.unpackInt(); // _zero padding
|
|
319
|
-
var _loop_1 = function (i) {
|
|
320
|
-
var deleted_key = unpacker.unpackInt(); // removed_item_keys
|
|
321
|
-
var index = this_1.deltas.map(function (delta) { return delta.key; }).indexOf(deleted_key);
|
|
322
|
-
// console.log("deleting ", deleted_key, index)
|
|
323
|
-
if (index > -1)
|
|
324
|
-
this_1.deltas.splice(index, 1);
|
|
325
|
-
this_1.eSnapHolder = this_1.eSnapHolder.filter(function (a) { return a.Snapshot.Key !== deleted_key; });
|
|
326
|
-
};
|
|
327
|
-
var this_1 = this;
|
|
328
320
|
/*snapshot_delta:
|
|
329
321
|
[ 4] num_removed_items
|
|
330
322
|
[ 4] num_item_deltas
|
|
@@ -332,9 +324,22 @@ var Snapshot = /** @class */ (function () {
|
|
|
332
324
|
[*4] removed_item_keys
|
|
333
325
|
[ ] item_deltas
|
|
334
326
|
*/
|
|
327
|
+
var deleted = [];
|
|
328
|
+
var _loop_1 = function (i) {
|
|
329
|
+
var deleted_key = unpacker.unpackInt(); // removed_item_keys
|
|
330
|
+
// let index = this.deltas.map(delta => delta.key).indexOf(deleted_key);
|
|
331
|
+
var index = this_1.deltas.findIndex(function (delta) { return delta.key === deleted_key; });
|
|
332
|
+
// console.log("deleting ", deleted_key, index)
|
|
333
|
+
if (index > -1)
|
|
334
|
+
this_1.deltas.splice(index, 1);
|
|
335
|
+
deleted.push(deleted_key);
|
|
336
|
+
};
|
|
337
|
+
var this_1 = this;
|
|
335
338
|
for (var i = 0; i < num_removed_items; i++) {
|
|
336
339
|
_loop_1(i);
|
|
337
340
|
}
|
|
341
|
+
if (deleted.length)
|
|
342
|
+
this.eSnapHolder = this.eSnapHolder.filter(function (a) { return !deleted.includes(a.Snapshot.Key); });
|
|
338
343
|
/*item_delta:
|
|
339
344
|
[ 4] type_id
|
|
340
345
|
[ 4] id
|
|
@@ -350,7 +355,7 @@ var Snapshot = /** @class */ (function () {
|
|
|
350
355
|
deltaSnaps.forEach(function (a) {
|
|
351
356
|
newSnaps.push({ Snapshot: a.Snapshot, ack: recvTick });
|
|
352
357
|
});
|
|
353
|
-
|
|
358
|
+
var _loop_2 = function (i) {
|
|
354
359
|
var type_id = unpacker.unpackInt();
|
|
355
360
|
var id = unpacker.unpackInt();
|
|
356
361
|
var key = (((type_id) << 16) | (id));
|
|
@@ -369,31 +374,38 @@ var Snapshot = /** @class */ (function () {
|
|
|
369
374
|
}
|
|
370
375
|
// console.log(index, deltatick)
|
|
371
376
|
if (deltatick >= 0) {
|
|
372
|
-
|
|
377
|
+
// let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
|
|
378
|
+
var index = deltaSnaps.findIndex(function (delta) { return delta.Snapshot.Key === key; });
|
|
373
379
|
if (index > -1) {
|
|
374
380
|
var out = UndiffItem(deltaSnaps[index].Snapshot.Data, data);
|
|
375
381
|
data = out;
|
|
376
382
|
} // else no previous, use new data
|
|
377
383
|
}
|
|
378
|
-
var parsed =
|
|
379
|
-
|
|
384
|
+
var parsed = this_2.parseItem(data, type_id);
|
|
385
|
+
this_2.eSnapHolder.push({ Snapshot: { Data: data, Key: key }, ack: recvTick });
|
|
380
386
|
items.items.push({ data: data, parsed: parsed, type_id: type_id, id: id, key: key });
|
|
387
|
+
};
|
|
388
|
+
var this_2 = this;
|
|
389
|
+
for (var i = 0; i < num_item_deltas; i++) {
|
|
390
|
+
_loop_2(i);
|
|
381
391
|
}
|
|
382
|
-
var
|
|
383
|
-
if (
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
var ____index = this_2.deltas.map(function (delta) { return delta.key; }).indexOf(newSnap.Snapshot.Key);
|
|
387
|
-
if (____index > -1 && deltatick > -1) {
|
|
388
|
-
this_2.deltas[____index] = { data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this_2.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff)) };
|
|
392
|
+
var _loop_3 = function (newSnap) {
|
|
393
|
+
if (this_3.eSnapHolder.findIndex(function (a) { return a.ack == newSnap.ack && a.Snapshot.Key == newSnap.Snapshot.Key; }) === -1) { // ugly copy new snap to eSnapHolder (if it isnt pushed already)
|
|
394
|
+
this_3.eSnapHolder.push({ Snapshot: { Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key }, ack: recvTick });
|
|
389
395
|
}
|
|
390
|
-
|
|
391
|
-
|
|
396
|
+
if (deltatick > -1) {
|
|
397
|
+
var ____index = this_3.deltas.findIndex(function (delta) { return delta.key == newSnap.Snapshot.Key; });
|
|
398
|
+
if (____index > -1) {
|
|
399
|
+
this_3.deltas[____index] = { data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this_3.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff)) };
|
|
400
|
+
return "continue";
|
|
401
|
+
}
|
|
402
|
+
} // else
|
|
403
|
+
this_3.deltas.push({ data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this_3.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff)) });
|
|
392
404
|
};
|
|
393
|
-
var
|
|
405
|
+
var this_3 = this;
|
|
394
406
|
for (var _i = 0, newSnaps_1 = newSnaps; _i < newSnaps_1.length; _i++) {
|
|
395
407
|
var newSnap = newSnaps_1[_i];
|
|
396
|
-
|
|
408
|
+
_loop_3(newSnap);
|
|
397
409
|
}
|
|
398
410
|
return { items: items, recvTick: recvTick };
|
|
399
411
|
};
|
package/lib/snapshot.ts
CHANGED
|
@@ -60,19 +60,19 @@ export class Snapshot {
|
|
|
60
60
|
|
|
61
61
|
private IntsToStr(pInts: number[]): string {
|
|
62
62
|
var pIntz: number[] = [];
|
|
63
|
-
var pStr = ''
|
|
63
|
+
// var pStr = ''
|
|
64
64
|
for (let x of pInts) {
|
|
65
|
-
pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
|
|
65
|
+
// pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
|
|
66
66
|
pIntz.push((((x) >> 24) & 0xff) - 128);
|
|
67
|
-
pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
|
|
67
|
+
// pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
|
|
68
68
|
pIntz.push((((x) >> 16) & 0xff) - 128);
|
|
69
|
-
pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
|
|
69
|
+
// pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
|
|
70
70
|
pIntz.push((((x) >> 8) & 0xff) - 128);
|
|
71
|
-
pStr += String.fromCharCode(((x) & 0xff) - 128);
|
|
71
|
+
// pStr += String.fromCharCode(((x) & 0xff) - 128);
|
|
72
72
|
pIntz.push(((x) & 0xff) - 128);
|
|
73
73
|
}
|
|
74
74
|
pIntz.splice(-1, 1)
|
|
75
|
-
pStr = decoder.decode(new Uint8Array(pIntz));
|
|
75
|
+
let pStr = decoder.decode(new Uint8Array(pIntz));
|
|
76
76
|
|
|
77
77
|
pStr = pStr.replace(/\0.*/g, ''); // Remove content from first null char to end.
|
|
78
78
|
return pStr;
|
|
@@ -306,7 +306,8 @@ export class Snapshot {
|
|
|
306
306
|
}
|
|
307
307
|
if (snap.length == 0) {
|
|
308
308
|
// empty snap, copy old one into new ack
|
|
309
|
-
this.eSnapHolder.
|
|
309
|
+
this.eSnapHolder.forEach(snap => {
|
|
310
|
+
if (snap.ack == deltatick)
|
|
310
311
|
this.eSnapHolder.push({Snapshot: snap.Snapshot, ack: recvTick});
|
|
311
312
|
|
|
312
313
|
})
|
|
@@ -330,14 +331,19 @@ export class Snapshot {
|
|
|
330
331
|
[ ] item_deltas
|
|
331
332
|
*/
|
|
332
333
|
|
|
334
|
+
var deleted: number[] = [];
|
|
333
335
|
for (let i = 0; i < num_removed_items; i++) {
|
|
334
336
|
let deleted_key = unpacker.unpackInt(); // removed_item_keys
|
|
335
|
-
let index = this.deltas.map(delta => delta.key).indexOf(deleted_key);
|
|
337
|
+
// let index = this.deltas.map(delta => delta.key).indexOf(deleted_key);
|
|
338
|
+
let index = this.deltas.findIndex(delta => delta.key === deleted_key);
|
|
336
339
|
// console.log("deleting ", deleted_key, index)
|
|
337
340
|
if (index > -1)
|
|
338
341
|
this.deltas.splice(index, 1);
|
|
339
|
-
|
|
342
|
+
deleted.push(deleted_key)
|
|
340
343
|
}
|
|
344
|
+
if (deleted.length)
|
|
345
|
+
this.eSnapHolder = this.eSnapHolder.filter(a => !deleted.includes(a.Snapshot.Key));
|
|
346
|
+
|
|
341
347
|
/*item_delta:
|
|
342
348
|
[ 4] type_id
|
|
343
349
|
[ 4] id
|
|
@@ -378,7 +384,8 @@ export class Snapshot {
|
|
|
378
384
|
}
|
|
379
385
|
// console.log(index, deltatick)
|
|
380
386
|
if (deltatick >= 0) {
|
|
381
|
-
let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
|
|
387
|
+
// let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
|
|
388
|
+
let index = deltaSnaps.findIndex(delta => delta.Snapshot.Key === key);
|
|
382
389
|
if (index > -1) {
|
|
383
390
|
|
|
384
391
|
let out = UndiffItem(deltaSnaps[index].Snapshot.Data, data)
|
|
@@ -395,21 +402,25 @@ export class Snapshot {
|
|
|
395
402
|
|
|
396
403
|
}
|
|
397
404
|
for (let newSnap of newSnaps) {
|
|
398
|
-
if (this.eSnapHolder.
|
|
405
|
+
if (this.eSnapHolder.findIndex(a => a.ack == newSnap.ack && a.Snapshot.Key == newSnap.Snapshot.Key) === -1) { // ugly copy new snap to eSnapHolder (if it isnt pushed already)
|
|
399
406
|
this.eSnapHolder.push({Snapshot: {Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key}, ack: recvTick});
|
|
400
407
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
408
|
+
if (deltatick > -1) {
|
|
409
|
+
let ____index = this.deltas.findIndex(delta => delta.key == newSnap.Snapshot.Key)
|
|
410
|
+
|
|
411
|
+
if (____index > -1) {
|
|
412
|
+
this.deltas[____index] = {data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff))};
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
} // else
|
|
416
|
+
this.deltas.push({data: newSnap.Snapshot.Data, key: newSnap.Snapshot.Key, id: newSnap.Snapshot.Key & 0xffff, type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff), parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff))});
|
|
407
417
|
}
|
|
408
418
|
|
|
409
419
|
|
|
410
420
|
return {items, recvTick};
|
|
411
421
|
}
|
|
412
422
|
}
|
|
423
|
+
|
|
413
424
|
function UndiffItem(oldItem: number[], newItem: number[]): number[] {
|
|
414
425
|
let out: number[] = newItem;
|
|
415
426
|
if (JSON.stringify(newItem) === JSON.stringify(oldItem))
|