yolkbot 0.1.2-alpha.2 → 0.1.2-alpha.21

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "yolkbot",
3
3
  "description": "create a shell shockers bot in under 10 lines.",
4
- "version": "0.1.2-alpha.2",
4
+ "version": "0.1.2-alpha.21",
5
5
  "keywords": [
6
6
  "shell shockers",
7
7
  "shellshock.io",
package/src/api.js CHANGED
@@ -97,7 +97,7 @@ async function loginWithCredentials(email, password, proxy = '', instance = 'she
97
97
  'x-client-version': 'Chrome/JsCore/9.17.2/FirebaseCore-web',
98
98
  'x-firebase-locale': 'en'
99
99
  },
100
- dispatcher: proxy ? new globals.ProxyAgent(proxy) : undefined
100
+ dispatcher: proxy ? new globals.ProxyAgent(proxy.replace(/socks([4|5|4a|5h]+)/g, 'https')) : undefined
101
101
  });
102
102
 
103
103
  body = await request.json();
@@ -158,7 +158,7 @@ async function loginWithRefreshToken(refreshToken, proxy = '', instance = 'shell
158
158
  'x-client-version': 'Chrome/JsCore/9.17.2/FirebaseCore-web',
159
159
  'x-firebase-locale': 'en'
160
160
  },
161
- dispatcher: proxy ? new globals.ProxyAgent(proxy) : undefined
161
+ dispatcher: proxy ? new globals.ProxyAgent(proxy.replace(/socks([4|5|4a|5h]+)/g, 'https')) : undefined
162
162
  });
163
163
 
164
164
  body = await request.json();
@@ -206,7 +206,7 @@ async function loginAnonymously(proxy = '', instance = 'shellshock.io') {
206
206
  'x-client-version': 'Chrome/JsCore/9.17.2/FirebaseCore-web',
207
207
  'x-firebase-locale': 'en'
208
208
  },
209
- dispatcher: proxy ? new globals.ProxyAgent(proxy) : undefined
209
+ dispatcher: proxy ? new globals.ProxyAgent(proxy.replace(/socks([4|5|4a|5h]+)/g, 'https')) : undefined
210
210
  });
211
211
 
212
212
  const body = await req.json();
package/src/bot.js CHANGED
@@ -43,7 +43,8 @@ const intents = {
43
43
  PING: 5,
44
44
  COSMETIC_DATA: 6,
45
45
  PLAYER_HEALTH: 7,
46
- PACKET_HOOK: 8
46
+ PACKET_HOOK: 8,
47
+ MONITOR: 9
47
48
  }
48
49
 
