teeworlds 2.4.4 → 2.4.7

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.ts CHANGED
@@ -1,29 +1,32 @@
1
+ import { UUIDManager, createTwMD5Hash } from "./UUIDManager";
2
+ import { Client } from "./client";
1
3
  import { MsgUnpacker } from "./MsgUnpacker";
4
+ import { PlayerInput, PlayerInfo, Projectile, Laser, Pickup, Flag, GameInfo, GameData, CharacterCore, Character, ClientInfo, SpectatorInfo, Common, Explosion, Spawn, HammerHit, Death, SoundGlobal, SoundWorld, DamageInd, MyOwnObject, DDNetCharacter, DDNetPlayer, GameInfoEx, DDNetProjectile, DDNetLaser } from "./snapshots";
2
5
  var decoder = new TextDecoder('utf-8');
3
6
 
4
- // export const itemAppendix: {"type_id": number, "size": number, "name": string}[] = [
5
- // {"type_id": 0, "size": 0, "name": "obj_ex"},
6
- // {"type_id": 1, "size": 10, "name": "obj_player_input"},
7
- // {"type_id": 2, "size": 6, "name": "obj_projectile"},
8
- // {"type_id": 3, "size": 5, "name": "obj_laser"},
9
- // {"type_id": 4, "size": 4, "name": "obj_pickup"},
10
- // {"type_id": 5, "size": 3, "name": "obj_flag"},
11
- // {"type_id": 6, "size": 8, "name": "obj_game_info"},
12
- // {"type_id": 7, "size": 4, "name": "obj_game_data"},
13
- // {"type_id": 8, "size": 15, "name": "obj_character_core"},
14
- // {"type_id": 9, "size": 22, "name": "obj_character"},
15
- // {"type_id": 10, "size": 5, "name": "obj_player_info"},
16
- // {"type_id": 11, "size": 17, "name": "obj_client_info"},
17
- // {"type_id": 12, "size": 3, "name": "obj_spectator_info"},
18
- // {"type_id": 13, "size": 2, "name": "event_common"},
19
- // {"type_id": 14, "size": 2, "name": "event_explosion"},
20
- // {"type_id": 15, "size": 2, "name": "event_spawn"},
21
- // {"type_id": 16, "size": 2, "name": "event_hammerhit"},
22
- // {"type_id": 17, "size": 3, "name": "event_death"},
23
- // {"type_id": 18, "size": 3, "name": "event_sound_global"},
24
- // {"type_id": 19, "size": 3, "name": "event_sound_world"},
25
- // {"type_id": 20, "size": 3, "name": "event_damage_indicator"}
26
- // ]
7
+ 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
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
+ ]
27
30
  const itemAppendix: number[] = [
28
31
  0,
29
32
  10,
@@ -72,16 +75,34 @@ export enum items {
72
75
  EVENT_DAMAGE_INDICATOR
73
76
  }
74
77
 
75
- export type Item = PlayerInput | PlayerInfo | Projectile | Laser | Pickup | Flag | GameInfo | GameData | CharacterCore | Character | PlayerInfo | ClientInfo | SpectatorInfo | Common | Explosion | Spawn |HammerHit | Death | SoundGlobal | SoundWorld | DamageInd | DdnetCharacter;
78
+ 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;
79
+ export declare type DDNetItem = MyOwnObject | DDNetCharacter | DDNetPlayer | GameInfoEx | DDNetProjectile | DDNetLaser;
76
80
  interface eSnap {
77
81
  Snapshot: {Key: number, Data: number[]},
78
82
  ack: number,
79
83
  }
84
+
85
+ // https://github.com/ddnet/ddnet/blob/571b0b36de83d18f2524ee371fc3223d04b94135/datasrc/network.py#L236
86
+ let supported_uuids = [
87
+ "my-own-object@heinrich5991.de",
88
+ "character@netobj.ddnet.tw", // validate_size=False
89
+ "player@netobj.ddnet.tw",
90
+ "gameinfo@netobj.ddnet.tw", // validate_size=False
91
+ "projectile@netobj.ddnet.tw",
92
+ "laser@netobj.ddnet.tw",
93
+ ]
94
+
80
95
  export class Snapshot {
81
- deltas: {'data': number[], 'parsed': Item, 'type_id': number, 'id': number, 'key': number}[] = [];
96
+ deltas: {'data': number[], 'parsed': Item | DDNetItem, 'type_id': number, 'id': number, 'key': number}[] = [];
82
97
  eSnapHolder: eSnap[] = [];
83
98
  crc_errors: number = 0;
99
+ client: Client;
100
+ uuid_manager: UUIDManager = new UUIDManager(32767, true); // snapshot max_type
84
101
 
102
+ constructor(_client: Client) {
103
+ this.client = _client;
104
+ }
105
+
85
106
  private IntsToStr(pInts: number[]): string {
86
107
  var pIntz: number[] = [];
87
108
  // var pStr = ''
@@ -101,8 +122,69 @@ export class Snapshot {
101
122
  pStr = pStr.replace(/\0.*/g, ''); // Remove content from first null char to end.
102
123
  return pStr;
103
124
  }
104
- private parseItem(data: number[], Type: number, id: number): Item {
105
- var _item = {} as Item;
125
+ private parseItem(data: number[], Type: number, id: number): Item | DDNetItem {
126
+ var _item = {} as Item | DDNetItem;
127
+ if (Type >= 0x4000) { // offset uuid type
128
+ if (this.uuid_manager.LookupType(Type)?.name == "my-own-object@heinrich5991.de") {
129
+ _item = {
130
+ m_Test: data[0]
131
+ } as MyOwnObject;
132
+ } else if (this.uuid_manager.LookupType(Type)?.name == "character@netobj.ddnet.tw") {
133
+ _item = {
134
+ m_Flags: data[0],
135
+ m_FreezeEnd: data[1],
136
+ m_Jumps: data[2],
137
+ m_TeleCheckpoint: data[3],
138
+ m_StrongWeakID: data[4],
139
+
140
+ // # New data fields for jump display, freeze bar and ninja bar
141
+ // # Default values indicate that these values should not be used
142
+ m_JumpedTotal: data[5] ?? null,
143
+ m_NinjaActivationTick: data[6] ?? null,
144
+ m_FreezeStart: data[7] ?? null,
145
+ // # New data fields for improved target accuracy
146
+ m_TargetX: data[8] ?? null,
147
+ m_TargetY: data[9] ?? null,
148
+ id: id
149
+
150
+ } as DDNetCharacter;
151
+ }
152
+ else if (this.uuid_manager.LookupType(Type)?.name == "player@netobj.ddnet.tw") {
153
+ _item = {
154
+ m_Flags: data[0],
155
+ m_AuthLevel: data[1],
156
+ id: id
157
+ } as DDNetPlayer
158
+ }
159
+ else if (this.uuid_manager.LookupType(Type)?.name == "gameinfo@netobj.ddnet.tw") {
160
+ _item = {
161
+ m_Flags: data[0],
162
+ m_Version: data[1],
163
+ m_Flags2: data[2]
164
+ } as GameInfoEx
165
+ }
166
+ else if (this.uuid_manager.LookupType(Type)?.name == "projectile@netobj.ddnet.tw") {
167
+ _item = {
168
+ m_X: data[0],
169
+ m_Y: data[1],
170
+ m_Angle: data[2],
171
+ m_Data: data[3],
172
+ m_Type: data[3],
173
+ m_StartTick: data[3]
174
+ } as DDNetProjectile
175
+ }
176
+ else if (this.uuid_manager.LookupType(Type)?.name == "laser@netobj.ddnet.tw") {
177
+ _item = {
178
+ m_ToX: data[0],
179
+ m_ToY: data[1],
180
+ m_FromX: data[2],
181
+ m_FromY: data[3],
182
+ m_Owner: data[3],
183
+ m_Type: data[3]
184
+ } as DDNetLaser
185
+ }
186
+ return _item;
187
+ }
106
188
  switch (Type) {
107
189
  case items.OBJ_EX:
108
190
  break;
@@ -220,6 +302,8 @@ export class Snapshot {
220
302
  weapon: data[19],
221
303
  emote: data[20],
222
304
  attack_tick: data[21],
305
+
306
+ client_id: id
223
307
  } as Character
224
308
  break;
225
309
  case items.OBJ_PLAYER_INFO:
@@ -347,10 +431,6 @@ export class Snapshot {
347
431
  deltaSnaps.push(a);
348
432
  return a.ack >= deltatick
349
433
  })
350
- // if (deltatick != -1 && this.eSnapHolder.length == 0) {
351
- // console.log("no deltatick stored")
352
- // return {items: [], recvTick: -1}
353
- // }
354
434
  }
355
435
  if (snap.length == 0) {
356
436
  // empty snap, copy old one into new ack
@@ -369,7 +449,8 @@ export class Snapshot {
369
449
  * https://github.com/heinrich5991/libtw2/blob/master/snapshot/src/
370
450
  * https://github.com/heinrich5991/libtw2/blob/master/doc/snapshot.md
371
451
  */
372
-
452
+ var _events: {type_id: number, parsed: Item | DDNetItem}[] = [];
453
+
373
454
  let num_removed_items = unpacker.unpackInt();
374
455
  let num_item_deltas = unpacker.unpackInt();
375
456
  unpacker.unpackInt(); // _zero padding
@@ -384,11 +465,6 @@ export class Snapshot {
384
465
  var deleted: number[] = [];
385
466
  for (let i = 0; i < num_removed_items; i++) {
386
467
  let deleted_key = unpacker.unpackInt(); // removed_item_keys
387
- // let index = this.deltas.map(delta => delta.key).indexOf(deleted_key);
388
- // let index = this.deltas.findIndex(delta => delta.key === deleted_key);
389
- // if (index > -1)
390
- // this.deltas.splice(index, 1);
391
- // console.log(deleted_key)
392
468
  deleted.push(deleted_key)
393
469
  }
394
470
  /*item_delta:
@@ -433,67 +509,70 @@ export class Snapshot {
433
509
  changed = true;
434
510
  } // else no previous, use new data
435
511
  }
436
- let parsed: Item;
437
- if (!changed) {
438
- let oldDelta = oldDeltas.find(delta => delta.key == key);
439
- if (oldDelta !== undefined && compareArrays(data, oldDelta.data)) {
440
- parsed = oldDelta.parsed;
441
-
512
+ let parsed: Item | DDNetItem;
513
+ if (type_id !== 0) {
514
+ if (!changed) {
515
+ let oldDelta = oldDeltas.find(delta => delta.key == key);
516
+ if (oldDelta !== undefined && compareArrays(data, oldDelta.data)) {
517
+ parsed = oldDelta.parsed;
518
+
519
+ } else
520
+ parsed = this.parseItem(data, type_id, id)
521
+
442
522
  } else
443
523
  parsed = this.parseItem(data, type_id, id)
444
524
 
445
- } else
446
- parsed = this.parseItem(data, type_id, id)
447
-
448
- this.eSnapHolder.push({Snapshot: {Data: data, Key: key}, ack: recvTick});
449
-
450
- // items.items.push({data, type_id, id, key})
451
-
452
- this.deltas.push({
453
- data,
454
- key,
455
- id,
456
- type_id,
457
- parsed
458
- });
459
-
460
-
525
+ this.eSnapHolder.push({Snapshot: {Data: data, Key: key}, ack: recvTick});
526
+
527
+ this.deltas.push({
528
+ data,
529
+ key,
530
+ id,
531
+ type_id,
532
+ parsed
533
+ });
534
+ if (type_id >= items.EVENT_COMMON && type_id <= items.EVENT_DAMAGE_INDICATOR) {
535
+ // this.client.SnapshotUnpacker.
536
+
537
+ _events.push({type_id, parsed});
538
+ // this.client.SnapshotUnpacker.emit(___itemAppendix[type_id].name, parsed);
539
+ }
540
+ } else {
461
541
 
542
+ this.eSnapHolder.push({Snapshot: {Data: data, Key: key}, ack: recvTick});
543
+
544
+ this.deltas.push({
545
+ data,
546
+ key,
547
+ id,
548
+ type_id,
549
+ parsed: {} as Item
550
+ });
462
551
 
552
+ let test = (int: number) => [(int >> 24) & 0xff, (int >> 16) & 0xff, (int >> 8) & 0xff, (int) & 0xff ];
553
+ let test2 = (ints: number[]) => ints.map(a => test(a)).flat();
554
+
555
+ let targetUUID = Buffer.from(test2(data));
556
+ if (!this.uuid_manager.LookupType(id)) {
557
+
558
+ supported_uuids.forEach((a, i) => {
559
+ let uuid = createTwMD5Hash(a);
560
+ if (targetUUID.compare(uuid) == 0) {
561
+ this.uuid_manager.RegisterName(a, id);
562
+ supported_uuids.splice(i, 1);
563
+ }
564
+ })
565
+ }
566
+ }
463
567
  }
464
- // if (deleted.length) {
465
- // let _beforeLength = this.eSnapHolder.length;
466
- // this.eSnapHolder = this.eSnapHolder.filter(snap => !deleted.includes(snap.Snapshot.Key));
467
- // let _beforeLength = this.eSnapHolder.length;
468
- // if ((_beforeLength - this.eSnapHolder.length) !== num_removed_items) {
469
- // console.log("remove!", (_beforeLength - this.eSnapHolder.length) == num_removed_items, (_beforeLength - this.eSnapHolder.length), num_removed_items, WantedCrc)
470
-
471
- // }
472
- // }
568
+
473
569
 
474
570
  for (let newSnap of deltaSnaps) {
475
571
  if (deleted.includes(newSnap.Snapshot.Key)) {
476
- // if ()
477
- // this.deltas = this.deltas.filter(a => !deleted.includes(a.key))
478
572
  continue;
479
573
  }
480
574
  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)
481
575
  this.eSnapHolder.push({Snapshot: {Data: newSnap.Snapshot.Data, Key: newSnap.Snapshot.Key}, ack: recvTick});
482
- // this.deltas.push({})
483
- // if (deltatick > -1) {
484
- // let ____index = this.deltas.findIndex(delta => delta.key == newSnap.Snapshot.Key)
485
-
486
- // if (____index > -1) {
487
- // this.deltas[____index] = {
488
- // data: newSnap.Snapshot.Data,
489
- // key: newSnap.Snapshot.Key,
490
- // id: newSnap.Snapshot.Key & 0xffff,
491
- // type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff),
492
- // parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff), ((newSnap.Snapshot.Key) & 0xffff))
493
- // };
494
- // continue;
495
- // }
496
- // // }
497
576
  let oldDelta = oldDeltas.find(delta => delta.key == newSnap.Snapshot.Key);
498
577
  if (oldDelta !== undefined && compareArrays(newSnap.Snapshot.Data, oldDelta.data)) {
499
578
  this.deltas.push(oldDelta);
@@ -510,24 +589,11 @@ export class Snapshot {
510
589
  }
511
590
  }
512
591
  }
513
- // if (items.items.length != num_item_deltas)
514
- // console.log("length", items.items.length, num_item_deltas, items.items.length - num_item_deltas, WantedCrc)
515
- /* this.deltas = [];
516
- for (let newSnap of this.eSnapHolder) {
517
- if (newSnap.ack == recvTick)
518
- this.deltas.push({
519
- data: newSnap.Snapshot.Data,
520
- key: newSnap.Snapshot.Key,
521
- id: newSnap.Snapshot.Key & 0xffff,
522
- type_id: ((newSnap.Snapshot.Key >> 16) & 0xffff),
523
- parsed: this.parseItem(newSnap.Snapshot.Data, ((newSnap.Snapshot.Key >> 16) & 0xffff), ((newSnap.Snapshot.Key) & 0xffff))
524
- });
525
- }*/
592
+
526
593
  let _crc = this.crc();
527
594
  if (_crc !== WantedCrc) {
528
595
  this.deltas = oldDeltas;
529
596
  this.crc_errors++;
530
- console.log("crc error", _crc, WantedCrc, this.crc_errors)
531
597
  if (this.crc_errors > 5) {
532
598
  recvTick = -1;
533
599
  this.crc_errors = 0;
@@ -539,12 +605,7 @@ export class Snapshot {
539
605
  }
540
606
  } else if (this.crc_errors > 0)
541
607
  this.crc_errors--;
542
- // let filterLength = this.eSnapHolder.filter(a => a.ack == recvTick).length
543
- // if (this.deltas.length !== filterLength) {
544
- // this.deltas = this.deltas.filter(a => !deleted.includes(a.key))
545
- // console.log(this.deltas.length, filterLength, this.deltas.length - filterLength, num_item_deltas )
546
- // }
547
-
608
+ _events.forEach(a => this.client.SnapshotUnpacker.emit(___itemAppendix[a.type_id].name, a.parsed))
548
609
  return {items: this.deltas, recvTick};
549
610
  }
550
611
  }
@@ -566,7 +627,6 @@ function UndiffItem(oldItem: number[], newItem: number[]): number[] {
566
627
  if (a !== undefined && out[i] !== undefined) {
567
628
  out[i] += a;
568
629
  } else {
569
- console.log("UNDEFINED UNDEFINED UNDEFINED")
570
630
  out[i] = 0;
571
631
  }
572
632
  })
@@ -1,4 +1,4 @@
1
- declare interface PlayerInput {
1
+ export declare interface PlayerInput {
2
2
  direction: number,
3
3
  target_x: number,
4
4
  target_y: number,
@@ -11,7 +11,7 @@ declare interface PlayerInput {
11
11
  prev_weapon: number,
12
12
  }
13
13
 
14
- declare interface Projectile {
14
+ export declare interface Projectile {
15
15
  x: number,
16
16
  y: number,
17
17
  vel_x: number,
@@ -20,7 +20,7 @@ declare interface Projectile {
20
20
  start_tick: number,
21
21
  }
22
22
 
23
- declare interface Laser {
23
+ export declare interface Laser {
24
24
  x: number,
25
25
  y: number,
26
26
  from_x: number,
@@ -28,20 +28,20 @@ declare interface Laser {
28
28
  start_tick: number,
29
29
  }
30
30
 
31
- declare interface Pickup {
31
+ export declare interface Pickup {
32
32
  x: number,
33
33
  y: number,
34
34
  type_: number,
35
35
  subtype: number,
36
36
  }
37
37
 
38
- declare interface Flag {
38
+ export declare interface Flag {
39
39
  x: number,
40
40
  y: number,
41
41
  team: number,
42
42
  }
43
43
 
44
- declare interface GameInfo {
44
+ export declare interface GameInfo {
45
45
  game_flags: number,
46
46
  game_state_flags: number,
47
47
  round_start_tick: number,
@@ -52,14 +52,14 @@ declare interface GameInfo {
52
52
  round_current: number,
53
53
  }
54
54
 
55
- declare interface GameData {
55
+ export declare interface GameData {
56
56
  teamscore_red: number,
57
57
  teamscore_blue: number,
58
58
  flag_carrier_red: number,
59
59
  flag_carrier_blue: number,
60
60
  }
61
61
 
62
- declare interface CharacterCore {
62
+ export declare interface CharacterCore {
63
63
  tick: number,
64
64
  x: number,
65
65
  y: number,
@@ -77,7 +77,7 @@ declare interface CharacterCore {
77
77
  hook_dy: number,
78
78
  }
79
79
 
80
- declare interface Character {
80
+ export declare interface Character {
81
81
  character_core: CharacterCore,
82
82
  player_flags: number,
83
83
  health: number,
@@ -86,9 +86,11 @@ declare interface Character {
86
86
  weapon: number,
87
87
  emote: number,
88
88
  attack_tick: number,
89
+
90
+ client_id: number
89
91
  }
90
92
 
91
- declare interface PlayerInfo {
93
+ export declare interface PlayerInfo {
92
94
  local: number,
93
95
  client_id: number,
94
96
  team: number,
@@ -96,7 +98,7 @@ declare interface PlayerInfo {
96
98
  latency: number,
97
99
  }
98
100
 
99
- declare interface ClientInfo {
101
+ export declare interface ClientInfo {
100
102
  name: string,
101
103
  clan: string,
102
104
  country: number,
@@ -104,59 +106,53 @@ declare interface ClientInfo {
104
106
  use_custom_color: number,
105
107
  color_body: number,
106
108
  color_feet: number,
107
- }
108
109
 
109
- declare interface DdnetCharacter {
110
- flags: number,
111
- freeze_end: number,
112
- jumps: number,
113
- tele_checkpoint: number,
114
- strong_weak_id: number,
110
+ id: number
115
111
  }
116
112
 
117
- declare interface SpectatorInfo {
113
+ export declare interface SpectatorInfo {
118
114
  spectator_id: number,
119
115
  x: number,
120
116
  y: number,
121
117
  }
122
118
 
123
- declare interface Common {
119
+ export declare interface Common {
124
120
  x: number,
125
121
  y: number,
126
122
  }
127
123
 
128
- declare interface Explosion {
124
+ export declare interface Explosion {
129
125
  common: Common,
130
126
  }
131
127
 
132
- declare interface Spawn {
128
+ export declare interface Spawn {
133
129
  common: Common,
134
130
  }
135
131
 
136
- declare interface HammerHit {
132
+ export declare interface HammerHit {
137
133
  common: Common,
138
134
  }
139
135
 
140
- declare interface Death {
136
+ export declare interface Death {
141
137
  common: Common,
142
138
  client_id: number,
143
139
  }
144
140
 
145
- declare interface SoundGlobal {
141
+ export declare interface SoundGlobal {
146
142
  common: Common,
147
143
  sound_id: number,
148
144
  }
149
145
 
150
- declare interface SoundWorld {
146
+ export declare interface SoundWorld {
151
147
  common: Common,
152
148
  sound_id: number,
153
149
  }
154
150
 
155
- declare interface DamageInd {
151
+ export declare interface DamageInd {
156
152
  common: Common,
157
153
  angle: number,
158
154
  }
159
- declare enum items {
155
+ export declare enum items {
160
156
  OBJ_EX,
161
157
  OBJ_PLAYER_INPUT,
162
158
  OBJ_PROJECTILE,
@@ -178,4 +174,60 @@ declare enum items {
178
174
  EVENT_SOUND_GLOBAL,
179
175
  EVENT_SOUND_WORLD,
180
176
  EVENT_DAMAGE_INDICATOR
181
- }
177
+ }
178
+
179
+ export declare interface MyOwnObject {
180
+ m_Test: number
181
+ }
182
+
183
+ export declare interface DDNetCharacter {
184
+ m_Flags: number,
185
+ m_FreezeEnd: number,
186
+ m_Jumps: number,
187
+ m_TeleCheckpoint: number,
188
+ m_StrongWeakID: number,
189
+
190
+ // # New data fields for jump display, freeze bar and ninja bar
191
+ // # Default values indicate that these values should not be used
192
+ m_JumpedTotal?: number,
193
+ m_NinjaActivationTick?: number,
194
+ m_FreezeStart?: number,
195
+ // # New data fields for improved target accuracy
196
+ m_TargetX?: number,
197
+ m_TargetY?: number,
198
+ id: number
199
+ } //, validate_size=False),
200
+ /** m_AuthLevel "AUTHED_NO", "AUTHED_ADMIN" */
201
+ export declare interface DDNetPlayer {
202
+ m_Flags: number,
203
+ m_AuthLevel: number,
204
+ id: number
205
+ }
206
+
207
+ export declare interface GameInfoEx {
208
+
209
+ m_Flags: number,
210
+ m_Version: number,
211
+ m_Flags2: number,
212
+ }//, validate_size=False),
213
+
214
+ // # The code assumes that this has the same in-memory representation as
215
+ // # the Projectile net object.
216
+ export declare interface DDNetProjectile {
217
+ m_X: number,
218
+ m_Y: number,
219
+ m_Angle: number,
220
+ m_Data: number,
221
+ m_Type: number,
222
+ m_StartTick: number,
223
+ }
224
+
225
+ export declare interface DDNetLaser {
226
+ m_ToX: number,
227
+ m_ToY: number,
228
+ m_FromX: number,
229
+ m_FromY: number,
230
+ m_StartTick: number,
231
+ m_Owner: number,
232
+ m_Type: number,
233
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teeworlds",
3
- "version": "2.4.4",
3
+ "version": "2.4.7",
4
4
  "description": "Library for (ingame) teeworlds bots.",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
package/test.js ADDED
@@ -0,0 +1,57 @@
1
+ let crypto = require('crypto');
2
+ let list = {
3
+ "WHAT_IS": Buffer.from([0x24, 0x5e, 0x50, 0x97, 0x9f, 0xe0, 0x39, 0xd6, 0xbf, 0x7d, 0x9a, 0x29, 0xe1, 0x69, 0x1e, 0x4c]),
4
+ "IT_IS": Buffer.from([0x69, 0x54, 0x84, 0x7e, 0x2e, 0x87, 0x36, 0x03, 0xb5, 0x62, 0x36, 0xda, 0x29, 0xed, 0x1a, 0xca]),
5
+ "I_DONT_KNOW": Buffer.from([0x41, 0x69, 0x11, 0xb5, 0x79, 0x73, 0x33, 0xbf, 0x8d, 0x52, 0x7b, 0xf0, 0x1e, 0x51, 0x9c, 0xf0]),
6
+ "RCON_TYPE": Buffer.from([0x12, 0x81, 0x0e, 0x1f, 0xa1, 0xdb, 0x33, 0x78, 0xb4, 0xfb, 0x16, 0x4e, 0xd6, 0x50, 0x59, 0x26]),
7
+ "MAP_DETAILS": Buffer.from([0xf9, 0x11, 0x7b, 0x3c, 0x80, 0x39, 0x34, 0x16, 0x9f, 0xc0, 0xae, 0xf2, 0xbc, 0xb7, 0x5c, 0x03]),
8
+ "CAPABILITIES": Buffer.from([0xf6, 0x21, 0xa5, 0xa1, 0xf5, 0x85, 0x37, 0x75, 0x8e, 0x73, 0x41, 0xbe, 0xee, 0x79, 0xf2, 0xb2]),
9
+ "CLIENT_VERSION": Buffer.from([0x8c, 0x00, 0x13, 0x04, 0x84, 0x61, 0x3e, 0x47, 0x87, 0x87, 0xf6, 0x72, 0xb3, 0x83, 0x5b, 0xd4]),
10
+ // "PING_EX": Buffer.from([]),
11
+ // "PONG_EX": Buffer.from([]),
12
+ // "CHECKSUM_REQUEST": Buffer.from([]),
13
+ // "CHECKSUM_RESPONSE": Buffer.from([]),
14
+ // "CHECKSUM_ERROR": Buffer.from([])
15
+ }
16
+ let newList = {
17
+ "what_is": ("what-is@ddnet.tw"),
18
+ "it_is": ("it-is@ddnet.tw"),
19
+ "i_dont_know": ("i-dont-know@ddnet.tw"),
20
+ "rcon_type": ("rcon-type@ddnet.tw"),
21
+ "map_details": ("map-details@ddnet.tw"),
22
+ "capabilities": ("capabilities@ddnet.tw"),
23
+ "client_version": ("clientver@ddnet.tw"),
24
+ "ping": ("ping@ddnet.tw"),
25
+ "pong": ("pong@ddnet.tw"),
26
+ "checksum_request": ("checksum-request@ddnet.tw"),
27
+ "checksum_response": ("checksum-response@ddnet.tw"),
28
+ "checksum_error": ("checksum-error@ddnet.tw")
29
+ }
30
+
31
+ const createTwMD5Hash = (name) => { // https://github.com/ddnet/ddnet/blob/6d9284adc1e0be4b5348447d857eae575e06e654/src/engine/shared/uuid_manager.cpp#L26
32
+ let hash = crypto.createHash("md5")
33
+ .update(Buffer.from([0xe0, 0x5d, 0xda, 0xaa, 0xc4, 0xe6, 0x4c, 0xfb, 0xb6, 0x42, 0x5d, 0x48, 0xe8, 0x0c, 0x00, 0x29]))
34
+ .update(name)
35
+ .digest()
36
+ hash[6] &= 0x0f;
37
+ hash[6] |= 0x30;
38
+ hash[8] &= 0x3f;
39
+ hash[8] |= 0x80;
40
+ return hash;
41
+ }
42
+
43
+ Object.keys(newList).forEach(name => {
44
+ let el = newList[name];
45
+ let el_old = list[name.toUpperCase()];
46
+ if (el_old == undefined)
47
+ return;
48
+ // let hash = crypto.createHash("md5")
49
+ // .update(Buffer.from([0xe0, 0x5d, 0xda, 0xaa, 0xc4, 0xe6, 0x4c, 0xfb, 0xb6, 0x42, 0x5d, 0x48, 0xe8, 0x0c, 0x00, 0x29]))
50
+ // .update(name).digest()
51
+
52
+ let hash = createTwMD5Hash(el);
53
+ console.log(hash.compare(el_old), name)
54
+ if (hash.compare(el_old) !== 0)
55
+ console.log(name, hash, el_old)
56
+ // it_is <Buffer 69 54 84 7e 2e 87 c6 03 75 62 36 da 29 ed 1a ca> <Buffer 69 54 84 7e 2e 87 36 03 b5 62 36 da 29 ed 1a ca>
57
+ });