teeworlds 2.3.8 → 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 +3 -9
- package/lib/MsgUnpacker.ts +5 -11
- package/lib/client.js +35 -30
- package/lib/client.ts +56 -39
- 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,20 +3,14 @@ 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 result = 0;
|
|
7
|
-
// var iter = pSrc[Symbol.iterator]()
|
|
8
|
-
// var src: any = iter.next()
|
|
9
|
-
// src = src.value
|
|
10
6
|
var srcIndex = 0;
|
|
11
7
|
var sign = ((pSrc[srcIndex] >> 6) & 1);
|
|
12
|
-
result
|
|
13
|
-
|
|
8
|
+
var result = (pSrc[srcIndex] & 63);
|
|
9
|
+
while (srcIndex <= 4) {
|
|
14
10
|
if ((pSrc[srcIndex] & 128) === 0)
|
|
15
11
|
break;
|
|
16
|
-
// src = iter.next()
|
|
17
|
-
// src = src.value;
|
|
18
12
|
srcIndex++;
|
|
19
|
-
result |= ((pSrc[srcIndex] & 127)) << (6 + 7 *
|
|
13
|
+
result |= ((pSrc[srcIndex] & 127)) << (6 + 7 * (srcIndex - 1));
|
|
20
14
|
}
|
|
21
15
|
result ^= -sign;
|
|
22
16
|
return { result: result, remaining: pSrc.slice(srcIndex + 1) };
|
package/lib/MsgUnpacker.ts
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
// src = src.value
|
|
8
|
-
let srcIndex = 0;
|
|
9
|
-
var sign = ((pSrc[srcIndex] >> 6) & 1)
|
|
4
|
+
var srcIndex = 0;
|
|
5
|
+
const sign = ((pSrc[srcIndex] >> 6) & 1)
|
|
10
6
|
|
|
11
|
-
result
|
|
12
|
-
|
|
7
|
+
var result = (pSrc[srcIndex] & 0b0011_1111)
|
|
8
|
+
while (srcIndex <= 4) {
|
|
13
9
|
|
|
14
10
|
if ((pSrc[srcIndex] & 0b1000_0000) === 0)
|
|
15
11
|
break;
|
|
16
|
-
// src = iter.next()
|
|
17
12
|
|
|
18
|
-
// src = src.value;
|
|
19
13
|
srcIndex++;
|
|
20
|
-
result |= ((pSrc[srcIndex] & 0b0111_1111)) << (6+7*
|
|
14
|
+
result |= ((pSrc[srcIndex] & 0b0111_1111)) << (6+7*(srcIndex-1))
|
|
21
15
|
|
|
22
16
|
}
|
|
23
17
|
result ^= -sign;
|
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;
|
|
@@ -390,6 +392,7 @@ var Client = /** @class */ (function (_super) {
|
|
|
390
392
|
_this.lastRecvTime = new Date().getTime();
|
|
391
393
|
}
|
|
392
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
|
|
393
396
|
unpacked.chunks.forEach(function (a) {
|
|
394
397
|
if (a.flags & 1 && (a.flags !== 15)) { // vital and not connless
|
|
395
398
|
if (a.seq === (_this.ack + 1) % (1 << 10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
|
|
@@ -427,42 +430,44 @@ var Client = /** @class */ (function (_super) {
|
|
|
427
430
|
if (snapChunks.length > 0) {
|
|
428
431
|
var part = 0;
|
|
429
432
|
var num_parts = 1;
|
|
433
|
+
if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
|
|
434
|
+
_this.PredGameTick = _this.AckGameTick + 1;
|
|
430
435
|
snapChunks.forEach(function (chunk) {
|
|
431
436
|
var unpacker = new MsgUnpacker_1.MsgUnpacker(chunk.raw.toJSON().data);
|
|
432
|
-
var
|
|
433
|
-
var
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
var part_size = 0;
|
|
452
|
-
if (chunk.msg != "SNAP_EMPTY") {
|
|
453
|
-
crc = unpacker.unpackInt(); // crc
|
|
454
|
-
part_size = unpacker.unpackInt();
|
|
455
|
-
}
|
|
456
|
-
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) {
|
|
457
456
|
_this.snaps = [];
|
|
457
|
+
_this.SnapshotParts = 0;
|
|
458
|
+
_this.currentSnapshotGameTick = GameTick;
|
|
458
459
|
}
|
|
459
|
-
chunk.raw = Buffer.from(unpacker.remaining);
|
|
460
|
-
_this.snaps.
|
|
461
|
-
|
|
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)) {
|
|
462
464
|
var mergedSnaps = Buffer.concat(_this.snaps);
|
|
463
|
-
|
|
464
|
-
_this.
|
|
465
|
+
_this.SnapshotParts = 0;
|
|
466
|
+
var snapUnpacked = _this.SnapUnpacker.unpackSnapshot(mergedSnaps.toJSON().data, DeltaTick, GameTick);
|
|
465
467
|
_this.emit("snapshot");
|
|
468
|
+
_this.AckGameTick = snapUnpacked.recvTick;
|
|
469
|
+
if (Math.abs(_this.PredGameTick - _this.AckGameTick) > 10)
|
|
470
|
+
_this.PredGameTick = _this.AckGameTick + 1;
|
|
466
471
|
_this.sendInput();
|
|
467
472
|
}
|
|
468
473
|
}
|
package/lib/client.ts
CHANGED
|
@@ -162,6 +162,9 @@ export declare interface Client {
|
|
|
162
162
|
timer: number;
|
|
163
163
|
PredGameTick: number;
|
|
164
164
|
AckGameTick: number;
|
|
165
|
+
|
|
166
|
+
SnapshotParts: number;
|
|
167
|
+
currentSnapshotGameTick: number;
|
|
165
168
|
|
|
166
169
|
movement: Movement;
|
|
167
170
|
|
|
@@ -203,6 +206,10 @@ export class Client extends EventEmitter {
|
|
|
203
206
|
this.name = nickname;
|
|
204
207
|
this.AckGameTick = 0;
|
|
205
208
|
this.PredGameTick = 0;
|
|
209
|
+
this.currentSnapshotGameTick = 0;
|
|
210
|
+
|
|
211
|
+
this.SnapshotParts = 0;
|
|
212
|
+
|
|
206
213
|
this.SnapUnpacker = new Snapshot();
|
|
207
214
|
// this.eSnapHolder = [];
|
|
208
215
|
this.requestResend = false;
|
|
@@ -516,6 +523,8 @@ export class Client extends EventEmitter {
|
|
|
516
523
|
|
|
517
524
|
|
|
518
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
|
+
|
|
519
528
|
unpacked.chunks.forEach(a => {
|
|
520
529
|
if (a.flags & 1 && (a.flags !== 15)) { // vital and not connless
|
|
521
530
|
if (a.seq === (this.ack+1)%(1<<10)) { // https://github.com/nobody-mb/twchatonly/blob/master/chatonly.cpp#L237
|
|
@@ -557,55 +566,63 @@ export class Client extends EventEmitter {
|
|
|
557
566
|
if (snapChunks.length > 0) {
|
|
558
567
|
let part = 0;
|
|
559
568
|
let num_parts = 1;
|
|
569
|
+
if (Math.abs(this.PredGameTick - this.AckGameTick) > 10)
|
|
570
|
+
this.PredGameTick = this.AckGameTick + 1;
|
|
571
|
+
|
|
560
572
|
snapChunks.forEach(chunk => {
|
|
561
573
|
let unpacker = new MsgUnpacker(chunk.raw.toJSON().data);
|
|
562
574
|
|
|
563
|
-
let
|
|
564
|
-
|
|
565
|
-
let
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
let num_parts = 1;
|
|
577
|
-
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
|
+
}
|
|
578
587
|
|
|
579
|
-
if (chunk.msg === "SNAP") {
|
|
580
|
-
num_parts = unpacker.unpackInt();
|
|
581
|
-
part = unpacker.unpackInt();
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
let crc = 0;
|
|
585
|
-
let part_size = 0;
|
|
586
588
|
if (chunk.msg != "SNAP_EMPTY") {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
}
|
|
590
|
-
if (part === 0 || this.snaps.length > 30) {
|
|
591
|
-
this.snaps = [];
|
|
589
|
+
Crc = unpacker.unpackInt();
|
|
590
|
+
PartSize = unpacker.unpackInt();
|
|
592
591
|
}
|
|
593
|
-
chunk.raw = Buffer.from(unpacker.remaining);
|
|
594
|
-
this.snaps.push(chunk.raw)
|
|
595
|
-
|
|
596
|
-
if ((num_parts - 1) === part && this.snaps.length === num_parts) {
|
|
597
592
|
|
|
598
|
-
|
|
593
|
+
if (PartSize < 1 || NumParts > 64 || Part < 0 || Part >= NumParts || PartSize <= 0 || PartSize > 900)
|
|
594
|
+
return;
|
|
599
595
|
|
|
600
|
-
|
|
601
|
-
this.
|
|
602
|
-
|
|
603
|
-
|
|
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;
|
|
604
607
|
|
|
605
|
-
this.
|
|
606
|
-
|
|
608
|
+
if (this.SnapshotParts == ((1 << NumParts) - 1)) {
|
|
609
|
+
let mergedSnaps = Buffer.concat(this.snaps);
|
|
610
|
+
this.SnapshotParts = 0;
|
|
607
611
|
|
|
608
|
-
|
|
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
|
+
|
|
609
626
|
})
|
|
610
627
|
}
|
|
611
628
|
var chunkMessages = unpacked.chunks.map(a => a.msg)
|
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))
|