49
50
  export class Bot {
@@ -68,8 +69,9 @@ export class Bot {
68
69
 
69
70
  // private information NOT FOR OTHER PLAYERS!!
70
71
  this.state = {
71
- // kept for specifying socket open sequence
72
+ // kept for specifying various params
72
73
  name: '',
74
+ weaponIdx: 0,
73
75
 
74
76
  // tracking for dispatch checks
75
77
  reloading: false,
@@ -77,7 +79,10 @@ export class Bot {
77
79
  usingMelee: false,
78
80
 
79
81
  // shots fired ezzz
80
- shotsFired: 0
82
+ shotsFired: 0,
83
+
84
+ // holy glitch
85
+ quit: false
81
86
  }
82
87
 
83
88
  this.players = {}
@@ -387,104 +392,13 @@ export class Bot {
387
392
  });
388
393
  }
389
394
 
390
- async #onGameMesssage(msg) {
391
- CommIn.init(msg.data);
392
-
393
- let out;
394
- const cmd = CommIn.unPackInt8U();
395
-
396
- switch (cmd) {
397
- case CommCode.socketReady:
398
- out = CommOut.getBuffer();
399
- out.packInt8(CommCode.joinGame);
400
-
401
- out.packString(this.state.name); // name
402
- out.packString(this.game.raw.uuid); // game id
403
-
404
- out.packInt8(0); // hidebadge
405
- out.packInt8(0); // weapon choice
406
-
407
- out.packInt32(this.account.session); // session int
408
- out.packString(this.account.firebaseId); // firebase id
409
- out.packString(this.account.sessionId); // session id
410
-
411
- out.send(this.game.socket);
412
- break;
413
-
414
- case CommCode.gameJoined: {
415
- this.me.id = CommIn.unPackInt8U();
416
- // console.log("My id is:", this.me.id);
417
- this.me.team = CommIn.unPackInt8U();
418
- // console.log("My team is:", this.me.team);
419
- this.game.gameModeId = CommIn.unPackInt8U(); // aka gameType
420
- this.game.gameMode = GameModesById[this.game.gameModeId];
421
- // console.log("Gametype:", this.game.gameMode, this.game.gameModeId);
422
- this.game.mapIdx = CommIn.unPackInt8U();
423
- this.game.map = Maps[this.game.mapIdx];
424
- if (this.intents.includes(this.Intents.PATHFINDING)) {
425
- this.game.map.raw = await this.#fetchMap(this.game.map.filename, this.game.map.hash);
426
- this.pathing.nodeList = new NodeList(this.game.map.raw);
427
- if (this.game.gameModeId === GameModes.kotc) this.#initKotcZones();
428
- }
429
- // console.log("Map:", this.game.map);
430
- this.game.playerLimit = CommIn.unPackInt8U();
431
- // console.log("Player limit:", this.game.playerLimit);
432
- this.game.isGameOwner = CommIn.unPackInt8U() == 1;
433
- // console.log("Is game owner:", this.game.isGameOwner);
434
- this.game.isPrivate = CommIn.unPackInt8U() == 1;
435
- // console.log("Is private game:", this.game.isPrivate);
436
-
437
- // console.log('Successfully joined game.');
438
- this.state.joinedGame = true;
439
- this.lastDeathTime = Date.now();
440
-
441
- const out = CommOut.getBuffer();
442
- out.packInt8(CommCode.clientReady);
443
- out.send(this.game.socket);
444
-
445
- this.game.socket.onmessage = (msg) => this._packetQueue.push(msg.data);
446
-
447
- if (this.autoUpdate)
448
- this.updateIntervalId = setInterval(() => this.update(), this.updateInterval);
449
-
450
- if (this.intents.includes(this.Intents.PING)) {
451
- const out = CommOut.getBuffer();
452
- out.packInt8(CommCode.ping);
453
- out.send(this.game.socket);
454
- this.lastPingTime = Date.now();
455
- }
456
- break;
457
- }
458
-
459
- case CommCode.eventModifier:
460
- // console.log("Echoed eventModifier"); // why the fuck do you need to do this
461
- out = CommOut.getBuffer();
462
- out.packInt8(CommCode.eventModifier);
463
- out.send(this.game.socket);
464
- break;
465
-
466
- case CommCode.requestGameOptions:
467
- this.#processGameRequestOptionsPacket();
468
- break;
469
-
470
- default:
471
- try {
472
- const inferredCode = Object.entries(CommCode).filter(([, v]) => v == cmd)[0][0];
473
- console.error('onGameMessage: Received but did not handle a:', inferredCode);
474
- // packet could potentially not exist, then [0][0] will error
475
- } catch {
476
- console.error('onGameMessage: Unexpected packet received during startup: ' + cmd);
477
- }
478
- }
479
- }
480
-
481
395
  // region - a region id ('useast', 'germany', etc)
482
396
  // mode - a mode name that corresponds to a GameMode id
483
397
  // map - the name of a map
