teeworlds 2.4.3 → 2.4.5
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 +0 -1
- package/index.ts +1 -2
- package/lib/MsgUnpacker.js +9 -11
- package/lib/MsgUnpacker.ts +13 -13
- package/lib/client.js +59 -108
- package/lib/client.ts +80 -133
- package/lib/components/game.js +11 -11
- package/lib/components/game.ts +33 -21
- package/lib/{movement.js → components/movement.js} +0 -0
- package/lib/{movement.ts → components/movement.ts} +0 -0
- package/lib/components/snapshot.js +200 -0
- package/lib/components/snapshot.ts +174 -0
- package/lib/snapshot.js +129 -56
- package/lib/snapshot.ts +134 -50
- package/lib/snapshots.d.ts +26 -22
- package/package.json +1 -1
- package/test.js +0 -32
package/lib/snapshot.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Snapshot = exports.items =
|
|
3
|
+
exports.Snapshot = exports.items = void 0;
|
|
4
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" },
|
|
8
8
|
{ "type_id": 1, "size": 10, "name": "obj_player_input" },
|
|
9
9
|
{ "type_id": 2, "size": 6, "name": "obj_projectile" },
|
|
@@ -17,14 +17,37 @@ exports.itemAppendix = [
|
|
|
17
17
|
{ "type_id": 10, "size": 5, "name": "obj_player_info" },
|
|
18
18
|
{ "type_id": 11, "size": 17, "name": "obj_client_info" },
|
|
19
19
|
{ "type_id": 12, "size": 3, "name": "obj_spectator_info" },
|
|
20
|
-
{ "type_id": 13, "size": 2, "name": "
|
|
21
|
-
{ "type_id": 14, "size": 2, "name": "
|
|
22
|
-
{ "type_id": 15, "size": 2, "name": "
|
|
23
|
-
{ "type_id": 16, "size": 2, "name": "
|
|
24
|
-
{ "type_id": 17, "size": 3, "name": "
|
|
25
|
-
{ "type_id": 18, "size": 3, "name": "
|
|
26
|
-
{ "type_id": 19, "size": 3, "name": "
|
|
27
|
-
{ "type_id": 20, "size": 3, "name": "
|
|
20
|
+
{ "type_id": 13, "size": 2, "name": "common" },
|
|
21
|
+
{ "type_id": 14, "size": 2, "name": "explosion" },
|
|
22
|
+
{ "type_id": 15, "size": 2, "name": "spawn" },
|
|
23
|
+
{ "type_id": 16, "size": 2, "name": "hammerhit" },
|
|
24
|
+
{ "type_id": 17, "size": 3, "name": "death" },
|
|
25
|
+
{ "type_id": 18, "size": 3, "name": "sound_global" },
|
|
26
|
+
{ "type_id": 19, "size": 3, "name": "sound_world" },
|
|
27
|
+
{ "type_id": 20, "size": 3, "name": "damage_indicator" } // event_damage_indicator
|
|
28
|
+
];
|
|
29
|
+
var itemAppendix = [
|
|
30
|
+
0,
|
|
31
|
+
10,
|
|
32
|
+
6,
|
|
33
|
+
5,
|
|
34
|
+
4,
|
|
35
|
+
3,
|
|
36
|
+
8,
|
|
37
|
+
4,
|
|
38
|
+
15,
|
|
39
|
+
22,
|
|
40
|
+
5,
|
|
41
|
+
17,
|
|
42
|
+
3,
|
|
43
|
+
2,
|
|
44
|
+
2,
|
|
45
|
+
2,
|
|
46
|
+
2,
|
|
47
|
+
3,
|
|
48
|
+
3,
|
|
49
|
+
3,
|
|
50
|
+
3,
|
|
28
51
|
];
|
|
29
52
|
var items;
|
|
30
53
|
(function (items) {
|
|
@@ -51,10 +74,11 @@ var items;
|
|
|
51
74
|
items[items["EVENT_DAMAGE_INDICATOR"] = 20] = "EVENT_DAMAGE_INDICATOR";
|
|
52
75
|
})(items = exports.items || (exports.items = {}));
|
|
53
76
|
var Snapshot = /** @class */ (function () {
|
|
54
|
-
function Snapshot() {
|
|
77
|
+
function Snapshot(_client) {
|
|
55
78
|
this.deltas = [];
|
|
56
79
|
this.eSnapHolder = [];
|
|
57
80
|
this.crc_errors = 0;
|
|
81
|
+
this.client = _client;
|
|
58
82
|
}
|
|
59
83
|
Snapshot.prototype.IntsToStr = function (pInts) {
|
|
60
84
|
var pIntz = [];
|
|
@@ -193,6 +217,7 @@ var Snapshot = /** @class */ (function () {
|
|
|
193
217
|
weapon: data[19],
|
|
194
218
|
emote: data[20],
|
|
195
219
|
attack_tick: data[21],
|
|
220
|
+
client_id: id
|
|
196
221
|
};
|
|
197
222
|
break;
|
|
198
223
|
case items.OBJ_PLAYER_INFO:
|
|
@@ -292,23 +317,32 @@ var Snapshot = /** @class */ (function () {
|
|
|
292
317
|
}
|
|
293
318
|
return _item;
|
|
294
319
|
};
|
|
295
|
-
Snapshot.prototype.crc = function (
|
|
320
|
+
Snapshot.prototype.crc = function () {
|
|
296
321
|
var checksum = 0;
|
|
297
|
-
this.eSnapHolder.forEach(
|
|
298
|
-
|
|
299
|
-
|
|
322
|
+
// this.eSnapHolder.forEach(snap => {
|
|
323
|
+
// if (snap.ack == tick)
|
|
324
|
+
// snap.Snapshot.Data.forEach(el => checksum += el);
|
|
325
|
+
// })
|
|
326
|
+
this.deltas.forEach(function (snap) {
|
|
327
|
+
// if (snap.ack == tick)
|
|
328
|
+
snap.data.forEach(function (el) { return checksum += el; });
|
|
300
329
|
});
|
|
301
330
|
return checksum & 0xffffffff;
|
|
302
331
|
};
|
|
303
332
|
Snapshot.prototype.unpackSnapshot = function (snap, deltatick, recvTick, WantedCrc) {
|
|
304
333
|
var _this = this;
|
|
305
334
|
var unpacker = new MsgUnpacker_1.MsgUnpacker(snap);
|
|
335
|
+
var deltaSnaps = [];
|
|
306
336
|
if (deltatick == -1) {
|
|
307
337
|
this.eSnapHolder = [];
|
|
308
338
|
this.deltas = [];
|
|
309
339
|
}
|
|
310
340
|
else {
|
|
311
|
-
this.eSnapHolder = this.eSnapHolder.filter(function (a) {
|
|
341
|
+
this.eSnapHolder = this.eSnapHolder.filter(function (a) {
|
|
342
|
+
if (a.ack == deltatick)
|
|
343
|
+
deltaSnaps.push(a);
|
|
344
|
+
return a.ack >= deltatick;
|
|
345
|
+
});
|
|
312
346
|
}
|
|
313
347
|
if (snap.length == 0) {
|
|
314
348
|
// empty snap, copy old one into new ack
|
|
@@ -318,12 +352,15 @@ var Snapshot = /** @class */ (function () {
|
|
|
318
352
|
});
|
|
319
353
|
return { items: [], recvTick: recvTick };
|
|
320
354
|
}
|
|
355
|
+
var oldDeltas = this.deltas;
|
|
356
|
+
this.deltas = [];
|
|
321
357
|
/* key = (((type_id) << 16) | (id))
|
|
322
358
|
* key_to_id = ((key) & 0xffff)
|
|
323
359
|
* key_to_type_id = ((key >> 16) & 0xffff)
|
|
324
360
|
* https://github.com/heinrich5991/libtw2/blob/master/snapshot/src/
|
|
325
361
|
* https://github.com/heinrich5991/libtw2/blob/master/doc/snapshot.md
|
|
326
362
|
*/
|
|
363
|
+
var _events = [];
|
|
327
364
|
var num_removed_items = unpacker.unpackInt();
|
|
328
365
|
var num_item_deltas = unpacker.unpackInt();
|
|
329
366
|
unpacker.unpackInt(); // _zero padding
|
|
@@ -335,81 +372,106 @@ var Snapshot = /** @class */ (function () {
|
|
|
335
372
|
[ ] item_deltas
|
|
336
373
|
*/
|
|
337
374
|
var deleted = [];
|
|
338
|
-
var
|
|
375
|
+
for (var i = 0; i < num_removed_items; i++) {
|
|
339
376
|
var deleted_key = unpacker.unpackInt(); // removed_item_keys
|
|
340
|
-
// let index = this.deltas.map(delta => delta.key).indexOf(deleted_key);
|
|
341
|
-
var index = this_1.deltas.findIndex(function (delta) { return delta.key === deleted_key; });
|
|
342
|
-
if (index > -1)
|
|
343
|
-
this_1.deltas.splice(index, 1);
|
|
344
377
|
deleted.push(deleted_key);
|
|
345
|
-
};
|
|
346
|
-
var this_1 = this;
|
|
347
|
-
for (var i = 0; i < num_removed_items; i++) {
|
|
348
|
-
_loop_1(i);
|
|
349
378
|
}
|
|
350
|
-
if (deleted.length)
|
|
351
|
-
this.eSnapHolder = this.eSnapHolder.filter(function (a) { return !deleted.includes(a.Snapshot.Key); });
|
|
352
379
|
/*item_delta:
|
|
353
380
|
[ 4] type_id
|
|
354
381
|
[ 4] id
|
|
355
382
|
[ 4] _size
|
|
356
383
|
[*4] data_delta*/
|
|
357
|
-
|
|
358
|
-
|
|
384
|
+
// let items: {'items': {'data': number[], '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};
|
|
385
|
+
// let deltaSnaps = this.eSnapHolder.filter(a => a.ack === deltatick);
|
|
359
386
|
if (deltaSnaps.length == 0 && deltatick >= 0) {
|
|
360
387
|
return { items: [], recvTick: -1 };
|
|
361
388
|
}
|
|
362
|
-
var
|
|
389
|
+
var _loop_1 = function (i) {
|
|
363
390
|
var type_id = unpacker.unpackInt();
|
|
364
391
|
var id = unpacker.unpackInt();
|
|
365
392
|
var key = (((type_id) << 16) | (id));
|
|
366
393
|
var _size = void 0;
|
|
367
|
-
if (type_id > 0 && type_id <
|
|
368
|
-
_size =
|
|
394
|
+
if (type_id > 0 && type_id < itemAppendix.length) {
|
|
395
|
+
_size = itemAppendix[type_id];
|
|
369
396
|
}
|
|
370
397
|
else
|
|
371
398
|
_size = unpacker.unpackInt();
|
|
372
399
|
var data = [];
|
|
373
400
|
for (var j = 0; j < _size; j++) {
|
|
374
|
-
if (unpacker.remaining.length > 0)
|
|
375
|
-
|
|
401
|
+
// if (unpacker.remaining.length > 0) {
|
|
402
|
+
data[j] = (unpacker.unpackInt());
|
|
403
|
+
// } else console.log(_size, "???")
|
|
376
404
|
}
|
|
405
|
+
var changed = false;
|
|
377
406
|
if (deltatick >= 0) {
|
|
378
407
|
// let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
|
|
379
|
-
var
|
|
380
|
-
if (
|
|
381
|
-
var out = UndiffItem(
|
|
408
|
+
var delta = deltaSnaps.find(function (delta) { return delta.Snapshot.Key === key; });
|
|
409
|
+
if (delta !== undefined) {
|
|
410
|
+
var out = UndiffItem(delta.Snapshot.Data, data);
|
|
382
411
|
data = out;
|
|
412
|
+
changed = true;
|
|
383
413
|
} // else no previous, use new data
|
|
384
414
|
}
|
|
385
|
-
var parsed =
|
|
386
|
-
|
|
387
|
-
|
|
415
|
+
var parsed = void 0;
|
|
416
|
+
if (!changed) {
|
|
417
|
+
var oldDelta = oldDeltas.find(function (delta) { return delta.key == key; });
|
|
418
|
+
if (oldDelta !== undefined && compareArrays(data, oldDelta.data)) {
|
|
419
|
+
parsed = oldDelta.parsed;
|
|
420
|
+
}
|
|
421
|
+
else
|
|
422
|
+
parsed = this_1.parseItem(data, type_id, id);
|
|
423
|
+
}
|
|
424
|
+
else
|
|
425
|
+
parsed = this_1.parseItem(data, type_id, id);
|
|
426
|
+
this_1.eSnapHolder.push({ Snapshot: { Data: data, Key: key }, ack: recvTick });
|
|
427
|
+
this_1.deltas.push({
|
|
428
|
+
data: data,
|
|
429
|
+
key: key,
|
|
430
|
+
id: id,
|
|
431
|
+
type_id: type_id,
|
|
432
|
+
parsed: parsed
|
|
433
|
+
});
|
|
434
|
+
if (type_id >= items.EVENT_COMMON && type_id <= items.EVENT_DAMAGE_INDICATOR) {
|
|
435
|
+
// this.client.SnapshotUnpacker.
|
|
436
|
+
_events.push({ type_id: type_id, parsed: parsed });
|
|
437
|
+
// this.client.SnapshotUnpacker.emit(___itemAppendix[type_id].name, parsed);
|
|
438
|
+
}
|
|
388
439
|
};
|
|
389
|
-
var
|
|
440
|
+
var this_1 = this;
|
|
390
441
|
for (var i = 0; i < num_item_deltas; i++) {
|
|
391
|
-
|
|
442
|
+
_loop_1(i);
|
|
392
443
|
}
|
|
393
|
-
var
|
|
394
|
-
if (
|
|
395
|
-
|
|
444
|
+
var _loop_2 = function (newSnap) {
|
|
445
|
+
if (deleted.includes(newSnap.Snapshot.Key)) {
|
|
446
|
+
return "continue";
|
|
396
447
|
}
|
|
397
|
-
if (
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
448
|
+
if (this_2.eSnapHolder.findIndex(function (a) { return a.ack == recvTick && a.Snapshot.Key == newSnap.Snapshot.Key; }) === -1) { // ugly copy new snap to eSnapHolder (if it isnt pushed already)
|
|
449
|
+
this_2.eSnapHolder.push({ Snapshot: { Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key }, ack: recvTick });
|
|
450
|
+
var oldDelta = oldDeltas.find(function (delta) { return delta.key == newSnap.Snapshot.Key; });
|
|
451
|
+
if (oldDelta !== undefined && compareArrays(newSnap.Snapshot.Data, oldDelta.data)) {
|
|
452
|
+
this_2.deltas.push(oldDelta);
|
|
402
453
|
}
|
|
403
|
-
|
|
404
|
-
|
|
454
|
+
else {
|
|
455
|
+
this_2.deltas.push({
|
|
456
|
+
data: newSnap.Snapshot.Data,
|
|
457
|
+
key: newSnap.Snapshot.Key,
|
|
458
|
+
id: newSnap.Snapshot.Key & 0xffff,
|
|
459
|
+
type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff),
|
|
460
|
+
parsed: this_2.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff), ((newSnap.Snapshot.Key) & 0xffff))
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}
|
|
405
464
|
};
|
|
406
|
-
var
|
|
465
|
+
var this_2 = this;
|
|
407
466
|
for (var _i = 0, deltaSnaps_1 = deltaSnaps; _i < deltaSnaps_1.length; _i++) {
|
|
408
467
|
var newSnap = deltaSnaps_1[_i];
|
|
409
|
-
|
|
468
|
+
_loop_2(newSnap);
|
|
410
469
|
}
|
|
411
|
-
|
|
470
|
+
var _crc = this.crc();
|
|
471
|
+
if (_crc !== WantedCrc) {
|
|
472
|
+
this.deltas = oldDeltas;
|
|
412
473
|
this.crc_errors++;
|
|
474
|
+
console.log("crc error", _crc, WantedCrc, this.crc_errors);
|
|
413
475
|
if (this.crc_errors > 5) {
|
|
414
476
|
recvTick = -1;
|
|
415
477
|
this.crc_errors = 0;
|
|
@@ -422,11 +484,21 @@ var Snapshot = /** @class */ (function () {
|
|
|
422
484
|
}
|
|
423
485
|
else if (this.crc_errors > 0)
|
|
424
486
|
this.crc_errors--;
|
|
425
|
-
|
|
487
|
+
_events.forEach(function (a) { return _this.client.SnapshotUnpacker.emit(___itemAppendix[a.type_id].name, a.parsed); });
|
|
488
|
+
return { items: this.deltas, recvTick: recvTick };
|
|
426
489
|
};
|
|
427
490
|
return Snapshot;
|
|
428
491
|
}());
|
|
429
492
|
exports.Snapshot = Snapshot;
|
|
493
|
+
function compareArrays(first, second) {
|
|
494
|
+
if (first.length !== second.length)
|
|
495
|
+
return false;
|
|
496
|
+
for (var i = 0; i < first.length; i++) {
|
|
497
|
+
if (first[i] !== second[i])
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
return true;
|
|
501
|
+
}
|
|
430
502
|
function UndiffItem(oldItem, newItem) {
|
|
431
503
|
var out = newItem;
|
|
432
504
|
// if (JSON.stringify(newItem) === JSON.stringify(oldItem))
|
|
@@ -436,6 +508,7 @@ function UndiffItem(oldItem, newItem) {
|
|
|
436
508
|
out[i] += a;
|
|
437
509
|
}
|
|
438
510
|
else {
|
|
511
|
+
console.log("UNDEFINED UNDEFINED UNDEFINED");
|
|
439
512
|
out[i] = 0;
|
|
440
513
|
}
|
|
441
514
|
});
|
package/lib/snapshot.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { Client } from "./client";
|
|
1
2
|
import { MsgUnpacker } from "./MsgUnpacker";
|
|
3
|
+
import { PlayerInput, PlayerInfo, Projectile, Laser, Pickup, Flag, GameInfo, GameData, CharacterCore, Character, ClientInfo, SpectatorInfo, Common, Explosion, Spawn, HammerHit, Death, SoundGlobal, SoundWorld, DamageInd } from "./snapshots";
|
|
2
4
|
var decoder = new TextDecoder('utf-8');
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
const ___itemAppendix: {"type_id": number, "size": number, "name": string}[] = [ // only used for the events underneath. the actual itemAppendix below this is only used for size
|
|
5
7
|
{"type_id": 0, "size": 0, "name": "obj_ex"},
|
|
6
8
|
{"type_id": 1, "size": 10, "name": "obj_player_input"},
|
|
7
9
|
{"type_id": 2, "size": 6, "name": "obj_projectile"},
|
|
@@ -15,14 +17,37 @@ export const itemAppendix: {"type_id": number, "size": number, "name": string}[]
|
|
|
15
17
|
{"type_id": 10, "size": 5, "name": "obj_player_info"},
|
|
16
18
|
{"type_id": 11, "size": 17, "name": "obj_client_info"},
|
|
17
19
|
{"type_id": 12, "size": 3, "name": "obj_spectator_info"},
|
|
18
|
-
{"type_id": 13, "size": 2, "name": "
|
|
19
|
-
{"type_id": 14, "size": 2, "name": "
|
|
20
|
-
{"type_id": 15, "size": 2, "name": "
|
|
21
|
-
{"type_id": 16, "size": 2, "name": "
|
|
22
|
-
{"type_id": 17, "size": 3, "name": "
|
|
23
|
-
{"type_id": 18, "size": 3, "name": "
|
|
24
|
-
{"type_id": 19, "size": 3, "name": "
|
|
25
|
-
{"type_id": 20, "size": 3, "name": "
|
|
20
|
+
{"type_id": 13, "size": 2, "name": "common"}, // event_common
|
|
21
|
+
{"type_id": 14, "size": 2, "name": "explosion"}, // event_explosion
|
|
22
|
+
{"type_id": 15, "size": 2, "name": "spawn"}, // event_spawn
|
|
23
|
+
{"type_id": 16, "size": 2, "name": "hammerhit"}, // event_hammerhit
|
|
24
|
+
{"type_id": 17, "size": 3, "name": "death"}, // event_death
|
|
25
|
+
{"type_id": 18, "size": 3, "name": "sound_global"}, // event_sound_global
|
|
26
|
+
{"type_id": 19, "size": 3, "name": "sound_world"}, // event_sound_world
|
|
27
|
+
{"type_id": 20, "size": 3, "name": "damage_indicator"} // event_damage_indicator
|
|
28
|
+
]
|
|
29
|
+
const itemAppendix: number[] = [
|
|
30
|
+
0,
|
|
31
|
+
10,
|
|
32
|
+
6,
|
|
33
|
+
5,
|
|
34
|
+
4,
|
|
35
|
+
3,
|
|
36
|
+
8,
|
|
37
|
+
4,
|
|
38
|
+
15,
|
|
39
|
+
22,
|
|
40
|
+
5,
|
|
41
|
+
17,
|
|
42
|
+
3,
|
|
43
|
+
2,
|
|
44
|
+
2,
|
|
45
|
+
2,
|
|
46
|
+
2,
|
|
47
|
+
3,
|
|
48
|
+
3,
|
|
49
|
+
3,
|
|
50
|
+
3,
|
|
26
51
|
]
|
|
27
52
|
|
|
28
53
|
export enum items {
|
|
@@ -49,7 +74,7 @@ export enum items {
|
|
|
49
74
|
EVENT_DAMAGE_INDICATOR
|
|
50
75
|
}
|
|
51
76
|
|
|
52
|
-
export type Item = PlayerInput | PlayerInfo | Projectile | Laser | Pickup | Flag | GameInfo | GameData | CharacterCore | Character | PlayerInfo | ClientInfo | SpectatorInfo | Common | Explosion | Spawn |HammerHit | Death | SoundGlobal | SoundWorld | DamageInd
|
|
77
|
+
export declare type Item = PlayerInput | PlayerInfo | Projectile | Laser | Pickup | Flag | GameInfo | GameData | CharacterCore | Character | PlayerInfo | ClientInfo | SpectatorInfo | Common | Explosion | Spawn |HammerHit | Death | SoundGlobal | SoundWorld | DamageInd;
|
|
53
78
|
interface eSnap {
|
|
54
79
|
Snapshot: {Key: number, Data: number[]},
|
|
55
80
|
ack: number,
|
|
@@ -58,7 +83,12 @@ export class Snapshot {
|
|
|
58
83
|
deltas: {'data': number[], 'parsed': Item, 'type_id': number, 'id': number, 'key': number}[] = [];
|
|
59
84
|
eSnapHolder: eSnap[] = [];
|
|
60
85
|
crc_errors: number = 0;
|
|
86
|
+
client: Client;
|
|
61
87
|
|
|
88
|
+
constructor(_client: Client) {
|
|
89
|
+
this.client = _client;
|
|
90
|
+
}
|
|
91
|
+
|
|
62
92
|
private IntsToStr(pInts: number[]): string {
|
|
63
93
|
var pIntz: number[] = [];
|
|
64
94
|
// var pStr = ''
|
|
@@ -197,6 +227,8 @@ export class Snapshot {
|
|
|
197
227
|
weapon: data[19],
|
|
198
228
|
emote: data[20],
|
|
199
229
|
attack_tick: data[21],
|
|
230
|
+
|
|
231
|
+
client_id: id
|
|
200
232
|
} as Character
|
|
201
233
|
break;
|
|
202
234
|
case items.OBJ_PLAYER_INFO:
|
|
@@ -299,40 +331,51 @@ export class Snapshot {
|
|
|
299
331
|
return _item;
|
|
300
332
|
}
|
|
301
333
|
|
|
302
|
-
crc(
|
|
334
|
+
crc() {
|
|
303
335
|
var checksum = 0;
|
|
304
|
-
this.eSnapHolder.forEach(snap => {
|
|
305
|
-
|
|
306
|
-
|
|
336
|
+
// this.eSnapHolder.forEach(snap => {
|
|
337
|
+
// if (snap.ack == tick)
|
|
338
|
+
// snap.Snapshot.Data.forEach(el => checksum += el);
|
|
339
|
+
// })
|
|
340
|
+
this.deltas.forEach(snap => {
|
|
341
|
+
// if (snap.ack == tick)
|
|
342
|
+
snap.data.forEach(el => checksum += el);
|
|
307
343
|
})
|
|
308
344
|
|
|
309
345
|
return checksum & 0xffffffff;
|
|
310
346
|
}
|
|
311
|
-
|
|
312
|
-
unpackSnapshot(snap: number[], deltatick: number, recvTick: number, WantedCrc: number) {
|
|
347
|
+
unpackSnapshot(snap: Buffer, deltatick: number, recvTick: number, WantedCrc: number) {
|
|
313
348
|
let unpacker = new MsgUnpacker(snap);
|
|
349
|
+
let deltaSnaps: eSnap[] = [];
|
|
314
350
|
if (deltatick == -1) {
|
|
315
351
|
this.eSnapHolder = [];
|
|
316
352
|
this.deltas = [];
|
|
317
353
|
} else {
|
|
318
|
-
this.eSnapHolder = this.eSnapHolder.filter(a =>
|
|
354
|
+
this.eSnapHolder = this.eSnapHolder.filter(a => {
|
|
355
|
+
if (a.ack == deltatick)
|
|
356
|
+
deltaSnaps.push(a);
|
|
357
|
+
return a.ack >= deltatick
|
|
358
|
+
})
|
|
319
359
|
}
|
|
320
360
|
if (snap.length == 0) {
|
|
321
361
|
// empty snap, copy old one into new ack
|
|
322
362
|
this.eSnapHolder.forEach(snap => {
|
|
323
|
-
if (snap.ack == deltatick)
|
|
363
|
+
if (snap.ack == deltatick)
|
|
324
364
|
this.eSnapHolder.push({Snapshot: snap.Snapshot, ack: recvTick});
|
|
325
365
|
|
|
326
366
|
})
|
|
327
367
|
return {items: [], recvTick: recvTick};
|
|
328
368
|
}
|
|
369
|
+
let oldDeltas = this.deltas;
|
|
370
|
+
this.deltas = [];
|
|
329
371
|
/* key = (((type_id) << 16) | (id))
|
|
330
372
|
* key_to_id = ((key) & 0xffff)
|
|
331
373
|
* key_to_type_id = ((key >> 16) & 0xffff)
|
|
332
374
|
* https://github.com/heinrich5991/libtw2/blob/master/snapshot/src/
|
|
333
375
|
* https://github.com/heinrich5991/libtw2/blob/master/doc/snapshot.md
|
|
334
376
|
*/
|
|
335
|
-
|
|
377
|
+
var _events: {type_id: number, parsed: Item}[] = [];
|
|
378
|
+
|
|
336
379
|
let num_removed_items = unpacker.unpackInt();
|
|
337
380
|
let num_item_deltas = unpacker.unpackInt();
|
|
338
381
|
unpacker.unpackInt(); // _zero padding
|
|
@@ -347,23 +390,17 @@ export class Snapshot {
|
|
|
347
390
|
var deleted: number[] = [];
|
|
348
391
|
for (let i = 0; i < num_removed_items; i++) {
|
|
349
392
|
let deleted_key = unpacker.unpackInt(); // removed_item_keys
|
|
350
|
-
// let index = this.deltas.map(delta => delta.key).indexOf(deleted_key);
|
|
351
|
-
let index = this.deltas.findIndex(delta => delta.key === deleted_key);
|
|
352
|
-
if (index > -1)
|
|
353
|
-
this.deltas.splice(index, 1);
|
|
354
393
|
deleted.push(deleted_key)
|
|
355
394
|
}
|
|
356
|
-
if (deleted.length)
|
|
357
|
-
this.eSnapHolder = this.eSnapHolder.filter(a => !deleted.includes(a.Snapshot.Key));
|
|
358
|
-
|
|
359
395
|
/*item_delta:
|
|
360
396
|
[ 4] type_id
|
|
361
397
|
[ 4] id
|
|
362
398
|
[ 4] _size
|
|
363
399
|
[*4] data_delta*/
|
|
364
400
|
|
|
365
|
-
let items: {'items': {'data': number[], '
|
|
366
|
-
|
|
401
|
+
// let items: {'items': {'data': number[], '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};
|
|
402
|
+
|
|
403
|
+
// let deltaSnaps = this.eSnapHolder.filter(a => a.ack === deltatick);
|
|
367
404
|
|
|
368
405
|
if (deltaSnaps.length == 0 && deltatick >= 0) {
|
|
369
406
|
return {items: [], recvTick: -1};
|
|
@@ -377,50 +414,87 @@ export class Snapshot {
|
|
|
377
414
|
|
|
378
415
|
let _size;
|
|
379
416
|
if (type_id > 0 && type_id < itemAppendix.length) {
|
|
380
|
-
_size = itemAppendix[type_id]
|
|
417
|
+
_size = itemAppendix[type_id];
|
|
381
418
|
} else
|
|
382
419
|
_size = unpacker.unpackInt();
|
|
383
420
|
|
|
384
421
|
let data: number[] = [];
|
|
385
422
|
for (let j = 0; j < _size; j++) {
|
|
386
|
-
if (unpacker.remaining.length > 0)
|
|
387
|
-
data
|
|
423
|
+
// if (unpacker.remaining.length > 0) {
|
|
424
|
+
data[j] = (unpacker.unpackInt());
|
|
425
|
+
// } else console.log(_size, "???")
|
|
388
426
|
}
|
|
427
|
+
let changed = false;
|
|
389
428
|
if (deltatick >= 0) {
|
|
390
429
|
// let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
|
|
391
|
-
let
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
let out = UndiffItem(deltaSnaps[index].Snapshot.Data, data)
|
|
430
|
+
let delta = deltaSnaps.find(delta => delta.Snapshot.Key === key);
|
|
431
|
+
if (delta !== undefined) {
|
|
432
|
+
let out = UndiffItem(delta.Snapshot.Data, data)
|
|
395
433
|
data = out;
|
|
434
|
+
changed = true;
|
|
396
435
|
} // else no previous, use new data
|
|
397
436
|
}
|
|
437
|
+
let parsed: Item;
|
|
438
|
+
if (!changed) {
|
|
439
|
+
let oldDelta = oldDeltas.find(delta => delta.key == key);
|
|
440
|
+
if (oldDelta !== undefined && compareArrays(data, oldDelta.data)) {
|
|
441
|
+
parsed = oldDelta.parsed;
|
|
398
442
|
|
|
399
|
-
|
|
443
|
+
} else
|
|
444
|
+
parsed = this.parseItem(data, type_id, id)
|
|
445
|
+
|
|
446
|
+
} else
|
|
447
|
+
parsed = this.parseItem(data, type_id, id)
|
|
448
|
+
|
|
400
449
|
this.eSnapHolder.push({Snapshot: {Data: data, Key: key}, ack: recvTick});
|
|
401
450
|
|
|
402
|
-
|
|
451
|
+
this.deltas.push({
|
|
452
|
+
data,
|
|
453
|
+
key,
|
|
454
|
+
id,
|
|
455
|
+
type_id,
|
|
456
|
+
parsed
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
if (type_id >= items.EVENT_COMMON && type_id <= items.EVENT_DAMAGE_INDICATOR) {
|
|
460
|
+
// this.client.SnapshotUnpacker.
|
|
461
|
+
|
|
462
|
+
_events.push({type_id, parsed});
|
|
463
|
+
// this.client.SnapshotUnpacker.emit(___itemAppendix[type_id].name, parsed);
|
|
464
|
+
}
|
|
403
465
|
|
|
404
466
|
|
|
405
467
|
|
|
406
468
|
}
|
|
469
|
+
|
|
407
470
|
for (let newSnap of deltaSnaps) {
|
|
471
|
+
if (deleted.includes(newSnap.Snapshot.Key)) {
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
408
474
|
if (this.eSnapHolder.findIndex(a => a.ack == recvTick && a.Snapshot.Key == newSnap.Snapshot.Key) === -1) { // ugly copy new snap to eSnapHolder (if it isnt pushed already)
|
|
409
475
|
this.eSnapHolder.push({Snapshot: {Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key}, ack: recvTick});
|
|
476
|
+
let oldDelta = oldDeltas.find(delta => delta.key == newSnap.Snapshot.Key);
|
|
477
|
+
if (oldDelta !== undefined && compareArrays(newSnap.Snapshot.Data, oldDelta.data)) {
|
|
478
|
+
this.deltas.push(oldDelta);
|
|
479
|
+
|
|
480
|
+
} else {
|
|
481
|
+
this.deltas.push({
|
|
482
|
+
data: newSnap.Snapshot.Data,
|
|
483
|
+
key: newSnap.Snapshot.Key,
|
|
484
|
+
id: newSnap.Snapshot.Key & 0xffff,
|
|
485
|
+
type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff),
|
|
486
|
+
parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff), ((newSnap.Snapshot.Key) & 0xffff))
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
}
|
|
410
490
|
}
|
|
411
|
-
if (deltatick > -1) {
|
|
412
|
-
let ____index = this.deltas.findIndex(delta => delta.key == newSnap.Snapshot.Key)
|
|
413
|
-
|
|
414
|
-
if (____index > -1) {
|
|
415
|
-
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), ((newSnap.Snapshot.Key) & 0xffff))};
|
|
416
|
-
continue;
|
|
417
|
-
}
|
|
418
|
-
} // else
|
|
419
|
-
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), ((newSnap.Snapshot.Key) & 0xffff))});
|
|
420
491
|
}
|
|
421
|
-
|
|
422
|
-
|
|
492
|
+
|
|
493
|
+
let _crc = this.crc();
|
|
494
|
+
if (_crc !== WantedCrc) {
|
|
495
|
+
this.deltas = oldDeltas;
|
|
423
496
|
this.crc_errors++;
|
|
497
|
+
console.log("crc error", _crc, WantedCrc, this.crc_errors)
|
|
424
498
|
if (this.crc_errors > 5) {
|
|
425
499
|
recvTick = -1;
|
|
426
500
|
this.crc_errors = 0;
|
|
@@ -432,9 +506,18 @@ export class Snapshot {
|
|
|
432
506
|
}
|
|
433
507
|
} else if (this.crc_errors > 0)
|
|
434
508
|
this.crc_errors--;
|
|
435
|
-
|
|
436
|
-
return {items, recvTick};
|
|
509
|
+
_events.forEach(a => this.client.SnapshotUnpacker.emit(___itemAppendix[a.type_id].name, a.parsed))
|
|
510
|
+
return {items: this.deltas, recvTick};
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function compareArrays(first: number[], second: number[]) {
|
|
514
|
+
if (first.length !== second.length)
|
|
515
|
+
return false;
|
|
516
|
+
for (var i = 0; i < first.length; i++) {
|
|
517
|
+
if (first[i] !== second[i])
|
|
518
|
+
return false;
|
|
437
519
|
}
|
|
520
|
+
return true;
|
|
438
521
|
}
|
|
439
522
|
|
|
440
523
|
function UndiffItem(oldItem: number[], newItem: number[]): number[] {
|
|
@@ -445,6 +528,7 @@ function UndiffItem(oldItem: number[], newItem: number[]): number[] {
|
|
|
445
528
|
if (a !== undefined && out[i] !== undefined) {
|
|
446
529
|
out[i] += a;
|
|
447
530
|
} else {
|
|
531
|
+
console.log("UNDEFINED UNDEFINED UNDEFINED")
|
|
448
532
|
out[i] = 0;
|
|
449
533
|
}
|
|
450
534
|
})
|