teeworlds 2.5.3 → 2.5.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/lib/snapshot.js CHANGED
@@ -1,610 +1,598 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Snapshot = exports.items = void 0;
4
- var UUIDManager_1 = require("./UUIDManager");
5
- var MsgUnpacker_1 = require("./MsgUnpacker");
6
- var decoder = new TextDecoder('utf-8');
7
- var ___itemAppendix = [
8
- { "type_id": 0, "size": 0, "name": "obj_ex" },
9
- { "type_id": 1, "size": 10, "name": "obj_player_input" },
10
- { "type_id": 2, "size": 6, "name": "obj_projectile" },
11
- { "type_id": 3, "size": 5, "name": "obj_laser" },
12
- { "type_id": 4, "size": 4, "name": "obj_pickup" },
13
- { "type_id": 5, "size": 3, "name": "obj_flag" },
14
- { "type_id": 6, "size": 8, "name": "obj_game_info" },
15
- { "type_id": 7, "size": 4, "name": "obj_game_data" },
16
- { "type_id": 8, "size": 15, "name": "obj_character_core" },
17
- { "type_id": 9, "size": 22, "name": "obj_character" },
18
- { "type_id": 10, "size": 5, "name": "obj_player_info" },
19
- { "type_id": 11, "size": 17, "name": "obj_client_info" },
20
- { "type_id": 12, "size": 3, "name": "obj_spectator_info" },
21
- { "type_id": 13, "size": 2, "name": "common" },
22
- { "type_id": 14, "size": 2, "name": "explosion" },
23
- { "type_id": 15, "size": 2, "name": "spawn" },
24
- { "type_id": 16, "size": 2, "name": "hammerhit" },
25
- { "type_id": 17, "size": 3, "name": "death" },
26
- { "type_id": 18, "size": 3, "name": "sound_global" },
27
- { "type_id": 19, "size": 3, "name": "sound_world" },
28
- { "type_id": 20, "size": 3, "name": "damage_indicator" } // event_damage_indicator
29
- ];
30
- var itemAppendix = [
31
- 0,
32
- 10,
33
- 6,
34
- 5,
35
- 4,
36
- 3,
37
- 8,
38
- 4,
39
- 15,
40
- 22,
41
- 5,
42
- 17,
43
- 3,
44
- 2,
45
- 2,
46
- 2,
47
- 2,
48
- 3,
49
- 3,
50
- 3,
51
- 3,
52
- ];
53
- var items;
54
- (function (items) {
55
- items[items["OBJ_EX"] = 0] = "OBJ_EX";
56
- items[items["OBJ_PLAYER_INPUT"] = 1] = "OBJ_PLAYER_INPUT";
57
- items[items["OBJ_PROJECTILE"] = 2] = "OBJ_PROJECTILE";
58
- items[items["OBJ_LASER"] = 3] = "OBJ_LASER";
59
- items[items["OBJ_PICKUP"] = 4] = "OBJ_PICKUP";
60
- items[items["OBJ_FLAG"] = 5] = "OBJ_FLAG";
61
- items[items["OBJ_GAME_INFO"] = 6] = "OBJ_GAME_INFO";
62
- items[items["OBJ_GAME_DATA"] = 7] = "OBJ_GAME_DATA";
63
- items[items["OBJ_CHARACTER_CORE"] = 8] = "OBJ_CHARACTER_CORE";
64
- items[items["OBJ_CHARACTER"] = 9] = "OBJ_CHARACTER";
65
- items[items["OBJ_PLAYER_INFO"] = 10] = "OBJ_PLAYER_INFO";
66
- items[items["OBJ_CLIENT_INFO"] = 11] = "OBJ_CLIENT_INFO";
67
- items[items["OBJ_SPECTATOR_INFO"] = 12] = "OBJ_SPECTATOR_INFO";
68
- items[items["EVENT_COMMON"] = 13] = "EVENT_COMMON";
69
- items[items["EVENT_EXPLOSION"] = 14] = "EVENT_EXPLOSION";
70
- items[items["EVENT_SPAWN"] = 15] = "EVENT_SPAWN";
71
- items[items["EVENT_HAMMERHIT"] = 16] = "EVENT_HAMMERHIT";
72
- items[items["EVENT_DEATH"] = 17] = "EVENT_DEATH";
73
- items[items["EVENT_SOUND_GLOBAL"] = 18] = "EVENT_SOUND_GLOBAL";
74
- items[items["EVENT_SOUND_WORLD"] = 19] = "EVENT_SOUND_WORLD";
75
- items[items["EVENT_DAMAGE_INDICATOR"] = 20] = "EVENT_DAMAGE_INDICATOR";
76
- })(items = exports.items || (exports.items = {}));
77
- // https://github.com/ddnet/ddnet/blob/571b0b36de83d18f2524ee371fc3223d04b94135/datasrc/network.py#L236
78
- var supported_uuids = [
79
- "my-own-object@heinrich5991.de",
80
- "character@netobj.ddnet.tw",
81
- "player@netobj.ddnet.tw",
82
- "gameinfo@netobj.ddnet.tw",
83
- "projectile@netobj.ddnet.tw",
84
- "laser@netobj.ddnet.tw",
85
- ];
86
- var Snapshot = /** @class */ (function () {
87
- function Snapshot(_client) {
88
- this.deltas = [];
89
- this.eSnapHolder = [];
90
- this.crc_errors = 0;
91
- this.uuid_manager = new UUIDManager_1.UUIDManager(32767, true); // snapshot max_type
92
- this.client = _client;
93
- }
94
- Snapshot.prototype.IntsToStr = function (pInts) {
95
- var pIntz = [];
96
- // var pStr = ''
97
- for (var _i = 0, pInts_1 = pInts; _i < pInts_1.length; _i++) {
98
- var x = pInts_1[_i];
99
- // pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
100
- pIntz.push((((x) >> 24) & 0xff) - 128);
101
- // pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
102
- pIntz.push((((x) >> 16) & 0xff) - 128);
103
- // pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
104
- pIntz.push((((x) >> 8) & 0xff) - 128);
105
- // pStr += String.fromCharCode(((x) & 0xff) - 128);
106
- pIntz.push(((x) & 0xff) - 128);
107
- }
108
- pIntz.splice(-1, 1);
109
- var pStr = decoder.decode(new Uint8Array(pIntz));
110
- pStr = pStr.replace(/\0.*/g, ''); // Remove content from first null char to end.
111
- return pStr;
112
- };
113
- Snapshot.prototype.parseItem = function (data, Type, id) {
114
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
115
- var _item = {};
116
- if (Type >= 0x4000) { // offset uuid type
117
- if (((_a = this.uuid_manager.LookupType(Type)) === null || _a === void 0 ? void 0 : _a.name) == "my-own-object@heinrich5991.de") {
118
- _item = {
119
- m_Test: data[0]
120
- };
121
- }
122
- else if (((_b = this.uuid_manager.LookupType(Type)) === null || _b === void 0 ? void 0 : _b.name) == "character@netobj.ddnet.tw") {
123
- _item = {
124
- m_Flags: data[0],
125
- m_FreezeEnd: data[1],
126
- m_Jumps: data[2],
127
- m_TeleCheckpoint: data[3],
128
- m_StrongWeakID: data[4],
129
- // # New data fields for jump display, freeze bar and ninja bar
130
- // # Default values indicate that these values should not be used
131
- m_JumpedTotal: (_c = data[5]) !== null && _c !== void 0 ? _c : null,
132
- m_NinjaActivationTick: (_d = data[6]) !== null && _d !== void 0 ? _d : null,
133
- m_FreezeStart: (_e = data[7]) !== null && _e !== void 0 ? _e : null,
134
- // # New data fields for improved target accuracy
135
- m_TargetX: (_f = data[8]) !== null && _f !== void 0 ? _f : null,
136
- m_TargetY: (_g = data[9]) !== null && _g !== void 0 ? _g : null,
137
- id: id
138
- };
139
- }
140
- else if (((_h = this.uuid_manager.LookupType(Type)) === null || _h === void 0 ? void 0 : _h.name) == "player@netobj.ddnet.tw") {
141
- _item = {
142
- m_Flags: data[0],
143
- m_AuthLevel: data[1],
144
- id: id
145
- };
146
- }
147
- else if (((_j = this.uuid_manager.LookupType(Type)) === null || _j === void 0 ? void 0 : _j.name) == "gameinfo@netobj.ddnet.tw") {
148
- _item = {
149
- m_Flags: data[0],
150
- m_Version: data[1],
151
- m_Flags2: data[2]
152
- };
153
- }
154
- else if (((_k = this.uuid_manager.LookupType(Type)) === null || _k === void 0 ? void 0 : _k.name) == "projectile@netobj.ddnet.tw") {
155
- _item = {
156
- m_X: data[0],
157
- m_Y: data[1],
158
- m_Angle: data[2],
159
- m_Data: data[3],
160
- m_Type: data[3],
161
- m_StartTick: data[3]
162
- };
163
- }
164
- else if (((_l = this.uuid_manager.LookupType(Type)) === null || _l === void 0 ? void 0 : _l.name) == "laser@netobj.ddnet.tw") {
165
- _item = {
166
- m_ToX: data[0],
167
- m_ToY: data[1],
168
- m_FromX: data[2],
169
- m_FromY: data[3],
170
- m_Owner: data[3],
171
- m_Type: data[3]
172
- };
173
- }
174
- return _item;
175
- }
176
- switch (Type) {
177
- case items.OBJ_EX:
178
- break;
179
- case items.OBJ_PLAYER_INPUT:
180
- _item = {
181
- direction: data[0],
182
- target_x: data[1],
183
- target_y: data[2],
184
- jump: data[3],
185
- fire: data[4],
186
- hook: data[5],
187
- player_flags: data[6],
188
- wanted_weapon: data[7],
189
- next_weapon: data[8],
190
- prev_weapon: data[9],
191
- };
192
- break;
193
- case items.OBJ_PROJECTILE:
194
- _item = {
195
- x: data[0],
196
- y: data[1],
197
- vel_x: data[2],
198
- vel_y: data[3],
199
- type_: data[4],
200
- start_tick: data[5],
201
- };
202
- break;
203
- case items.OBJ_LASER:
204
- _item = {
205
- x: data[0],
206
- y: data[1],
207
- from_x: data[2],
208
- from_y: data[3],
209
- start_tick: data[4],
210
- };
211
- break;
212
- case items.OBJ_PICKUP:
213
- _item = {
214
- x: data[0],
215
- y: data[1],
216
- type_: data[2],
217
- subtype: data[3],
218
- };
219
- break;
220
- case items.OBJ_FLAG:
221
- _item = {
222
- x: data[0],
223
- y: data[1],
224
- team: data[2],
225
- };
226
- break;
227
- case items.OBJ_GAME_INFO:
228
- _item = {
229
- game_flags: data[0],
230
- game_state_flags: data[1],
231
- round_start_tick: data[2],
232
- warmup_timer: data[3],
233
- score_limit: data[4],
234
- time_limit: data[5],
235
- round_num: data[6],
236
- round_current: data[7],
237
- };
238
- break;
239
- case items.OBJ_GAME_DATA:
240
- _item = {
241
- teamscore_red: data[0],
242
- teamscore_blue: data[1],
243
- flag_carrier_red: data[2],
244
- flag_carrier_blue: data[3],
245
- };
246
- break;
247
- case items.OBJ_CHARACTER_CORE:
248
- _item = {
249
- tick: data[0],
250
- x: data[1],
251
- y: data[2],
252
- vel_x: data[3],
253
- vel_y: data[4],
254
- angle: data[5],
255
- direction: data[6],
256
- jumped: data[7],
257
- hooked_player: data[8],
258
- hook_state: data[9],
259
- hook_tick: data[10],
260
- hook_x: data[11],
261
- hook_y: data[12],
262
- hook_dx: data[13],
263
- hook_dy: data[14],
264
- };
265
- break;
266
- case items.OBJ_CHARACTER:
267
- _item = {
268
- character_core: {
269
- tick: data[0],
270
- x: data[1],
271
- y: data[2],
272
- vel_x: data[3],
273
- vel_y: data[4],
274
- angle: data[5],
275
- direction: data[6],
276
- jumped: data[7],
277
- hooked_player: data[8],
278
- hook_state: data[9],
279
- hook_tick: data[10],
280
- hook_x: data[11],
281
- hook_y: data[12],
282
- hook_dx: data[13],
283
- hook_dy: data[14],
284
- },
285
- player_flags: data[15],
286
- health: data[16],
287
- armor: data[17],
288
- ammo_count: data[18],
289
- weapon: data[19],
290
- emote: data[20],
291
- attack_tick: data[21],
292
- client_id: id
293
- };
294
- break;
295
- case items.OBJ_PLAYER_INFO:
296
- _item = {
297
- local: data[0],
298
- client_id: data[1],
299
- team: data[2],
300
- score: data[3],
301
- latency: data[4],
302
- };
303
- break;
304
- case items.OBJ_CLIENT_INFO:
305
- _item = {
306
- name: this.IntsToStr([data[0], data[1], data[2], data[3]]),
307
- clan: this.IntsToStr([data[4], data[5], data[6]]),
308
- country: data[7],
309
- skin: this.IntsToStr([data[8], data[9], data[10], data[11], data[12], data[13]]),
310
- use_custom_color: Number(data.slice(14, 15)),
311
- color_body: Number(data.slice(15, 16)),
312
- color_feet: Number(data.slice(16, 17)),
313
- id: id
314
- };
315
- break;
316
- case items.OBJ_SPECTATOR_INFO:
317
- _item = {
318
- spectator_id: data[0],
319
- x: data[1],
320
- y: data[2],
321
- };
322
- break;
323
- case items.EVENT_COMMON:
324
- _item = {
325
- x: data[0],
326
- y: data[1],
327
- };
328
- break;
329
- case items.EVENT_EXPLOSION:
330
- _item = {
331
- common: {
332
- x: data[0],
333
- y: data[1]
334
- }
335
- };
336
- break;
337
- case items.EVENT_SPAWN:
338
- _item = {
339
- common: {
340
- x: data[0],
341
- y: data[1]
342
- }
343
- };
344
- break;
345
- case items.EVENT_HAMMERHIT:
346
- _item = {
347
- common: {
348
- x: data[0],
349
- y: data[1]
350
- }
351
- };
352
- break;
353
- case items.EVENT_DEATH:
354
- _item = {
355
- client_id: data[0],
356
- common: {
357
- x: data[1],
358
- y: data[2]
359
- }
360
- };
361
- break;
362
- case items.EVENT_SOUND_GLOBAL:
363
- _item = {
364
- common: {
365
- x: data[0],
366
- y: data[1]
367
- },
368
- sound_id: data[2]
369
- };
370
- break;
371
- case items.EVENT_SOUND_WORLD:
372
- _item = {
373
- common: {
374
- x: data[0],
375
- y: data[1]
376
- },
377
- sound_id: data[2]
378
- };
379
- break;
380
- case items.EVENT_DAMAGE_INDICATOR:
381
- _item = {
382
- angle: data[0],
383
- common: {
384
- x: data[0],
385
- y: data[1]
386
- },
387
- };
388
- break;
389
- }
390
- return _item;
391
- };
392
- Snapshot.prototype.crc = function () {
393
- var checksum = 0;
394
- // this.eSnapHolder.forEach(snap => {
395
- // if (snap.ack == tick)
396
- // snap.Snapshot.Data.forEach(el => checksum += el);
397
- // })
398
- this.deltas.forEach(function (snap) {
399
- // if (snap.ack == tick)
400
- snap.data.forEach(function (el) { return checksum += el; });
401
- });
402
- return checksum & 0xffffffff;
403
- };
404
- Snapshot.prototype.unpackSnapshot = function (snap, deltatick, recvTick, WantedCrc) {
405
- var _this = this;
406
- var unpacker = new MsgUnpacker_1.MsgUnpacker(snap);
407
- var deltaSnaps = [];
408
- if (deltatick == -1) {
409
- this.eSnapHolder = [];
410
- this.deltas = [];
411
- }
412
- else {
413
- this.eSnapHolder = this.eSnapHolder.filter(function (a) {
414
- if (a.ack == deltatick)
415
- deltaSnaps.push(a);
416
- return a.ack >= deltatick;
417
- });
418
- }
419
- if (snap.length == 0) {
420
- // empty snap, copy old one into new ack
421
- this.eSnapHolder.forEach(function (snap) {
422
- if (snap.ack == deltatick)
423
- _this.eSnapHolder.push({ Snapshot: snap.Snapshot, ack: recvTick });
424
- });
425
- return { items: [], recvTick: recvTick };
426
- }
427
- var oldDeltas = this.deltas;
428
- this.deltas = [];
429
- /* key = (((type_id) << 16) | (id))
430
- * key_to_id = ((key) & 0xffff)
431
- * key_to_type_id = ((key >> 16) & 0xffff)
432
- * https://github.com/heinrich5991/libtw2/blob/master/snapshot/src/
433
- * https://github.com/heinrich5991/libtw2/blob/master/doc/snapshot.md
434
- */
435
- var _events = [];
436
- var num_removed_items = unpacker.unpackInt();
437
- var num_item_deltas = unpacker.unpackInt();
438
- unpacker.unpackInt(); // _zero padding
439
- /*snapshot_delta:
440
- [ 4] num_removed_items
441
- [ 4] num_item_deltas
442
- [ 4] _zero
443
- [*4] removed_item_keys
444
- [ ] item_deltas
445
- */
446
- var deleted = [];
447
- for (var i = 0; i < num_removed_items; i++) {
448
- var deleted_key = unpacker.unpackInt(); // removed_item_keys
449
- deleted.push(deleted_key);
450
- }
451
- /*item_delta:
452
- [ 4] type_id
453
- [ 4] id
454
- [ 4] _size
455
- [*4] data_delta*/
456
- // 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};
457
- // let deltaSnaps = this.eSnapHolder.filter(a => a.ack === deltatick);
458
- if (deltaSnaps.length == 0 && deltatick >= 0) {
459
- return { items: [], recvTick: -1 };
460
- }
461
- var _loop_1 = function (i) {
462
- var type_id = unpacker.unpackInt();
463
- var id = unpacker.unpackInt();
464
- var key = (((type_id) << 16) | (id));
465
- var _size = void 0;
466
- if (type_id > 0 && type_id < itemAppendix.length) {
467
- _size = itemAppendix[type_id];
468
- }
469
- else
470
- _size = unpacker.unpackInt();
471
- var data = [];
472
- for (var j = 0; j < _size; j++) {
473
- // if (unpacker.remaining.length > 0) {
474
- data[j] = (unpacker.unpackInt());
475
- // } else console.log(_size, "???")
476
- }
477
- var changed = false;
478
- if (deltatick >= 0) {
479
- // let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
480
- var delta = deltaSnaps.find(function (delta) { return delta.Snapshot.Key === key; });
481
- if (delta !== undefined) {
482
- var out = UndiffItem(delta.Snapshot.Data, data);
483
- data = out;
484
- changed = true;
485
- } // else no previous, use new data
486
- }
487
- var parsed = void 0;
488
- if (type_id !== 0) {
489
- if (!changed) {
490
- var oldDelta = oldDeltas.find(function (delta) { return delta.key == key; });
491
- if (oldDelta !== undefined && compareArrays(data, oldDelta.data)) {
492
- parsed = oldDelta.parsed;
493
- }
494
- else
495
- parsed = this_1.parseItem(data, type_id, id);
496
- }
497
- else
498
- parsed = this_1.parseItem(data, type_id, id);
499
- this_1.eSnapHolder.push({ Snapshot: { Data: data, Key: key }, ack: recvTick });
500
- this_1.deltas.push({
501
- data: data,
502
- key: key,
503
- id: id,
504
- type_id: type_id,
505
- parsed: parsed
506
- });
507
- if (type_id >= items.EVENT_COMMON && type_id <= items.EVENT_DAMAGE_INDICATOR) {
508
- // this.client.SnapshotUnpacker.
509
- _events.push({ type_id: type_id, parsed: parsed });
510
- // this.client.SnapshotUnpacker.emit(___itemAppendix[type_id].name, parsed);
511
- }
512
- }
513
- else {
514
- this_1.eSnapHolder.push({ Snapshot: { Data: data, Key: key }, ack: recvTick });
515
- this_1.deltas.push({
516
- data: data,
517
- key: key,
518
- id: id,
519
- type_id: type_id,
520
- parsed: {}
521
- });
522
- var test_1 = function (int) { return [(int >> 24) & 0xff, (int >> 16) & 0xff, (int >> 8) & 0xff, (int) & 0xff]; };
523
- var test2 = function (ints) { return ints.map(function (a) { return test_1(a); }).flat(); };
524
- var targetUUID_1 = Buffer.from(test2(data));
525
- if (!this_1.uuid_manager.LookupType(id)) {
526
- supported_uuids.forEach(function (a, i) {
527
- var uuid = (0, UUIDManager_1.createTwMD5Hash)(a);
528
- if (targetUUID_1.compare(uuid) == 0) {
529
- _this.uuid_manager.RegisterName(a, id);
530
- supported_uuids.splice(i, 1);
531
- }
532
- });
533
- }
534
- }
535
- };
536
- var this_1 = this;
537
- for (var i = 0; i < num_item_deltas; i++) {
538
- _loop_1(i);
539
- }
540
- var _loop_2 = function (newSnap) {
541
- if (deleted.includes(newSnap.Snapshot.Key)) {
542
- return "continue";
543
- }
544
- 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)
545
- this_2.eSnapHolder.push({ Snapshot: { Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key }, ack: recvTick });
546
- var oldDelta = oldDeltas.find(function (delta) { return delta.key == newSnap.Snapshot.Key; });
547
- if (oldDelta !== undefined && compareArrays(newSnap.Snapshot.Data, oldDelta.data)) {
548
- this_2.deltas.push(oldDelta);
549
- }
550
- else {
551
- this_2.deltas.push({
552
- data: newSnap.Snapshot.Data,
553
- key: newSnap.Snapshot.Key,
554
- id: newSnap.Snapshot.Key & 0xffff,
555
- type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff),
556
- parsed: this_2.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff), ((newSnap.Snapshot.Key) & 0xffff))
557
- });
558
- }
559
- }
560
- };
561
- var this_2 = this;
562
- for (var _i = 0, deltaSnaps_1 = deltaSnaps; _i < deltaSnaps_1.length; _i++) {
563
- var newSnap = deltaSnaps_1[_i];
564
- _loop_2(newSnap);
565
- }
566
- var _crc = this.crc();
567
- if (_crc !== WantedCrc) {
568
- this.deltas = oldDeltas;
569
- this.crc_errors++;
570
- if (this.crc_errors > 5) {
571
- recvTick = -1;
572
- this.crc_errors = 0;
573
- this.eSnapHolder = [];
574
- this.deltas = [];
575
- }
576
- else {
577
- recvTick = deltatick;
578
- }
579
- }
580
- else if (this.crc_errors > 0)
581
- this.crc_errors--;
582
- _events.forEach(function (a) { return _this.client.SnapshotUnpacker.emit(___itemAppendix[a.type_id].name, a.parsed); });
583
- return { items: this.deltas, recvTick: recvTick };
584
- };
585
- return Snapshot;
586
- }());
587
- exports.Snapshot = Snapshot;
588
- function compareArrays(first, second) {
589
- if (first.length !== second.length)
590
- return false;
591
- for (var i = 0; i < first.length; i++) {
592
- if (first[i] !== second[i])
593
- return false;
594
- }
595
- return true;
596
- }
597
- function UndiffItem(oldItem, newItem) {
598
- var out = newItem;
599
- // if (JSON.stringify(newItem) === JSON.stringify(oldItem))
600
- // return newItem;
601
- oldItem.forEach(function (a, i) {
602
- if (a !== undefined && out[i] !== undefined) {
603
- out[i] += a;
604
- }
605
- else {
606
- out[i] = 0;
607
- }
608
- });
609
- return out;
610
- }
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Snapshot = exports.items = void 0;
4
+ const UUIDManager_1 = require("./UUIDManager");
5
+ const MsgUnpacker_1 = require("./MsgUnpacker");
6
+ var decoder = new TextDecoder('utf-8');
7
+ const ___itemAppendix = [
8
+ { "type_id": 0, "size": 0, "name": "obj_ex" },
9
+ { "type_id": 1, "size": 10, "name": "obj_player_input" },
10
+ { "type_id": 2, "size": 6, "name": "obj_projectile" },
11
+ { "type_id": 3, "size": 5, "name": "obj_laser" },
12
+ { "type_id": 4, "size": 4, "name": "obj_pickup" },
13
+ { "type_id": 5, "size": 3, "name": "obj_flag" },
14
+ { "type_id": 6, "size": 8, "name": "obj_game_info" },
15
+ { "type_id": 7, "size": 4, "name": "obj_game_data" },
16
+ { "type_id": 8, "size": 15, "name": "obj_character_core" },
17
+ { "type_id": 9, "size": 22, "name": "obj_character" },
18
+ { "type_id": 10, "size": 5, "name": "obj_player_info" },
19
+ { "type_id": 11, "size": 17, "name": "obj_client_info" },
20
+ { "type_id": 12, "size": 3, "name": "obj_spectator_info" },
21
+ { "type_id": 13, "size": 2, "name": "common" }, // event_common
22
+ { "type_id": 14, "size": 2, "name": "explosion" }, // event_explosion
23
+ { "type_id": 15, "size": 2, "name": "spawn" }, // event_spawn
24
+ { "type_id": 16, "size": 2, "name": "hammerhit" }, // event_hammerhit
25
+ { "type_id": 17, "size": 3, "name": "death" }, // event_death
26
+ { "type_id": 18, "size": 3, "name": "sound_global" }, // event_sound_global
27
+ { "type_id": 19, "size": 3, "name": "sound_world" }, // event_sound_world
28
+ { "type_id": 20, "size": 3, "name": "damage_indicator" } // event_damage_indicator
29
+ ];
30
+ const itemAppendix = [
31
+ 0,
32
+ 10,
33
+ 6,
34
+ 5,
35
+ 4,
36
+ 3,
37
+ 8,
38
+ 4,
39
+ 15,
40
+ 22,
41
+ 5,
42
+ 17,
43
+ 3,
44
+ 2,
45
+ 2,
46
+ 2,
47
+ 2,
48
+ 3,
49
+ 3,
50
+ 3,
51
+ 3,
52
+ ];
53
+ var items;
54
+ (function (items) {
55
+ items[items["OBJ_EX"] = 0] = "OBJ_EX";
56
+ items[items["OBJ_PLAYER_INPUT"] = 1] = "OBJ_PLAYER_INPUT";
57
+ items[items["OBJ_PROJECTILE"] = 2] = "OBJ_PROJECTILE";
58
+ items[items["OBJ_LASER"] = 3] = "OBJ_LASER";
59
+ items[items["OBJ_PICKUP"] = 4] = "OBJ_PICKUP";
60
+ items[items["OBJ_FLAG"] = 5] = "OBJ_FLAG";
61
+ items[items["OBJ_GAME_INFO"] = 6] = "OBJ_GAME_INFO";
62
+ items[items["OBJ_GAME_DATA"] = 7] = "OBJ_GAME_DATA";
63
+ items[items["OBJ_CHARACTER_CORE"] = 8] = "OBJ_CHARACTER_CORE";
64
+ items[items["OBJ_CHARACTER"] = 9] = "OBJ_CHARACTER";
65
+ items[items["OBJ_PLAYER_INFO"] = 10] = "OBJ_PLAYER_INFO";
66
+ items[items["OBJ_CLIENT_INFO"] = 11] = "OBJ_CLIENT_INFO";
67
+ items[items["OBJ_SPECTATOR_INFO"] = 12] = "OBJ_SPECTATOR_INFO";
68
+ items[items["EVENT_COMMON"] = 13] = "EVENT_COMMON";
69
+ items[items["EVENT_EXPLOSION"] = 14] = "EVENT_EXPLOSION";
70
+ items[items["EVENT_SPAWN"] = 15] = "EVENT_SPAWN";
71
+ items[items["EVENT_HAMMERHIT"] = 16] = "EVENT_HAMMERHIT";
72
+ items[items["EVENT_DEATH"] = 17] = "EVENT_DEATH";
73
+ items[items["EVENT_SOUND_GLOBAL"] = 18] = "EVENT_SOUND_GLOBAL";
74
+ items[items["EVENT_SOUND_WORLD"] = 19] = "EVENT_SOUND_WORLD";
75
+ items[items["EVENT_DAMAGE_INDICATOR"] = 20] = "EVENT_DAMAGE_INDICATOR";
76
+ })(items || (exports.items = items = {}));
77
+ // https://github.com/ddnet/ddnet/blob/571b0b36de83d18f2524ee371fc3223d04b94135/datasrc/network.py#L236
78
+ let supported_uuids = [
79
+ "my-own-object@heinrich5991.de",
80
+ "character@netobj.ddnet.tw", // validate_size=False
81
+ "player@netobj.ddnet.tw",
82
+ "gameinfo@netobj.ddnet.tw", // validate_size=False
83
+ "projectile@netobj.ddnet.tw",
84
+ "laser@netobj.ddnet.tw",
85
+ ];
86
+ class Snapshot {
87
+ constructor(_client) {
88
+ this.deltas = [];
89
+ this.eSnapHolder = [];
90
+ this.crc_errors = 0;
91
+ this.uuid_manager = new UUIDManager_1.UUIDManager(32767, true); // snapshot max_type
92
+ this.client = _client;
93
+ }
94
+ IntsToStr(pInts) {
95
+ var pIntz = [];
96
+ // var pStr = ''
97
+ for (let x of pInts) {
98
+ // pStr += String.fromCharCode((((x) >> 24) & 0xff) - 128);
99
+ pIntz.push((((x) >> 24) & 0xff) - 128);
100
+ // pStr += String.fromCharCode((((x) >> 16) & 0xff) - 128);
101
+ pIntz.push((((x) >> 16) & 0xff) - 128);
102
+ // pStr += String.fromCharCode((((x) >> 8) & 0xff) - 128);
103
+ pIntz.push((((x) >> 8) & 0xff) - 128);
104
+ // pStr += String.fromCharCode(((x) & 0xff) - 128);
105
+ pIntz.push(((x) & 0xff) - 128);
106
+ }
107
+ pIntz.splice(-1, 1);
108
+ let pStr = decoder.decode(new Uint8Array(pIntz));
109
+ pStr = pStr.replace(/\0.*/g, ''); // Remove content from first null char to end.
110
+ return pStr;
111
+ }
112
+ parseItem(data, Type, id) {
113
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
114
+ var _item = {};
115
+ if (Type >= 0x4000) { // offset uuid type
116
+ if (((_a = this.uuid_manager.LookupType(Type)) === null || _a === void 0 ? void 0 : _a.name) == "my-own-object@heinrich5991.de") {
117
+ _item = {
118
+ m_Test: data[0]
119
+ };
120
+ }
121
+ else if (((_b = this.uuid_manager.LookupType(Type)) === null || _b === void 0 ? void 0 : _b.name) == "character@netobj.ddnet.tw") {
122
+ _item = {
123
+ m_Flags: data[0],
124
+ m_FreezeEnd: data[1],
125
+ m_Jumps: data[2],
126
+ m_TeleCheckpoint: data[3],
127
+ m_StrongWeakID: data[4],
128
+ // # New data fields for jump display, freeze bar and ninja bar
129
+ // # Default values indicate that these values should not be used
130
+ m_JumpedTotal: (_c = data[5]) !== null && _c !== void 0 ? _c : null,
131
+ m_NinjaActivationTick: (_d = data[6]) !== null && _d !== void 0 ? _d : null,
132
+ m_FreezeStart: (_e = data[7]) !== null && _e !== void 0 ? _e : null,
133
+ // # New data fields for improved target accuracy
134
+ m_TargetX: (_f = data[8]) !== null && _f !== void 0 ? _f : null,
135
+ m_TargetY: (_g = data[9]) !== null && _g !== void 0 ? _g : null,
136
+ id: id
137
+ };
138
+ }
139
+ else if (((_h = this.uuid_manager.LookupType(Type)) === null || _h === void 0 ? void 0 : _h.name) == "player@netobj.ddnet.tw") {
140
+ _item = {
141
+ m_Flags: data[0],
142
+ m_AuthLevel: data[1],
143
+ id: id
144
+ };
145
+ }
146
+ else if (((_j = this.uuid_manager.LookupType(Type)) === null || _j === void 0 ? void 0 : _j.name) == "gameinfo@netobj.ddnet.tw") {
147
+ _item = {
148
+ m_Flags: data[0],
149
+ m_Version: data[1],
150
+ m_Flags2: data[2]
151
+ };
152
+ }
153
+ else if (((_k = this.uuid_manager.LookupType(Type)) === null || _k === void 0 ? void 0 : _k.name) == "projectile@netobj.ddnet.tw") {
154
+ _item = {
155
+ m_X: data[0],
156
+ m_Y: data[1],
157
+ m_Angle: data[2],
158
+ m_Data: data[3],
159
+ m_Type: data[3],
160
+ m_StartTick: data[3]
161
+ };
162
+ }
163
+ else if (((_l = this.uuid_manager.LookupType(Type)) === null || _l === void 0 ? void 0 : _l.name) == "laser@netobj.ddnet.tw") {
164
+ _item = {
165
+ m_ToX: data[0],
166
+ m_ToY: data[1],
167
+ m_FromX: data[2],
168
+ m_FromY: data[3],
169
+ m_Owner: data[3],
170
+ m_Type: data[3]
171
+ };
172
+ }
173
+ return _item;
174
+ }
175
+ switch (Type) {
176
+ case items.OBJ_EX:
177
+ break;
178
+ case items.OBJ_PLAYER_INPUT:
179
+ _item = {
180
+ direction: data[0],
181
+ target_x: data[1],
182
+ target_y: data[2],
183
+ jump: data[3],
184
+ fire: data[4],
185
+ hook: data[5],
186
+ player_flags: data[6],
187
+ wanted_weapon: data[7],
188
+ next_weapon: data[8],
189
+ prev_weapon: data[9],
190
+ };
191
+ break;
192
+ case items.OBJ_PROJECTILE:
193
+ _item = {
194
+ x: data[0],
195
+ y: data[1],
196
+ vel_x: data[2],
197
+ vel_y: data[3],
198
+ type_: data[4],
199
+ start_tick: data[5],
200
+ };
201
+ break;
202
+ case items.OBJ_LASER:
203
+ _item = {
204
+ x: data[0],
205
+ y: data[1],
206
+ from_x: data[2],
207
+ from_y: data[3],
208
+ start_tick: data[4],
209
+ };
210
+ break;
211
+ case items.OBJ_PICKUP:
212
+ _item = {
213
+ x: data[0],
214
+ y: data[1],
215
+ type_: data[2],
216
+ subtype: data[3],
217
+ };
218
+ break;
219
+ case items.OBJ_FLAG:
220
+ _item = {
221
+ x: data[0],
222
+ y: data[1],
223
+ team: data[2],
224
+ };
225
+ break;
226
+ case items.OBJ_GAME_INFO:
227
+ _item = {
228
+ game_flags: data[0],
229
+ game_state_flags: data[1],
230
+ round_start_tick: data[2],
231
+ warmup_timer: data[3],
232
+ score_limit: data[4],
233
+ time_limit: data[5],
234
+ round_num: data[6],
235
+ round_current: data[7],
236
+ };
237
+ break;
238
+ case items.OBJ_GAME_DATA:
239
+ _item = {
240
+ teamscore_red: data[0],
241
+ teamscore_blue: data[1],
242
+ flag_carrier_red: data[2],
243
+ flag_carrier_blue: data[3],
244
+ };
245
+ break;
246
+ case items.OBJ_CHARACTER_CORE:
247
+ _item = {
248
+ tick: data[0],
249
+ x: data[1],
250
+ y: data[2],
251
+ vel_x: data[3],
252
+ vel_y: data[4],
253
+ angle: data[5],
254
+ direction: data[6],
255
+ jumped: data[7],
256
+ hooked_player: data[8],
257
+ hook_state: data[9],
258
+ hook_tick: data[10],
259
+ hook_x: data[11],
260
+ hook_y: data[12],
261
+ hook_dx: data[13],
262
+ hook_dy: data[14],
263
+ };
264
+ break;
265
+ case items.OBJ_CHARACTER:
266
+ _item = {
267
+ character_core: {
268
+ tick: data[0],
269
+ x: data[1],
270
+ y: data[2],
271
+ vel_x: data[3],
272
+ vel_y: data[4],
273
+ angle: data[5],
274
+ direction: data[6],
275
+ jumped: data[7],
276
+ hooked_player: data[8],
277
+ hook_state: data[9],
278
+ hook_tick: data[10],
279
+ hook_x: data[11],
280
+ hook_y: data[12],
281
+ hook_dx: data[13],
282
+ hook_dy: data[14],
283
+ },
284
+ player_flags: data[15],
285
+ health: data[16],
286
+ armor: data[17],
287
+ ammo_count: data[18],
288
+ weapon: data[19],
289
+ emote: data[20],
290
+ attack_tick: data[21],
291
+ client_id: id
292
+ };
293
+ break;
294
+ case items.OBJ_PLAYER_INFO:
295
+ _item = {
296
+ local: data[0],
297
+ client_id: data[1],
298
+ team: data[2],
299
+ score: data[3],
300
+ latency: data[4],
301
+ };
302
+ break;
303
+ case items.OBJ_CLIENT_INFO:
304
+ _item = {
305
+ name: this.IntsToStr([data[0], data[1], data[2], data[3]]),
306
+ clan: this.IntsToStr([data[4], data[5], data[6]]),
307
+ country: data[7],
308
+ skin: this.IntsToStr([data[8], data[9], data[10], data[11], data[12], data[13]]),
309
+ use_custom_color: Number(data.slice(14, 15)),
310
+ color_body: Number(data.slice(15, 16)),
311
+ color_feet: Number(data.slice(16, 17)),
312
+ id: id
313
+ };
314
+ break;
315
+ case items.OBJ_SPECTATOR_INFO:
316
+ _item = {
317
+ spectator_id: data[0],
318
+ x: data[1],
319
+ y: data[2],
320
+ };
321
+ break;
322
+ case items.EVENT_COMMON:
323
+ _item = {
324
+ x: data[0],
325
+ y: data[1],
326
+ };
327
+ break;
328
+ case items.EVENT_EXPLOSION:
329
+ _item = {
330
+ common: {
331
+ x: data[0],
332
+ y: data[1]
333
+ }
334
+ };
335
+ break;
336
+ case items.EVENT_SPAWN:
337
+ _item = {
338
+ common: {
339
+ x: data[0],
340
+ y: data[1]
341
+ }
342
+ };
343
+ break;
344
+ case items.EVENT_HAMMERHIT:
345
+ _item = {
346
+ common: {
347
+ x: data[0],
348
+ y: data[1]
349
+ }
350
+ };
351
+ break;
352
+ case items.EVENT_DEATH:
353
+ _item = {
354
+ client_id: data[0],
355
+ common: {
356
+ x: data[1],
357
+ y: data[2]
358
+ }
359
+ };
360
+ break;
361
+ case items.EVENT_SOUND_GLOBAL:
362
+ _item = {
363
+ common: {
364
+ x: data[0],
365
+ y: data[1]
366
+ },
367
+ sound_id: data[2]
368
+ };
369
+ break;
370
+ case items.EVENT_SOUND_WORLD:
371
+ _item = {
372
+ common: {
373
+ x: data[0],
374
+ y: data[1]
375
+ },
376
+ sound_id: data[2]
377
+ };
378
+ break;
379
+ case items.EVENT_DAMAGE_INDICATOR:
380
+ _item = {
381
+ angle: data[0],
382
+ common: {
383
+ x: data[0],
384
+ y: data[1]
385
+ },
386
+ };
387
+ break;
388
+ }
389
+ return _item;
390
+ }
391
+ crc() {
392
+ var checksum = 0;
393
+ // this.eSnapHolder.forEach(snap => {
394
+ // if (snap.ack == tick)
395
+ // snap.Snapshot.Data.forEach(el => checksum += el);
396
+ // })
397
+ this.deltas.forEach(snap => {
398
+ // if (snap.ack == tick)
399
+ snap.data.forEach(el => checksum += el);
400
+ });
401
+ return checksum & 0xffffffff;
402
+ }
403
+ unpackSnapshot(snap, deltatick, recvTick, WantedCrc) {
404
+ let unpacker = new MsgUnpacker_1.MsgUnpacker(snap);
405
+ let deltaSnaps = [];
406
+ if (deltatick == -1) {
407
+ this.eSnapHolder = [];
408
+ this.deltas = [];
409
+ }
410
+ else {
411
+ this.eSnapHolder = this.eSnapHolder.filter(a => {
412
+ if (a.ack == deltatick)
413
+ deltaSnaps.push(a);
414
+ return a.ack >= deltatick;
415
+ });
416
+ }
417
+ if (snap.length == 0) {
418
+ // empty snap, copy old one into new ack
419
+ this.eSnapHolder.forEach(snap => {
420
+ if (snap.ack == deltatick)
421
+ this.eSnapHolder.push({ Snapshot: snap.Snapshot, ack: recvTick });
422
+ });
423
+ return { items: [], recvTick: recvTick };
424
+ }
425
+ let oldDeltas = this.deltas;
426
+ this.deltas = [];
427
+ /* key = (((type_id) << 16) | (id))
428
+ * key_to_id = ((key) & 0xffff)
429
+ * key_to_type_id = ((key >> 16) & 0xffff)
430
+ * https://github.com/heinrich5991/libtw2/blob/master/snapshot/src/
431
+ * https://github.com/heinrich5991/libtw2/blob/master/doc/snapshot.md
432
+ */
433
+ var _events = [];
434
+ let num_removed_items = unpacker.unpackInt();
435
+ let num_item_deltas = unpacker.unpackInt();
436
+ unpacker.unpackInt(); // _zero padding
437
+ /*snapshot_delta:
438
+ [ 4] num_removed_items
439
+ [ 4] num_item_deltas
440
+ [ 4] _zero
441
+ [*4] removed_item_keys
442
+ [ ] item_deltas
443
+ */
444
+ var deleted = [];
445
+ for (let i = 0; i < num_removed_items; i++) {
446
+ let deleted_key = unpacker.unpackInt(); // removed_item_keys
447
+ deleted.push(deleted_key);
448
+ }
449
+ /*item_delta:
450
+ [ 4] type_id
451
+ [ 4] id
452
+ [ 4] _size
453
+ [*4] data_delta*/
454
+ // 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};
455
+ // let deltaSnaps = this.eSnapHolder.filter(a => a.ack === deltatick);
456
+ if (deltaSnaps.length == 0 && deltatick >= 0) {
457
+ return { items: [], recvTick: -1 };
458
+ }
459
+ for (let i = 0; i < num_item_deltas; i++) {
460
+ let type_id = unpacker.unpackInt();
461
+ let id = unpacker.unpackInt();
462
+ const key = (((type_id) << 16) | (id));
463
+ let _size;
464
+ if (type_id > 0 && type_id < itemAppendix.length) {
465
+ _size = itemAppendix[type_id];
466
+ }
467
+ else
468
+ _size = unpacker.unpackInt();
469
+ let data = [];
470
+ for (let j = 0; j < _size; j++) {
471
+ // if (unpacker.remaining.length > 0) {
472
+ data[j] = (unpacker.unpackInt());
473
+ // } else console.log(_size, "???")
474
+ }
475
+ let changed = false;
476
+ if (deltatick >= 0) {
477
+ // let index = deltaSnaps.map(delta => delta.Snapshot.Key).indexOf(key)
478
+ let delta = deltaSnaps.find(delta => delta.Snapshot.Key === key);
479
+ if (delta !== undefined) {
480
+ let out = UndiffItem(delta.Snapshot.Data, data);
481
+ data = out;
482
+ changed = true;
483
+ } // else no previous, use new data
484
+ }
485
+ let parsed;
486
+ if (type_id !== 0) {
487
+ if (!changed) {
488
+ let oldDelta = oldDeltas.find(delta => delta.key == key);
489
+ if (oldDelta !== undefined && compareArrays(data, oldDelta.data)) {
490
+ parsed = oldDelta.parsed;
491
+ }
492
+ else
493
+ parsed = this.parseItem(data, type_id, id);
494
+ }
495
+ else
496
+ parsed = this.parseItem(data, type_id, id);
497
+ this.eSnapHolder.push({ Snapshot: { Data: data, Key: key }, ack: recvTick });
498
+ this.deltas.push({
499
+ data,
500
+ key,
501
+ id,
502
+ type_id,
503
+ parsed
504
+ });
505
+ if (type_id >= items.EVENT_COMMON && type_id <= items.EVENT_DAMAGE_INDICATOR) {
506
+ // this.client.SnapshotUnpacker.
507
+ _events.push({ type_id, parsed });
508
+ // this.client.SnapshotUnpacker.emit(___itemAppendix[type_id].name, parsed);
509
+ }
510
+ }
511
+ else {
512
+ this.eSnapHolder.push({ Snapshot: { Data: data, Key: key }, ack: recvTick });
513
+ this.deltas.push({
514
+ data,
515
+ key,
516
+ id,
517
+ type_id,
518
+ parsed: {}
519
+ });
520
+ let test = (int) => [(int >> 24) & 0xff, (int >> 16) & 0xff, (int >> 8) & 0xff, (int) & 0xff];
521
+ let test2 = (ints) => ints.map(a => test(a)).flat();
522
+ let targetUUID = Buffer.from(test2(data));
523
+ if (!this.uuid_manager.LookupType(id)) {
524
+ supported_uuids.forEach((a, i) => {
525
+ let uuid = (0, UUIDManager_1.createTwMD5Hash)(a);
526
+ if (targetUUID.compare(uuid) == 0) {
527
+ this.uuid_manager.RegisterName(a, id);
528
+ supported_uuids.splice(i, 1);
529
+ }
530
+ });
531
+ }
532
+ }
533
+ }
534
+ for (let newSnap of deltaSnaps) {
535
+ if (deleted.includes(newSnap.Snapshot.Key)) {
536
+ continue;
537
+ }
538
+ 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)
539
+ this.eSnapHolder.push({ Snapshot: { Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key }, ack: recvTick });
540
+ let oldDelta = oldDeltas.find(delta => delta.key == newSnap.Snapshot.Key);
541
+ if (oldDelta !== undefined && compareArrays(newSnap.Snapshot.Data, oldDelta.data)) {
542
+ this.deltas.push(oldDelta);
543
+ }
544
+ else {
545
+ this.deltas.push({
546
+ data: newSnap.Snapshot.Data,
547
+ key: newSnap.Snapshot.Key,
548
+ id: newSnap.Snapshot.Key & 0xffff,
549
+ type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff),
550
+ parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff), ((newSnap.Snapshot.Key) & 0xffff))
551
+ });
552
+ }
553
+ }
554
+ }
555
+ let _crc = this.crc();
556
+ if (_crc !== WantedCrc) {
557
+ this.deltas = oldDeltas;
558
+ this.crc_errors++;
559
+ if (this.crc_errors > 5) {
560
+ recvTick = -1;
561
+ this.crc_errors = 0;
562
+ this.eSnapHolder = [];
563
+ this.deltas = [];
564
+ }
565
+ else {
566
+ recvTick = deltatick;
567
+ }
568
+ }
569
+ else if (this.crc_errors > 0)
570
+ this.crc_errors--;
571
+ _events.forEach(a => this.client.SnapshotUnpacker.emit(___itemAppendix[a.type_id].name, a.parsed));
572
+ return { items: this.deltas, recvTick };
573
+ }
574
+ }
575
+ exports.Snapshot = Snapshot;
576
+ function compareArrays(first, second) {
577
+ if (first.length !== second.length)
578
+ return false;
579
+ for (var i = 0; i < first.length; i++) {
580
+ if (first[i] !== second[i])
581
+ return false;
582
+ }
583
+ return true;
584
+ }
585
+ function UndiffItem(oldItem, newItem) {
586
+ let out = newItem;
587
+ // if (JSON.stringify(newItem) === JSON.stringify(oldItem))
588
+ // return newItem;
589
+ oldItem.forEach((a, i) => {
590
+ if (a !== undefined && out[i] !== undefined) {
591
+ out[i] += a;
592
+ }
593
+ else {
594
+ out[i] = 0;
595
+ }
596
+ });
597
+ return out;
598
+ }