484
398
  async createPrivateGame(opts = {}) {
485
399
  if (!await this.initMatchmaker()) return false;
486
400
 
487
- if (!opts.region) { throw new Error('pass a region: createPrivateGame({ region: "useast", ... })') }
401
+ if (!opts.region) throw new Error('pass a region: createPrivateGame({ region: "useast", ... })')
488
402
  if (!this.matchmaker.regionList.find(r => r.id == opts.region))
489
403
  throw new Error('invalid region, see <bot>.matchmaker.regionList for a region list (pass an "id")')
490
404
 
@@ -571,7 +485,7 @@ export class Bot {
571
485
  this.game.socket.onerror = null;
572
486
  }
573
487
 
574
- this.game.socket.onmessage = this.#onGameMesssage.bind(this);
488
+ this.game.socket.onmessage = (msg) => this.processPacket(msg.data);
575
489
 
576
490
  this.game.socket.onclose = (e) => {
577
491
  // console.log('Game socket closed:', e.code, Object.entries(CloseCode).filter(([, v]) => v == e.code));
@@ -641,6 +555,7 @@ export class Bot {
641
555
 
642
556
  update() {
643
557
  if (!this.state.joinedGame) throw new Error('You cannot call update() if the bot is not in a game.');
558
+ if (this.state.quit) return;
644
559
 
645
560
  // process pathfinding
646
561
  if (this.pathing.followingPath && this.intents.includes(this.Intents.PATHFINDING)) this.#processPathfinding();
@@ -665,19 +580,20 @@ export class Bot {
665
580
  if (now - this.lastUpdateTime >= 50) {
666
581
  this.emit('tick');
667
582
 
668
- // Send out update packet
669
- const out = CommOut.getBuffer();
670
- out.packInt8(CommCode.syncMe);
671
- out.packInt8(Math.random() * 128 | 0); // stateIdx
672
- out.packInt8(this.me.serverStateIdx); // serverStateIdx
673
- for (let i = 0; i < 3; i++) {
674
- out.packInt8(this.controlKeys); // controlkeys
675
- out.packInt8(this.state.shotsFired); // shots fired
676
- out.packRadU(this.me.view.yaw); // yaw
677
- out.packRad(this.me.view.pitch); // pitch
678
- out.packInt8(100); // fixes commcode issues, does nothing
583
+ if (!this.intents.includes(this.Intents.MONITOR)) {
584
+ const out = CommOut.getBuffer();
585
+ out.packInt8(CommCode.syncMe);
586
+ out.packInt8(Math.random() * 128 | 0); // stateIdx
587
+ out.packInt8(this.me.serverStateIdx); // serverStateIdx
588
+ for (let i = 0; i < 3; i++) {
589
+ out.packInt8(this.controlKeys); // controlkeys
590
+ out.packInt8(this.state.shotsFired); // shots fired
591
+ out.packRadU(this.me.view.yaw); // yaw
592
+ out.packRad(this.me.view.pitch); // pitch
593
+ out.packInt8(100); // fixes commcode issues, does nothing
594
+ }
595
+ out.send(this.game.socket);
679
596
  }
680
- out.send(this.game.socket);
681
597
 
682
598
  this.lastUpdateTime = now;
683
599
  this.state.shotsFired = 0;
@@ -702,6 +618,8 @@ export class Bot {
702
618
  #mustBeInstant = ['authFail', 'banned'];
703
619
 
704
620
  emit(event, ...args) {
621
+ if (this.state.quit) return;
622
+
705
623
  if (this._hooks[event]) {
706
624
  for (const cb of this._hooks[event]) {
707
625
  if (this.#mustBeInstant.includes(event)) cb(...args);
@@ -1114,9 +1032,11 @@ export class Bot {
1114
1032
  }
1115
1033
 
1116
1034
  #processEventModifierPacket() {
1117
- const out = CommOut.getBuffer();
1118
- out.packInt8(CommCode.eventModifier);
1119
- out.send(this.game.socket);
1035
+ if (!this.intents.includes(this.Intents.MONITOR)) {
1036
+ const out = CommOut.getBuffer();
1037
+ out.packInt8(CommCode.eventModifier);
1038
+ out.send(this.game.socket);
1039
+ }
1120
1040
  }
1121
1041
 
1122
1042
  #processRemovePlayerPacket() {
@@ -1350,7 +1270,7 @@ export class Bot {
1350
1270
 
1351
1271
  this.emit('pingUpdate', oldPing, this.ping);
1352
1272
 
1353
- setTimeout(() => {
1273
+ if (!this.intents.includes(this.Intents.MONITOR)) setTimeout(() => {
1354
1274
  const out = CommOut.getBuffer();
1355
1275
  out.packInt8(CommCode.ping);
1356
1276
  out.send(this.game.socket);
@@ -1460,22 +1380,26 @@ export class Bot {
1460
1380
  }
1461
1381
 
1462
1382
  #processGameRequestOptionsPacket() {
1463
- const out = CommOut.getBuffer();
1464
- out.packInt8(CommCode.gameOptions);
1465
- out.packInt8(this.game.options.gravity * 4);
1466
- out.packInt8(this.game.options.damage * 4);
1467
- out.packInt8(this.game.options.healthRegen * 4);
1383
+ if (!this.intents.includes(this.Intents.MONITOR)) {
1384
+ const out = CommOut.getBuffer();
1385
+ out.packInt8(CommCode.gameOptions);
1386
+ out.packInt8(this.game.options.gravity * 4);
1387
+ out.packInt8(this.game.options.damage * 4);
1388
+ out.packInt8(this.game.options.healthRegen * 4);
1468
1389
 
1469
- const flags =
1470
- (this.game.options.locked ? 1 : 0) |
1471
- (this.game.options.noTeamChange ? 2 : 0) |
1472
- (this.game.options.noTeamShuffle ? 4 : 0);
1390
+ const flags =
1391
+ (this.game.options.locked ? 1 : 0) |
1392
+ (this.game.options.noTeamChange ? 2 : 0) |
1393
+ (this.game.options.noTeamShuffle ? 4 : 0);
1473
1394
 
1474
- out.packInt8(flags);
1395
+ out.packInt8(flags);
1475
1396
 
1476
- this.game.options.weaponsDisabled.forEach((v) => {
1477
- out.packInt8(v ? 1 : 0);
1478
- });
1397
+ this.game.options.weaponsDisabled.forEach((v) => {
1398
+ out.packInt8(v ? 1 : 0);
1399
+ });
1400
+
1401
+ out.send(this.game.socket);
1402
+ }
1479
1403
  }
1480
1404
 
1481
1405
  #processExplodePacket() {
@@ -1547,6 +1471,68 @@ export class Bot {
1547
1471
  }
1548
1472
  }
1549
1473
 
1474
+ #processSocketReadyPacket() {
1475
+ if (!this.intents.includes(this.Intents.MONITOR)) {
1476
+ const out = CommOut.getBuffer();
1477
+ out.packInt8(CommCode.joinGame);
1478
+
1479
+ out.packString(this.state.name);
1480
+ out.packString(this.game.raw.uuid);
1481
+
1482
+ out.packInt8(0); // hidebadge
1483
+ out.packInt8(this.state.weaponIdx || 0); // weapon idx
1484
+
1485
+ out.packInt32(this.account.session);
1486
+ out.packString(this.account.firebaseId);
1487
+ out.packString(this.account.sessionId);
1488
+
1489
+ out.send(this.game.socket);
1490
+ }
1491
+ }
1492
+
1493
+ async #processGameJoinedPacket() {
1494
+ this.me.id = CommIn.unPackInt8U();
1495
+ this.me.team = CommIn.unPackInt8U();
1496
+ this.game.gameModeId = CommIn.unPackInt8U(); // aka gameType
1497
+ this.game.gameMode = GameModesById[this.game.gameModeId];
1498
+ this.game.mapIdx = CommIn.unPackInt8U();
1499
+ this.game.map = Maps[this.game.mapIdx];
1500
+ if (this.intents.includes(this.Intents.PATHFINDING)) {
1501
+ this.game.map.raw = await this.#fetchMap(this.game.map.filename, this.game.map.hash);
1502
+ this.pathing.nodeList = new NodeList(this.game.map.raw);
1503
+ if (this.game.gameModeId === GameModes.kotc) this.#initKotcZones();
1504
+ }
1505
+ this.game.playerLimit = CommIn.unPackInt8U();
1506
+ this.game.isGameOwner = CommIn.unPackInt8U() == 1;
1507
+ this.game.isPrivate = CommIn.unPackInt8U() == 1;
1508
+
1509
+ // console.log('Successfully joined game.');
1510
+
1511
+ this.state.joinedGame = true;
1512
+ this.lastDeathTime = Date.now();
1513
+
1514
+ if (!this.intents.includes(this.Intents.MONITOR)) {
1515
+ const out = CommOut.getBuffer();
1516
+ out.packInt8(CommCode.clientReady);
1517
+ out.send(this.game.socket);
1518
+
1519
+ this.game.socket.onmessage = (msg) => this._packetQueue.push(msg.data);
1520
+ }
1521
+
1522
+ if (this.autoUpdate)
1523
+ this.updateIntervalId = setInterval(() => this.update(), this.updateInterval);
1524
+
1525
+ if (this.intents.includes(this.Intents.PING)) {
1526
+ this.lastPingTime = Date.now();
1527
+
1528
+ if (!this.intents.includes(this.Intents.MONITOR)) {
1529
+ const out = CommOut.getBuffer();
1530
+ out.packInt8(CommCode.ping);
1531
+ out.send(this.game.socket);
1532
+ }
1533
+ }
1534
+ }
1535
+
1550
1536
  processPacket(packet) {
1551
1537
  CommIn.init(packet);
1552
1538
 
@@ -1682,6 +1668,14 @@ export class Bot {
1682
1668
  this.#processChallengeCompletePacket();
1683
1669
  break;
1684
1670
 
1671
+ case CommCode.socketReady:
1672
+ this.#processSocketReadyPacket();
1673
+ break;
1674
+
1675
+ case CommCode.gameJoined:
1676
+ this.#processGameJoinedPacket();
1677
+ break;
1678
+
1685
1679
  case CommCode.gameAction:
1686
1680
  this.#processGameActionPacket();
1687
1681
  break;
@@ -1730,11 +1724,11 @@ export class Bot {
1730
1724
  if (typeof response === 'string') return response;
1731
1725
 
1732
1726
  this.account.cw.limit = response.limit;
1733
- this.account.cw.atLimit = response.limit > 3;
1727
+ this.account.cw.atLimit = response.limit >= 5;
1734
1728
 
1735
1729
  // if there is a "span", that means that it's under the daily limit and you can play again soon
1736
1730
  // if there is a "period", that means that the account is done for the day and must wait a long time
1737
- this.account.cw.secondsUntilPlay = response.span || response.period || 0;
1731
+ this.account.cw.secondsUntilPlay = (this.account.cw.atLimit ? response.period : response.span) || 0;
1738
1732
  this.account.cw.canPlayAgain = Date.now() + (this.account.cw.secondsUntilPlay * 1000);
1739
1733
 
1740
1734
  return this.account.cw;
@@ -1755,7 +1749,7 @@ export class Bot {
1755
1749
  if (typeof response === 'string') return response;
1756
1750
 
1757
1751
  if (response.error) {
1758
- if (response.error == 'RATELIMITED') {
1752
+ if (response.error == 'RATELIMITED' || response.error == 'RATELMITED') {
1759
1753
  await this.checkChiknWinner();
1760
1754
  return 'on_cooldown';
1761
1755
  } else if (response.error == 'SESSION_EXPIRED') {
@@ -1924,8 +1918,8 @@ export class Bot {
1924
1918
 
1925
1919
  clearInterval(this.updateIntervalId);
1926
1920
 
1927
- if (this.game) this.game.socket.close();
1928
- this.matchmaker.close();
1921
+ if (this.game.socket) this.game.socket.close();
1922
+ if (this.matchmaker) this.matchmaker.close();
1929
1923
 
1930
1924
  if (!finishDispatches) this._dispatches = [];
1931
1925
  this._packetQueue = [];
@@ -1936,6 +1930,8 @@ export class Bot {
1936
1930
  delete this.me;
1937
1931
  delete this.players;
1938
1932
  }
1933
+
1934
+ this.state.quit = true;
1939
1935
  }
1940
1936
  }
1941
1937
 
@@ -70,10 +70,12 @@ export class SaveLoadoutDispatch {
70
70
  }
71
71
 
72
72
  execute(bot) {
73
- if (this.changes.classIdx && this.changes.classIdx !== bot.me.selectedGun) {
73
+ if (bot.me && this.changes.classIdx && this.changes.classIdx !== bot.me.selectedGun) {
74
74
  bot.me.weapons[0] = new GunList[this.changes.classIdx]();
75
75
  }
76
76
 
77
+ bot.state.weaponIdx = this.changes.classIdx || bot.state.weaponIdx;
78
+
77
79
  const loadout = {
78
80
  ...bot.account.loadout,
79
81
  ...this.changes
@@ -89,7 +91,7 @@ export class SaveLoadoutDispatch {
89
91
 
90
92
  bot.account.loadout = loadout;
91
93
 
92
- saveLoadout.then(() => {
94
+ if (bot.me) saveLoadout.then(() => {
93
95
  if (bot.state.joinedGame) {
94
96
  const out = CommOut.getBuffer();
95
97
  out.packInt8(CommCode.changeCharacter);
package/src/matchmaker.js CHANGED
@@ -103,7 +103,7 @@ export class Matchmaker {
103
103
  this.on('msg', listener);
104
104
 
105
105
  this.ws.onerror = (e2) => {
106
- throw new Error('Failed to get regions', e2);
106
+ throw new Error('failed to get regions', e2);
107
107
  }
108
108
 
109
109
  this.ws.send(JSON.stringify({ command: 'regionList' }));
@@ -116,17 +116,15 @@ export class Matchmaker {
116
116
  // params.region
117
117
  // params.mode -> params.gameType
118
118
  // params.isPublic -> params.playType
119
- if (!params.region) { throw new Error('did not specify a region in findGame, use <Matchmaker>.getRegions() for a list') }
119
+ if (!params.region) throw new Error('did not specify a region in findGame, use <Matchmaker>.getRegions() for a list')
120
120
 
121
121
  if (this.regionList) {
122
122
  const region = this.regionList.find(r => r.id == params.region);
123
- if (!region) {
124
- throw new Error('did not find region in regionList, if you are attempting to force a region, avoid calling getRegions()')
125
- }
123
+ if (!region) throw new Error('did not find region in regionList, if you are attempting to force a region, avoid calling getRegions()')
126
124
  } // else { console.log('regionList not found, not validating findGame region, use <Matchmaker>.regionList() to check region') }
127
125
 
128
- if (!params.mode) { throw new Error('did not specify a mode in findGame') }
129
- if (GameModes[params.mode] === undefined) { throw new Error('invalid mode in findGame, see GameModes for a list') }
126
+ if (!params.mode) throw new Error('did not specify a mode in findGame')
127
+ if (GameModes[params.mode] === undefined) throw new Error('invalid mode in findGame, see GameModes for a list')
130
128
 
131
129
  return new Promise((res) => {
132
130
  const opts = {
@@ -16,6 +16,7 @@ export interface QueryResponse {
16
16
  }
17
17
 
18
18
  export function queryServices(request: QueryRequest, proxy?: string, instance?: string): Promise<QueryResponse | string>;
19
- export function loginWithCredentials(email: string, password: string, prox?: string, instance?: string): Promise<QueryResponse | string>;
20
- export function loginWithRefreshToken(refreshToken: string, prox?: string, instance?: string): Promise<QueryResponse | string>;
21
- export function loginAnonymously(prox?: string, instance?: string): Promise<QueryResponse | string>;
19
+ export function loginWithCredentials(email: string, password: string, proxy?: string, instance?: string): Promise<QueryResponse | string>;
20
+ export function loginWithRefreshToken(refreshToken: string, proxy?: string, instance?: string): Promise<QueryResponse | string>;
21
+ export function loginAnonymously(proxy?: string, instance?: string): Promise<QueryResponse | string>;
22
+ export function createAccount(email: string, password: string, proxy?: string, instance?: string): Promise<QueryResponse | string>;
@@ -66,6 +66,8 @@ export interface Account {
66
66
  firebaseId: string;
67
67
  sessionId: string;
68
68
  session: string;
69
+ email: string;
70
+ password: string;
69
71
  cw: ChiknWinnerStatus;
70
72
  loadout: {
71
73
  hatId: number | null;
@@ -170,10 +172,12 @@ export interface Pathing {
170
172
 
171
173
  export interface BotState {
172
174
  name: string;
175
+ weaponIdx: number;
173
176
  reloading: boolean;
174
177
  swappingGun: boolean;
175
178
  usingMelee: boolean;
176
179
  shotsFired: number;
180
+ quit: boolean;
177
181
  }
178
182
 
179
183
  export interface ChiknWinnerResponse {
@@ -190,7 +194,8 @@ type intents = {
190
194
  PING: 5,
191
195
  COSMETIC_DATA: 6,
192
196
  PLAYER_HEALTH: 7,
193
- PACKET_HOOK: 8
197
+ PACKET_HOOK: 8,
198
+ MONITOR: 9
194
199
  }
195
200
 
196
201
  export class Bot {
@@ -227,11 +232,12 @@ export class Bot {
227
232
  createPrivateGame(opts: { region: string; mode: string; map: string }): Promise<RawGameData>;
228
233
  join(botName: string, data: string | RawGameData): Promise<void>;
229
234
 
235
+ processPacket(data: number[]): void;
230
236
  dispatch(disp: ADispatch): void;
231
237
  update(): void;
232
238
 
233
239
  canSee(player: GamePlayer): boolean;
234
- getBestTarget(customFilter: (player: GamePlayer) => boolean): GamePlayer | undefined;
240
+ getBestTarget(customFilter?: (player: GamePlayer) => boolean): GamePlayer | undefined;
235
241
 
236
242
  onAny(cb: Function): void;
237
243