yolkbot 0.1.0-alpha.5 → 0.1.0-alpha.50
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/build/browser.js +6 -6
- package/package.json +27 -8
- package/src/api.js +44 -23
- package/src/bot/GamePlayer.js +3 -3
- package/src/bot.js +758 -391
- package/src/constants/index.js +23 -1
- package/src/constants/items.js +372 -173
- package/src/constants/maps.js +51 -12
- package/src/dispatches/BootPlayerDispatch.js +1 -1
- package/src/dispatches/ChatDispatch.js +1 -1
- package/src/dispatches/GameOptionsDispatch.js +1 -1
- package/src/dispatches/GoToAmmoDispatch.js +44 -0
- package/src/dispatches/GoToCoopDispatch.js +44 -0
- package/src/dispatches/GoToGrenadeDispatch.js +44 -0
- package/src/dispatches/GoToPlayerDispatch.js +5 -1
- package/src/dispatches/GoToSpatulaDispatch.js +5 -1
- package/src/dispatches/MeleeDispatch.js +1 -1
- package/src/dispatches/PauseDispatch.js +1 -1
- package/src/dispatches/ReloadDispatch.js +1 -1
- package/src/dispatches/ReportPlayerDispatch.js +1 -1
- package/src/dispatches/SaveLoadoutDispatch.js +11 -34
- package/src/dispatches/SpawnDispatch.js +1 -1
- package/src/dispatches/SwapWeaponDispatch.js +1 -1
- package/src/dispatches/SwitchTeamDispatch.js +1 -1
- package/src/dispatches/ThrowGrenadeDispatch.js +1 -1
- package/src/dispatches/index.js +14 -2
- package/src/matchmaker.js +11 -2
- package/src/pathing/mapnode.js +33 -4
- package/src/socket.js +1 -1
- package/src/types/api.d.ts +1 -16
- package/src/types/bot/GamePlayer.d.ts +87 -0
- package/src/types/bot.d.ts +117 -35
- package/src/types/constants/guns.d.ts +240 -0
- package/src/types/constants/index.d.ts +100 -0
- package/src/types/constants/items.d.ts +21 -0
- package/src/types/constants/maps.d.ts +15 -0
- package/src/types/dispatches/BootPlayerDispatch.d.ts +12 -0
- package/src/types/dispatches/ChatDispatch.d.ts +10 -0
- package/src/types/dispatches/FireDispatch.d.ts +10 -0
- package/src/types/dispatches/GameOptionsDispatch.d.ts +8 -0
- package/src/types/dispatches/GoToAmmoDispatch.d.ts +8 -0
- package/src/types/dispatches/GoToCoopDispatch.d.ts +8 -0
- package/src/types/dispatches/GoToGrenadeDispatch.d.ts +8 -0
- package/src/types/dispatches/GoToPlayerDispatch.d.ts +11 -0
- package/src/types/dispatches/GoToSpatulaDispatch.d.ts +8 -0
- package/src/types/dispatches/LookAtDispatch.d.ts +14 -0
- package/src/types/dispatches/LookAtPosDispatch.d.ts +19 -0
- package/src/types/dispatches/MeleeDispatch.d.ts +8 -0
- package/src/types/dispatches/MovementDispatch.d.ts +12 -0
- package/src/types/dispatches/PauseDispatch.d.ts +8 -0
- package/src/types/dispatches/ReloadDispatch.d.ts +8 -0
- package/src/types/dispatches/ReportPlayerDispatch.d.ts +22 -0
- package/src/types/dispatches/SaveLoadoutDispatch.d.ts +34 -0
- package/src/types/dispatches/SpawnDispatch.d.ts +8 -0
- package/src/types/dispatches/SwapWeaponDispatch.d.ts +8 -0
- package/src/types/dispatches/SwitchTeamDispatch.d.ts +8 -0
- package/src/types/dispatches/ThrowGrenadeDispatch.d.ts +10 -0
- package/src/types/dispatches/index.d.ts +174 -0
- package/src/types/matchmaker.d.ts +19 -14
- package/src/types/socket.d.ts +7 -0
package/src/bot.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loginAnonymously, loginWithCredentials } from '#api';
|
|
1
|
+
import { createAccount, loginAnonymously, loginWithCredentials, queryServices } from '#api';
|
|
2
2
|
|
|
3
3
|
import CommIn from './comm/CommIn.js';
|
|
4
4
|
import CommOut from './comm/CommOut.js';
|
|
@@ -9,6 +9,7 @@ import Matchmaker from './matchmaker.js';
|
|
|
9
9
|
import yolkws from './socket.js';
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
|
+
ChiknWinnerDailyLimit,
|
|
12
13
|
CollectTypes,
|
|
13
14
|
CoopStates,
|
|
14
15
|
findItemById,
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
GameOptionFlags,
|
|
18
19
|
GunList,
|
|
19
20
|
IsBrowser,
|
|
21
|
+
ItemTypes,
|
|
20
22
|
Movements,
|
|
21
23
|
PlayTypes,
|
|
22
24
|
ShellStreaks
|
|
@@ -32,30 +34,30 @@ import { Maps } from './constants/maps.js';
|
|
|
32
34
|
const CoopStagesById = Object.fromEntries(Object.entries(CoopStates).map(([key, value]) => [value, key]));
|
|
33
35
|
const GameModesById = Object.fromEntries(Object.entries(GameModes).map(([key, value]) => [value, key]));
|
|
34
36
|
|
|
37
|
+
const intents = {
|
|
38
|
+
CHALLENGES: 1,
|
|
39
|
+
STATS: 2,
|
|
40
|
+
PATHFINDING: 3,
|
|
41
|
+
BUFFERS: 4,
|
|
42
|
+
PING: 5,
|
|
43
|
+
COSMETIC_DATA: 6
|
|
44
|
+
}
|
|
45
|
+
|
|
35
46
|
export class Bot {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// params.updateInterval - the auto update interval
|
|
40
|
-
// params.doPing - whether to auto ping (for bot.<ping>)
|
|
41
|
-
// params.pingInterval - the ping interval
|
|
42
|
-
// params.doPathing - whether to run pathfinding logic
|
|
43
|
-
// params.instance - a custom shell URL to run requests through
|
|
47
|
+
static Intents = intents;
|
|
48
|
+
Intents = intents;
|
|
49
|
+
|
|
44
50
|
constructor(params = {}) {
|
|
45
51
|
if (params.proxy && IsBrowser)
|
|
46
52
|
throw new Error('proxies do not work and hence are not supported in the browser');
|
|
47
53
|
|
|
54
|
+
this.intents = params.intents || [];
|
|
55
|
+
|
|
56
|
+
this.instance = params.instance || 'shellshock.io';
|
|
48
57
|
this.proxy = params.proxy || '';
|
|
49
|
-
this.name = params.name || Math.random().toString(36).substring(8);
|
|
50
58
|
|
|
51
|
-
this.autoPing = params.doPing || true;
|
|
52
59
|
this.autoUpdate = params.doUpdate || true;
|
|
53
|
-
this.
|
|
54
|
-
|
|
55
|
-
this.pingInterval = params.pingInterval || 1000;
|
|
56
|
-
this.updateInterval = params.updateInterval || 5;
|
|
57
|
-
|
|
58
|
-
this.instance = params.instance || 'shellshock.io';
|
|
60
|
+
this.updateInterval = params.updateInterval || 11;
|
|
59
61
|
|
|
60
62
|
this._hooks = {};
|
|
61
63
|
this._globalHooks = [];
|
|
@@ -63,10 +65,10 @@ export class Bot {
|
|
|
63
65
|
|
|
64
66
|
// private information NOT FOR OTHER PLAYERS!!
|
|
65
67
|
this.state = {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
// kept for specifying socket open sequence
|
|
69
|
+
name: '',
|
|
68
70
|
|
|
69
|
-
//
|
|
71
|
+
// tracking for dispatch checks
|
|
70
72
|
reloading: false,
|
|
71
73
|
swappingGun: false,
|
|
72
74
|
usingMelee: false,
|
|
@@ -81,6 +83,7 @@ export class Bot {
|
|
|
81
83
|
this.game = {
|
|
82
84
|
raw: {}, // matchmaker response
|
|
83
85
|
code: '',
|
|
86
|
+
socket: null,
|
|
84
87
|
|
|
85
88
|
// data given on sign in
|
|
86
89
|
gameModeId: 0, // assume ffa
|
|
@@ -98,8 +101,10 @@ export class Bot {
|
|
|
98
101
|
},
|
|
99
102
|
availability: 'both',
|
|
100
103
|
numPlayers: '18',
|
|
104
|
+
|
|
101
105
|
raw: {},
|
|
102
|
-
nodes: {}
|
|
106
|
+
nodes: {},
|
|
107
|
+
zones: []
|
|
103
108
|
},
|
|
104
109
|
playerLimit: 0,
|
|
105
110
|
isGameOwner: false,
|
|
@@ -135,7 +140,8 @@ export class Bot {
|
|
|
135
140
|
|
|
136
141
|
// data from kotc
|
|
137
142
|
stage: CoopStates.capturing,
|
|
138
|
-
|
|
143
|
+
zoneNumber: 0,
|
|
144
|
+
activeZone: [],
|
|
139
145
|
capturing: 0,
|
|
140
146
|
captureProgress: 0,
|
|
141
147
|
numCapturing: 0,
|
|
@@ -145,10 +151,23 @@ export class Bot {
|
|
|
145
151
|
|
|
146
152
|
this.account = {
|
|
147
153
|
// used for auth
|
|
154
|
+
id: 0,
|
|
148
155
|
firebaseId: '',
|
|
149
156
|
sessionId: '',
|
|
150
157
|
session: '',
|
|
151
158
|
|
|
159
|
+
// raw login params
|
|
160
|
+
email: '',
|
|
161
|
+
password: '',
|
|
162
|
+
|
|
163
|
+
// chikn winner related info
|
|
164
|
+
cw: {
|
|
165
|
+
atLimit: false,
|
|
166
|
+
limit: 0,
|
|
167
|
+
secondsUntilPlay: 0, // short cooldown, in seconds
|
|
168
|
+
canPlayAgain: Date.now()
|
|
169
|
+
},
|
|
170
|
+
|
|
152
171
|
// used for skin changing
|
|
153
172
|
loadout: {
|
|
154
173
|
hatId: null,
|
|
@@ -184,21 +203,17 @@ export class Bot {
|
|
|
184
203
|
this._dispatches = [];
|
|
185
204
|
this._packetQueue = [];
|
|
186
205
|
|
|
187
|
-
this.
|
|
206
|
+
this.matchmaker = null;
|
|
188
207
|
|
|
189
208
|
this.ping = 0;
|
|
190
209
|
this.lastPingTime = -1;
|
|
191
210
|
|
|
192
211
|
this.lastDeathTime = -1;
|
|
193
212
|
this.lastChatTime = -1;
|
|
194
|
-
|
|
195
213
|
this.lastUpdateTime = -1;
|
|
196
|
-
this.nUpdates = 0;
|
|
197
214
|
|
|
198
215
|
this.controlKeys = 0;
|
|
199
216
|
|
|
200
|
-
this.initTime = Date.now();
|
|
201
|
-
|
|
202
217
|
this.pathing = {
|
|
203
218
|
nodeList: null,
|
|
204
219
|
followingPath: false,
|
|
@@ -208,47 +223,11 @@ export class Bot {
|
|
|
208
223
|
}
|
|
209
224
|
}
|
|
210
225
|
|
|
211
|
-
async login(email, pass) {
|
|
212
|
-
// const time = Date.now();
|
|
213
|
-
|
|
214
|
-
this.email = email;
|
|
215
|
-
this.pass = pass;
|
|
216
|
-
|
|
217
|
-
const loginData = await loginWithCredentials(email, pass, this.proxy, this.instance);
|
|
218
|
-
|
|
219
|
-
if (typeof loginData == 'string') {
|
|
220
|
-
this.#emit('authFail', loginData);
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (loginData.banRemaining) {
|
|
225
|
-
this.#emit('banned', loginData.banRemaining);
|
|
226
|
-
return false;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
this.state.loggedIn = true;
|
|
230
|
-
|
|
231
|
-
this.account.rawLoginData = loginData;
|
|
232
|
-
|
|
233
|
-
this.account.accountAge = loginData.accountAge;
|
|
234
|
-
this.account.eggBalance = loginData.currentBalance;
|
|
235
|
-
this.account.emailVerified = loginData.emailVerified;
|
|
236
|
-
this.account.firebaseId = loginData.firebaseId;
|
|
237
|
-
this.account.loadout = loginData.loadout;
|
|
238
|
-
this.account.ownedItemIds = loginData.ownedItemIds;
|
|
239
|
-
this.account.sessionId = loginData.sessionId;
|
|
240
|
-
this.account.vip = loginData.upgradeProductId && !loginData.upgradeIsExpired;
|
|
241
|
-
|
|
242
|
-
// console.log('Logged in successfully. Time:', Date.now() - time, 'ms');
|
|
243
|
-
|
|
244
|
-
return this.account;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
226
|
dispatch(disp) {
|
|
248
227
|
this._dispatches.push(disp);
|
|
249
228
|
}
|
|
250
229
|
|
|
251
|
-
drain() {
|
|
230
|
+
#drain() {
|
|
252
231
|
for (let i = 0; i < this._dispatches.length; i++) {
|
|
253
232
|
const disp = this._dispatches[i];
|
|
254
233
|
if (disp.check(this)) {
|
|
@@ -261,15 +240,40 @@ export class Bot {
|
|
|
261
240
|
}
|
|
262
241
|
}
|
|
263
242
|
|
|
264
|
-
async
|
|
243
|
+
async createAccount(email, pass) {
|
|
244
|
+
this.account.email = email;
|
|
245
|
+
this.account.password = pass;
|
|
246
|
+
|
|
247
|
+
const loginData = await createAccount(email, pass, this.proxy, this.instance);
|
|
248
|
+
return this.#processLoginData(loginData);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async login(email, pass) {
|
|
252
|
+
this.account.email = email;
|
|
253
|
+
this.account.password = pass;
|
|
254
|
+
|
|
255
|
+
const loginData = await loginWithCredentials(email, pass, this.proxy, this.instance);
|
|
256
|
+
return this.#processLoginData(loginData);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async loginAnonymously() {
|
|
260
|
+
delete this.account.email;
|
|
261
|
+
delete this.account.password;
|
|
262
|
+
|
|
265
263
|
const loginData = await loginAnonymously(this.proxy, this.instance);
|
|
264
|
+
return this.#processLoginData(loginData);
|
|
265
|
+
}
|
|
266
266
|
|
|
267
|
+
#processLoginData(loginData) {
|
|
267
268
|
if (typeof loginData == 'string') {
|
|
268
269
|
this.#emit('authFail', loginData);
|
|
269
270
|
return false;
|
|
270
271
|
}
|
|
271
272
|
|
|
272
|
-
|
|
273
|
+
if (loginData.banRemaining) {
|
|
274
|
+
this.#emit('banned', loginData.banRemaining);
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
273
277
|
|
|
274
278
|
this.account.rawLoginData = loginData;
|
|
275
279
|
|
|
@@ -277,19 +281,20 @@ export class Bot {
|
|
|
277
281
|
this.account.eggBalance = loginData.currentBalance;
|
|
278
282
|
this.account.emailVerified = loginData.emailVerified;
|
|
279
283
|
this.account.firebaseId = loginData.firebaseId;
|
|
284
|
+
this.account.id = loginData.id;
|
|
280
285
|
this.account.loadout = loginData.loadout;
|
|
281
286
|
this.account.ownedItemIds = loginData.ownedItemIds;
|
|
282
287
|
this.account.session = loginData.session;
|
|
283
288
|
this.account.sessionId = loginData.sessionId;
|
|
284
|
-
this.account.vip =
|
|
289
|
+
this.account.vip = loginData.upgradeProductId && !loginData.upgradeIsExpired;
|
|
285
290
|
|
|
286
291
|
return this.account;
|
|
287
292
|
}
|
|
288
293
|
|
|
289
294
|
async initMatchmaker() {
|
|
290
|
-
if (
|
|
295
|
+
if (this.account.id == 0) {
|
|
291
296
|
// console.log('Not logged in, attempting to create anonymous user...');
|
|
292
|
-
const anonLogin = await this
|
|
297
|
+
const anonLogin = await this.loginAnonymously();
|
|
293
298
|
if (!anonLogin) return false;
|
|
294
299
|
}
|
|
295
300
|
|
|
@@ -312,34 +317,33 @@ export class Bot {
|
|
|
312
317
|
async #joinGameWithCode(code) {
|
|
313
318
|
if (!await this.initMatchmaker()) return false;
|
|
314
319
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
delete this.game.raw.command; // pissed me off
|
|
320
|
+
return await new Promise((resolve) => {
|
|
321
|
+
const listener = (mes) => {
|
|
322
|
+
if (mes.command == 'gameFound') {
|
|
323
|
+
this.matchmaker.off('msg', listener);
|
|
320
324
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
if (mes.error && mes.error == 'gameNotFound')
|
|
325
|
-
throw new Error(`Game ${code} not found (likely expired).`)
|
|
326
|
-
};
|
|
325
|
+
this.game.raw = mes;
|
|
326
|
+
this.game.code = code;
|
|
327
327
|
|
|
328
|
-
|
|
328
|
+
resolve();
|
|
329
|
+
}
|
|
329
330
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
observe: false,
|
|
334
|
-
sessionId: this.account.sessionId
|
|
335
|
-
})
|
|
331
|
+
if (mes.error && mes.error == 'gameNotFound')
|
|
332
|
+
throw new Error(`Game ${code} not found (likely expired).`)
|
|
333
|
+
};
|
|
336
334
|
|
|
337
|
-
|
|
335
|
+
this.matchmaker.on('msg', listener);
|
|
338
336
|
|
|
339
|
-
|
|
337
|
+
this.matchmaker.send({
|
|
338
|
+
command: 'joinGame',
|
|
339
|
+
id: code,
|
|
340
|
+
observe: false,
|
|
341
|
+
sessionId: this.account.sessionId
|
|
342
|
+
})
|
|
343
|
+
});
|
|
340
344
|
}
|
|
341
345
|
|
|
342
|
-
async #onGameMesssage(msg) {
|
|
346
|
+
async #onGameMesssage(msg) {
|
|
343
347
|
CommIn.init(msg.data);
|
|
344
348
|
|
|
345
349
|
let out;
|
|
@@ -350,7 +354,7 @@ export class Bot {
|
|
|
350
354
|
out = CommOut.getBuffer();
|
|
351
355
|
out.packInt8(CommCode.joinGame);
|
|
352
356
|
|
|
353
|
-
out.packString(this.name); // name
|
|
357
|
+
out.packString(this.state.name); // name
|
|
354
358
|
out.packString(this.game.raw.uuid); // game id
|
|
355
359
|
|
|
356
360
|
out.packInt8(0); // hidebadge
|
|
@@ -360,10 +364,10 @@ export class Bot {
|
|
|
360
364
|
out.packString(this.account.firebaseId); // firebase id
|
|
361
365
|
out.packString(this.account.sessionId); // session id
|
|
362
366
|
|
|
363
|
-
out.send(this.
|
|
367
|
+
out.send(this.game.socket);
|
|
364
368
|
break;
|
|
365
369
|
|
|
366
|
-
case CommCode.gameJoined:
|
|
370
|
+
case CommCode.gameJoined: {
|
|
367
371
|
this.me.id = CommIn.unPackInt8U();
|
|
368
372
|
// console.log("My id is:", this.me.id);
|
|
369
373
|
this.me.team = CommIn.unPackInt8U();
|
|
@@ -373,9 +377,10 @@ export class Bot {
|
|
|
373
377
|
// console.log("Gametype:", this.game.gameMode, this.game.gameModeId);
|
|
374
378
|
this.game.mapIdx = CommIn.unPackInt8U();
|
|
375
379
|
this.game.map = Maps[this.game.mapIdx];
|
|
376
|
-
if (
|
|
380
|
+
if (this.intents.includes(this.Intents.PATHFINDING)) {
|
|
377
381
|
this.game.map.raw = await this.#fetchMap(this.game.map.filename, this.game.map.hash);
|
|
378
382
|
this.pathing.nodeList = new NodeList(this.game.map.raw);
|
|
383
|
+
if (this.game.gameModeId === GameModes.kotc) this.#initKotcZones();
|
|
379
384
|
}
|
|
380
385
|
// console.log("Map:", this.game.map);
|
|
381
386
|
this.game.playerLimit = CommIn.unPackInt8U();
|
|
@@ -389,34 +394,34 @@ export class Bot {
|
|
|
389
394
|
this.state.joinedGame = true;
|
|
390
395
|
this.lastDeathTime = Date.now();
|
|
391
396
|
|
|
397
|
+
const out = CommOut.getBuffer();
|
|
398
|
+
out.packInt8(CommCode.clientReady);
|
|
399
|
+
out.send(this.game.socket);
|
|
400
|
+
|
|
401
|
+
this.game.socket.onmessage = (msg) => this._packetQueue.push(msg.data);
|
|
402
|
+
|
|
403
|
+
if (this.autoUpdate)
|
|
404
|
+
setInterval(() => this.update(), this.updateInterval);
|
|
405
|
+
|
|
406
|
+
if (this.intents.includes(this.Intents.PING)) {
|
|
407
|
+
const out = CommOut.getBuffer();
|
|
408
|
+
out.packInt8(CommCode.ping);
|
|
409
|
+
out.send(this.game.socket);
|
|
410
|
+
this.lastPingTime = Date.now();
|
|
411
|
+
}
|
|
392
412
|
break;
|
|
413
|
+
}
|
|
393
414
|
|
|
394
415
|
case CommCode.eventModifier:
|
|
395
416
|
// console.log("Echoed eventModifier"); // why the fuck do you need to do this
|
|
396
417
|
out = CommOut.getBuffer();
|
|
397
418
|
out.packInt8(CommCode.eventModifier);
|
|
398
|
-
out.send(this.
|
|
419
|
+
out.send(this.game.socket);
|
|
399
420
|
break;
|
|
400
421
|
|
|
401
|
-
case CommCode.requestGameOptions:
|
|
402
|
-
|
|
403
|
-
out.packInt8(CommCode.gameOptions);
|
|
404
|
-
out.packInt8(this.game.options.gravity * 4);
|
|
405
|
-
out.packInt8(this.game.options.damage * 4);
|
|
406
|
-
out.packInt8(this.game.options.healthRegen * 4);
|
|
407
|
-
|
|
408
|
-
const flags =
|
|
409
|
-
(this.game.options.locked ? 1 : 0) |
|
|
410
|
-
(this.game.options.noTeamChange ? 2 : 0) |
|
|
411
|
-
(this.game.options.noTeamShuffle ? 4 : 0);
|
|
412
|
-
|
|
413
|
-
out.packInt8(flags);
|
|
414
|
-
|
|
415
|
-
this.game.options.weaponsDisabled.forEach((v) => {
|
|
416
|
-
out.packInt8(v ? 1 : 0);
|
|
417
|
-
});
|
|
422
|
+
case CommCode.requestGameOptions:
|
|
423
|
+
this.#processGameRequestOptionsPacket();
|
|
418
424
|
break;
|
|
419
|
-
}
|
|
420
425
|
|
|
421
426
|
default:
|
|
422
427
|
try {
|
|
@@ -449,52 +454,50 @@ export class Bot {
|
|
|
449
454
|
|
|
450
455
|
if (mapIdx == -1) throw new Error('invalid map, see the Maps constant for a list')
|
|
451
456
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
delete this.game.raw.command;
|
|
457
|
-
|
|
458
|
-
this.gameFound = true;
|
|
459
|
-
}
|
|
460
|
-
};
|
|
457
|
+
await new Promise((resolve) => {
|
|
458
|
+
const listener = (msg) => {
|
|
459
|
+
if (msg.command == 'gameFound') {
|
|
460
|
+
this.matchmaker.off('msg', listener);
|
|
461
461
|
|
|
462
|
-
|
|
462
|
+
this.game.raw = msg;
|
|
463
|
+
this.game.code = this.game.raw.id;
|
|
463
464
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
playType: PlayTypes.createPrivate,
|
|
468
|
-
gameType: GameModes[opts.mode],
|
|
469
|
-
sessionId: this.account.sessionId,
|
|
470
|
-
noobLobby: false,
|
|
471
|
-
map: mapIdx
|
|
472
|
-
});
|
|
465
|
+
resolve();
|
|
466
|
+
}
|
|
467
|
+
};
|
|
473
468
|
|
|
474
|
-
|
|
469
|
+
this.matchmaker.on('msg', listener);
|
|
475
470
|
|
|
476
|
-
|
|
471
|
+
this.matchmaker.send({
|
|
472
|
+
command: 'findGame',
|
|
473
|
+
region: opts.region,
|
|
474
|
+
playType: PlayTypes.createPrivate,
|
|
475
|
+
gameType: GameModes[opts.mode],
|
|
476
|
+
sessionId: this.account.sessionId,
|
|
477
|
+
noobLobby: false,
|
|
478
|
+
map: mapIdx
|
|
479
|
+
});
|
|
480
|
+
});
|
|
477
481
|
|
|
478
482
|
return this.game.raw;
|
|
479
483
|
}
|
|
480
484
|
|
|
481
|
-
async join(data) {
|
|
485
|
+
async join(name, data) {
|
|
486
|
+
this.state.name = name || 'yolkbot';
|
|
487
|
+
|
|
482
488
|
if (typeof data == 'string') {
|
|
483
489
|
if (data.includes('#')) data = data.split('#')[1]; // stupid shell kids put in full links
|
|
484
490
|
// this is a string code that we can pass and get the needed info from
|
|
485
491
|
await this.#joinGameWithCode(data);
|
|
486
492
|
} else if (typeof data == 'object') {
|
|
487
|
-
if (
|
|
493
|
+
if (this.account.id == 0) {
|
|
488
494
|
// console.log('passed an object but you still need to be logged in!!')
|
|
489
|
-
await this
|
|
495
|
+
await this.loginAnonymously();
|
|
490
496
|
}
|
|
491
497
|
|
|
492
498
|
// this is a game object that we can pass and get the needed info from
|
|
493
499
|
this.game.raw = data;
|
|
494
500
|
this.game.code = this.game.raw.id;
|
|
495
|
-
delete this.game.raw.command;
|
|
496
|
-
|
|
497
|
-
this.gameFound = true;
|
|
498
501
|
}
|
|
499
502
|
|
|
500
503
|
if (!this.game.raw.id || !this.game.raw.subdomain)
|
|
@@ -502,113 +505,103 @@ export class Bot {
|
|
|
502
505
|
|
|
503
506
|
// console.log(`Joining ${this.game.raw.id} using proxy ${this.proxy || 'none'}`);
|
|
504
507
|
|
|
505
|
-
|
|
508
|
+
const attempt = async () => {
|
|
509
|
+
try {
|
|
510
|
+
this.game.socket = new yolkws(`wss://${this.game.raw.subdomain}.${this.instance}/game/${this.game.raw.id}`, this.proxy);
|
|
511
|
+
} catch {
|
|
512
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
513
|
+
await attempt();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
await attempt();
|
|
506
518
|
|
|
507
|
-
this.
|
|
519
|
+
this.game.socket.binaryType = 'arraybuffer';
|
|
508
520
|
|
|
509
|
-
this.
|
|
521
|
+
this.game.socket.onopen = () => {
|
|
510
522
|
// console.log('Successfully connected to game server.');
|
|
511
523
|
}
|
|
512
524
|
|
|
513
|
-
this.
|
|
525
|
+
this.game.socket.onmessage = this.#onGameMesssage.bind(this);
|
|
514
526
|
|
|
515
|
-
this.
|
|
527
|
+
this.game.socket.onclose = (e) => {
|
|
516
528
|
// console.log('Game socket closed:', e.code, Object.entries(CloseCode).filter(([, v]) => v == e.code));
|
|
517
529
|
this.#emit('close', e.code);
|
|
518
530
|
}
|
|
519
|
-
|
|
520
|
-
while (!this.state.joinedGame) await new Promise(r => setTimeout(r, 5));
|
|
521
|
-
|
|
522
|
-
const out = CommOut.getBuffer();
|
|
523
|
-
out.packInt8(CommCode.clientReady);
|
|
524
|
-
out.send(this.gameSocket);
|
|
525
|
-
|
|
526
|
-
this.gameSocket.onmessage = (msg) => this._packetQueue.push(msg.data);
|
|
527
|
-
|
|
528
|
-
// console.log(`Successfully joined ${this.game.code}. Startup to join time: ${Date.now() - this.initTime} ms`);
|
|
529
|
-
|
|
530
|
-
if (this.autoUpdate)
|
|
531
|
-
setInterval(() => this.update(), this.updateInterval);
|
|
532
|
-
|
|
533
|
-
if (this.autoPing) {
|
|
534
|
-
const out = CommOut.getBuffer();
|
|
535
|
-
out.packInt8(CommCode.ping);
|
|
536
|
-
out.send(this.gameSocket);
|
|
537
|
-
this.lastPingTime = Date.now();
|
|
538
|
-
}
|
|
539
531
|
}
|
|
540
532
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
this.nUpdates++;
|
|
545
|
-
|
|
546
|
-
if (this._packetQueue.length === 0 && this._dispatches.length === 0) return;
|
|
547
|
-
|
|
548
|
-
let packet;
|
|
549
|
-
while ((packet = this._packetQueue.shift()) !== undefined) { this.#handlePacket(packet); }
|
|
550
|
-
|
|
551
|
-
this.drain();
|
|
533
|
+
#processPathfinding() {
|
|
534
|
+
const myPositionStr = Object.entries(this.me.position).map(entry => Math.floor(entry[1])).join(',');
|
|
552
535
|
|
|
553
|
-
if (this.pathing.
|
|
554
|
-
|
|
536
|
+
if (myPositionStr == this.pathing.activePath[this.pathing.activePath.length - 1].positionStr()) {
|
|
537
|
+
// console.log('Completed path to', this.pathing.activePath[this.pathing.activePath.length - 1].position);
|
|
538
|
+
this.pathing.followingPath = false;
|
|
539
|
+
this.pathing.activePath = null;
|
|
540
|
+
this.pathing.activeNode = null;
|
|
541
|
+
this.pathing.activeNodeIdx = 0;
|
|
555
542
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
this.pathing.
|
|
561
|
-
this.
|
|
562
|
-
|
|
563
|
-
this.dispatch(new MovementDispatch(0));
|
|
543
|
+
this.dispatch(new MovementDispatch(0));
|
|
544
|
+
} else {
|
|
545
|
+
let positionTarget;
|
|
546
|
+
if (this.pathing.activeNodeIdx < this.pathing.activePath.length - 1) {
|
|
547
|
+
positionTarget = this.pathing.activePath[this.pathing.activeNodeIdx + 1].flatCenter();
|
|
548
|
+
this.dispatch(new LookAtPosDispatch(positionTarget));
|
|
564
549
|
} else {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
this.dispatch(new LookAtPosDispatch(positionTarget));
|
|
569
|
-
} else {
|
|
570
|
-
positionTarget = this.pathing.activePath[this.pathing.activeNodeIdx].flatCenter();
|
|
571
|
-
this.dispatch(new LookAtPosDispatch(positionTarget));
|
|
572
|
-
}
|
|
550
|
+
positionTarget = this.pathing.activePath[this.pathing.activeNodeIdx].flatCenter();
|
|
551
|
+
this.dispatch(new LookAtPosDispatch(positionTarget));
|
|
552
|
+
}
|
|
573
553
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
} else {
|
|
581
|
-
// console.log('Close to node that\'s before, idx:',
|
|
582
|
-
// this.pathing.activePath.indexOf(node), 'current:', this.pathing.activeNodeIdx);
|
|
583
|
-
}
|
|
554
|
+
for (const node of this.pathing.activePath) {
|
|
555
|
+
if (node.flatRadialDistance(this.me.position) < 0.1 && node.position.y == Math.floor(this.me.position.y)) {
|
|
556
|
+
if (this.pathing.activePath.indexOf(node) >= this.pathing.activeNodeIdx) {
|
|
557
|
+
this.pathing.activeNodeIdx = this.pathing.activePath.indexOf(node) + 1;
|
|
558
|
+
this.pathing.activeNode = this.pathing.activePath[this.pathing.activeNodeIdx];
|
|
559
|
+
break;
|
|
584
560
|
} else {
|
|
585
|
-
// console.log('
|
|
561
|
+
// console.log('Close to node that\'s before, idx:',
|
|
562
|
+
// this.pathing.activePath.indexOf(node), 'current:', this.pathing.activeNodeIdx);
|
|
586
563
|
}
|
|
587
|
-
|
|
564
|
+
} else {
|
|
565
|
+
// console.log('Node at', node.position, 'is', node.flatRadialDistance(this.me.position), 'away.')
|
|
588
566
|
}
|
|
567
|
+
// console.log('activeNode is ', this.pathing.activeNode.flatRadialDistance(this.me.position), 'away');
|
|
568
|
+
}
|
|
589
569
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
}
|
|
570
|
+
if (!(this.controlKeys & Movements.FORWARD)) {
|
|
571
|
+
this.dispatch(new MovementDispatch(Movements.FORWARD));
|
|
593
572
|
}
|
|
573
|
+
}
|
|
594
574
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
}
|
|
575
|
+
/*let onPath = false;
|
|
576
|
+
for (const node of this.pathing.activePath) {
|
|
577
|
+
if (node.positionStr() == myPositionStr) {
|
|
578
|
+
onPath = true;
|
|
579
|
+
break;
|
|
601
580
|
}
|
|
602
|
-
if (!onPath) {
|
|
603
|
-
console.log('Got off-path somehow');
|
|
604
|
-
this.dispatch(new PathfindDispatch(this.pathing.activePath[this.pathing.activePath.length - 1]));
|
|
605
|
-
this.pathing.followingPath = false;
|
|
606
|
-
this.pathing.activePath = null;
|
|
607
|
-
this.pathing.activeNode = null;
|
|
608
|
-
this.pathing.activeNodeIdx = 0;
|
|
609
|
-
}*/
|
|
610
581
|
}
|
|
582
|
+
if (!onPath) {
|
|
583
|
+
console.log('Got off-path somehow');
|
|
584
|
+
this.dispatch(new PathfindDispatch(this.pathing.activePath[this.pathing.activePath.length - 1]));
|
|
585
|
+
this.pathing.followingPath = false;
|
|
586
|
+
this.pathing.activePath = null;
|
|
587
|
+
this.pathing.activeNode = null;
|
|
588
|
+
this.pathing.activeNodeIdx = 0;
|
|
589
|
+
}*/
|
|
590
|
+
}
|
|
611
591
|
|
|
592
|
+
update() {
|
|
593
|
+
if (!this.state.joinedGame) throw new Error('Not playing, can\'t update. ');
|
|
594
|
+
|
|
595
|
+
// process pathfinding
|
|
596
|
+
if (this.pathing.followingPath && this.intents.includes(this.Intents.PATHFINDING)) this.#processPathfinding();
|
|
597
|
+
|
|
598
|
+
// process incoming packets
|
|
599
|
+
while (this._packetQueue.length > 0) this.#handlePacket(this._packetQueue.shift());
|
|
600
|
+
|
|
601
|
+
// process dispatches
|
|
602
|
+
if (this._dispatches.length > 0) this.#drain();
|
|
603
|
+
|
|
604
|
+
// process syncMe
|
|
612
605
|
if (Date.now() - this.lastUpdateTime >= 50) {
|
|
613
606
|
this.#emit('tick');
|
|
614
607
|
|
|
@@ -624,14 +617,16 @@ export class Bot {
|
|
|
624
617
|
out.packRad(this.me.view.pitch); // pitch
|
|
625
618
|
out.packInt8(100); // fixes commcode issues, does nothing
|
|
626
619
|
}
|
|
627
|
-
out.send(this.
|
|
620
|
+
out.send(this.game.socket);
|
|
628
621
|
|
|
629
622
|
this.lastUpdateTime = Date.now();
|
|
630
623
|
this.state.shotsFired = 0;
|
|
631
624
|
}
|
|
632
625
|
|
|
633
|
-
|
|
634
|
-
|
|
626
|
+
while (this._liveCallbacks.length > 0) {
|
|
627
|
+
const cb = this._liveCallbacks.shift();
|
|
628
|
+
cb();
|
|
629
|
+
}
|
|
635
630
|
}
|
|
636
631
|
|
|
637
632
|
on(event, cb) {
|
|
@@ -688,6 +683,64 @@ export class Bot {
|
|
|
688
683
|
}
|
|
689
684
|
}
|
|
690
685
|
|
|
686
|
+
#initKotcZones() {
|
|
687
|
+
const meshData = this.game.map.raw.data['DYNAMIC.capture-zone.none'];
|
|
688
|
+
if (!meshData) return delete this.game.map.zones;
|
|
689
|
+
|
|
690
|
+
let numCaptureZones = 0;
|
|
691
|
+
const mapData = {};
|
|
692
|
+
const zones = [];
|
|
693
|
+
|
|
694
|
+
for (const cell of meshData) {
|
|
695
|
+
if (!mapData[cell.x]) mapData[cell.x] = {};
|
|
696
|
+
if (!mapData[cell.x][cell.y]) mapData[cell.x][cell.y] = {};
|
|
697
|
+
mapData[cell.x][cell.y][cell.z] = { zone: null };
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
const offsets = [
|
|
701
|
+
{ x: -1, z: 0 },
|
|
702
|
+
{ x: 1, z: 0 },
|
|
703
|
+
{ x: 0, z: -1 },
|
|
704
|
+
{ x: 0, z: 1 }
|
|
705
|
+
];
|
|
706
|
+
|
|
707
|
+
function getMapCellAt(x, y, z) {
|
|
708
|
+
return mapData[x] && mapData[x][y] && mapData[x][y][z] ? mapData[x][y][z] : null;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
for (const cellA of meshData) {
|
|
712
|
+
if (!mapData[cellA.x][cellA.y][cellA.z].zone) {
|
|
713
|
+
cellA.zone = ++numCaptureZones;
|
|
714
|
+
mapData[cellA.x][cellA.y][cellA.z].zone = cellA.zone;
|
|
715
|
+
|
|
716
|
+
const currentZone = [cellA];
|
|
717
|
+
let hits;
|
|
718
|
+
|
|
719
|
+
do {
|
|
720
|
+
hits = 0;
|
|
721
|
+
for (const cellB of meshData) {
|
|
722
|
+
if (!mapData[cellB.x][cellB.y][cellB.z].zone) {
|
|
723
|
+
for (const o of offsets) {
|
|
724
|
+
const cell = getMapCellAt(cellB.x + o.x, cellB.y, cellB.z + o.z);
|
|
725
|
+
if (cell && cell.zone == cellA.zone) {
|
|
726
|
+
hits++;
|
|
727
|
+
cellB.zone = cellA.zone;
|
|
728
|
+
mapData[cellB.x][cellB.y][cellB.z].zone = cellA.zone;
|
|
729
|
+
currentZone.push(cellB);
|
|
730
|
+
break;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
} while (hits > 0);
|
|
736
|
+
|
|
737
|
+
zones.push(currentZone);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
this.game.map.zones = zones;
|
|
742
|
+
}
|
|
743
|
+
|
|
691
744
|
#processChatPacket() {
|
|
692
745
|
const id = CommIn.unPackInt8U();
|
|
693
746
|
const msgFlags = CommIn.unPackInt8U();
|
|
@@ -704,6 +757,7 @@ export class Bot {
|
|
|
704
757
|
const name = CommIn.unPackString();
|
|
705
758
|
const safename = CommIn.unPackString(); // ??? (a)
|
|
706
759
|
const charClass = CommIn.unPackInt8U();
|
|
760
|
+
const findCosmetics = this.intents.includes(this.Intents.COSMETIC_DATA);
|
|
707
761
|
const playerData = {
|
|
708
762
|
id_: id_,
|
|
709
763
|
uniqueId_: uniqueId,
|
|
@@ -712,14 +766,14 @@ export class Bot {
|
|
|
712
766
|
charClass_: charClass,
|
|
713
767
|
team_: CommIn.unPackInt8U(),
|
|
714
768
|
primaryWeaponItem_: findItemById(CommIn.unPackInt16U()),
|
|
715
|
-
secondaryWeaponItem_: findItemById(CommIn.unPackInt16U())
|
|
769
|
+
secondaryWeaponItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
716
770
|
shellColor_: CommIn.unPackInt8U(),
|
|
717
|
-
hatItem_: findItemById(CommIn.unPackInt16U()),
|
|
718
|
-
stampItem_: findItemById(CommIn.unPackInt16U()),
|
|
771
|
+
hatItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
772
|
+
stampItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
719
773
|
unknownInt8: CommIn.unPackInt8(), // c
|
|
720
774
|
otherUnknownInt8: CommIn.unPackInt8(),
|
|
721
|
-
grenadeItem_: findItemById(CommIn.unPackInt16U()),
|
|
722
|
-
meleeItem_: findItemById(CommIn.unPackInt16U()),
|
|
775
|
+
grenadeItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
776
|
+
meleeItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
723
777
|
x_: CommIn.unPackFloat(),
|
|
724
778
|
y_: CommIn.unPackFloat(),
|
|
725
779
|
z_: CommIn.unPackFloat(),
|
|
@@ -777,11 +831,6 @@ export class Bot {
|
|
|
777
831
|
}
|
|
778
832
|
|
|
779
833
|
this.#emit('playerJoin', this.players[playerData.id_]);
|
|
780
|
-
|
|
781
|
-
const unp = CommIn.unPackInt8U();
|
|
782
|
-
if (unp == CommCode.addPlayer) { // there is another player stacked
|
|
783
|
-
this.#processAddPlayerPacket();
|
|
784
|
-
}
|
|
785
834
|
}
|
|
786
835
|
|
|
787
836
|
#processRespawnPacket() {
|
|
@@ -838,37 +887,53 @@ export class Bot {
|
|
|
838
887
|
const climbing = CommIn.unPackInt8U();
|
|
839
888
|
|
|
840
889
|
const player = this.players[id];
|
|
841
|
-
if (!player
|
|
890
|
+
if (!player) return;
|
|
842
891
|
|
|
843
|
-
if (player.
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
892
|
+
if (player.position.x !== x) player.position.x = x;
|
|
893
|
+
if (player.position.z !== z) player.position.z = z;
|
|
894
|
+
|
|
895
|
+
if (!player.jumping || Math.abs(player.position.y - y) > 0.5 && player.position.y !== y)
|
|
896
|
+
player.position.y = y;
|
|
897
|
+
|
|
898
|
+
if (player.climbing !== climbing) player.climbing = climbing;
|
|
899
|
+
|
|
900
|
+
if (this.intents.includes(this.Intents.BUFFERS)) {
|
|
901
|
+
if (!player.buffer) return;
|
|
902
|
+
|
|
903
|
+
if (player.id == this.me.id) {
|
|
904
|
+
for (let i2 = 0; i2 < 3 /* FramesBetweenSyncs */; i2++) {
|
|
905
|
+
CommIn.unPackInt8U();
|
|
906
|
+
CommIn.unPackRadU();
|
|
907
|
+
CommIn.unPackRad();
|
|
908
|
+
CommIn.unPackInt8U();
|
|
909
|
+
}
|
|
910
|
+
return;
|
|
848
911
|
}
|
|
849
|
-
}
|
|
850
912
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
yaw = CommIn.unPackRadU();
|
|
855
|
-
if (!isNaN(yaw)) { player.buffer[i2].yaw_ = yaw }
|
|
856
|
-
pitch = CommIn.unPackRad();
|
|
857
|
-
if (!isNaN(pitch)) { player.buffer[i2].pitch_ = pitch }
|
|
858
|
-
}
|
|
913
|
+
let yaw, pitch;
|
|
914
|
+
for (let i2 = 0; i2 < 3; i2++) {
|
|
915
|
+
player.buffer[i2].controlKeys = CommIn.unPackInt8U();
|
|
859
916
|
|
|
860
|
-
|
|
917
|
+
yaw = CommIn.unPackRadU();
|
|
918
|
+
if (!isNaN(yaw)) player.buffer[i2].yaw_ = yaw
|
|
861
919
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
}
|
|
920
|
+
pitch = CommIn.unPackRad();
|
|
921
|
+
if (!isNaN(pitch)) player.buffer[i2].pitch_ = pitch
|
|
865
922
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
923
|
+
CommIn.unPackInt8U();
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
player.buffer[0].x = x;
|
|
927
|
+
player.buffer[0].y = y;
|
|
928
|
+
player.buffer[0].z = z;
|
|
929
|
+
} else {
|
|
930
|
+
for (let i2 = 0; i2 < 3; i2++) {
|
|
931
|
+
CommIn.unPackInt8U();
|
|
932
|
+
CommIn.unPackRadU();
|
|
933
|
+
CommIn.unPackRad();
|
|
934
|
+
CommIn.unPackInt8U();
|
|
935
|
+
}
|
|
936
|
+
}
|
|
872
937
|
}
|
|
873
938
|
|
|
874
939
|
#processPausePacket() {
|
|
@@ -894,16 +959,14 @@ export class Bot {
|
|
|
894
959
|
#processDeathPacket() {
|
|
895
960
|
const killedId = CommIn.unPackInt8U();
|
|
896
961
|
const byId = CommIn.unPackInt8U();
|
|
897
|
-
|
|
962
|
+
|
|
963
|
+
CommIn.unPackInt8U();
|
|
964
|
+
CommIn.unPackInt8U();
|
|
965
|
+
CommIn.unPackInt8U();
|
|
898
966
|
|
|
899
967
|
const killed = this.players[killedId];
|
|
900
968
|
const killer = this.players[byId];
|
|
901
969
|
|
|
902
|
-
/*
|
|
903
|
-
const killerLastDmg = CommIn.unPackInt8U();
|
|
904
|
-
const killedLastDmg = CommIn.unPackInt8U();
|
|
905
|
-
*/
|
|
906
|
-
|
|
907
970
|
if (killed) {
|
|
908
971
|
killed.playing = false;
|
|
909
972
|
killed.kills = 0;
|
|
@@ -920,6 +983,9 @@ export class Bot {
|
|
|
920
983
|
#processFirePacket() {
|
|
921
984
|
const id = CommIn.unPackInt8U();
|
|
922
985
|
|
|
986
|
+
for (let i = 0; i < 6; i++)
|
|
987
|
+
CommIn.unPackFloat();
|
|
988
|
+
|
|
923
989
|
const player = this.players[id];
|
|
924
990
|
const playerWeapon = player.weapons[player.activeGun];
|
|
925
991
|
|
|
@@ -960,7 +1026,9 @@ export class Bot {
|
|
|
960
1026
|
}
|
|
961
1027
|
|
|
962
1028
|
if (type == CollectTypes.GRENADE) {
|
|
963
|
-
player.grenades
|
|
1029
|
+
player.grenades++;
|
|
1030
|
+
if (player.grenades > 3) player.grenades = 3
|
|
1031
|
+
|
|
964
1032
|
this.#emit('collectGrenade', player);
|
|
965
1033
|
}
|
|
966
1034
|
}
|
|
@@ -980,8 +1048,11 @@ export class Bot {
|
|
|
980
1048
|
|
|
981
1049
|
#processHitMePacket() {
|
|
982
1050
|
const hp = CommIn.unPackInt8U();
|
|
983
|
-
const oldHp = this.me.hp;
|
|
984
1051
|
|
|
1052
|
+
CommIn.unPackFloat();
|
|
1053
|
+
CommIn.unPackFloat();
|
|
1054
|
+
|
|
1055
|
+
const oldHp = this.me.hp;
|
|
985
1056
|
this.me.hp = hp;
|
|
986
1057
|
|
|
987
1058
|
this.#emit('selfDamaged', oldHp, this.me.hp);
|
|
@@ -1001,6 +1072,10 @@ export class Bot {
|
|
|
1001
1072
|
const newY = CommIn.unPackFloat();
|
|
1002
1073
|
const newZ = CommIn.unPackFloat();
|
|
1003
1074
|
|
|
1075
|
+
CommIn.unPackInt8U();
|
|
1076
|
+
CommIn.unPackInt8U();
|
|
1077
|
+
CommIn.unPackInt8U();
|
|
1078
|
+
|
|
1004
1079
|
const oldX = player.position.x;
|
|
1005
1080
|
const oldY = player.position.y;
|
|
1006
1081
|
const oldZ = player.position.z;
|
|
@@ -1017,7 +1092,7 @@ export class Bot {
|
|
|
1017
1092
|
#processEventModifierPacket() {
|
|
1018
1093
|
const out = CommOut.getBuffer();
|
|
1019
1094
|
out.packInt8(CommCode.eventModifier);
|
|
1020
|
-
out.send(this.
|
|
1095
|
+
out.send(this.game.socket);
|
|
1021
1096
|
}
|
|
1022
1097
|
|
|
1023
1098
|
#processRemovePlayerPacket() {
|
|
@@ -1052,7 +1127,7 @@ export class Bot {
|
|
|
1052
1127
|
this.#emit('gameStateChange', this.game);
|
|
1053
1128
|
} else if (this.game.gameModeId == GameModes.kotc) {
|
|
1054
1129
|
this.game.stage = CommIn.unPackInt8U(); // constants.CoopStates
|
|
1055
|
-
this.game.
|
|
1130
|
+
this.game.zoneNumber = CommIn.unPackInt8U(); // a number to represent which 'active zone' kotc is using
|
|
1056
1131
|
this.game.capturing = CommIn.unPackInt8U(); // the team capturing, named "teams" in shell src
|
|
1057
1132
|
this.game.captureProgress = CommIn.unPackInt16U(); // progress of the coop capture
|
|
1058
1133
|
this.game.numCapturing = CommIn.unPackInt8U(); // number of players capturing - number/1000
|
|
@@ -1062,8 +1137,12 @@ export class Bot {
|
|
|
1062
1137
|
// not in shell, for utility purposes =D
|
|
1063
1138
|
this.game.stageName = CoopStagesById[this.game.stage]; // name of the stage ('start' / 'capturing' / 'etc')
|
|
1064
1139
|
this.game.capturePercent = this.game.captureProgress / 1000; // progress of the capture as a percentage
|
|
1140
|
+
this.game.activeZone = this.game.map.zones ? this.game.map.zones[this.game.zoneNumber - 1] : null;
|
|
1065
1141
|
|
|
1066
1142
|
this.#emit('gameStateChange', this.game);
|
|
1143
|
+
} else if (this.game.gameModeId == GameModes.team) {
|
|
1144
|
+
this.game.teamScore[1] = CommIn.unPackInt16U();
|
|
1145
|
+
this.game.teamScore[2] = CommIn.unPackInt16U();
|
|
1067
1146
|
}
|
|
1068
1147
|
|
|
1069
1148
|
if (this.game.gameModeId !== GameModes.spatula) {
|
|
@@ -1072,13 +1151,16 @@ export class Bot {
|
|
|
1072
1151
|
|
|
1073
1152
|
if (this.game.gameModeId !== GameModes.kotc) {
|
|
1074
1153
|
delete this.game.stage;
|
|
1075
|
-
delete this.game.
|
|
1154
|
+
delete this.game.zoneNumber;
|
|
1076
1155
|
delete this.game.capturing;
|
|
1077
1156
|
delete this.game.captureProgress;
|
|
1078
|
-
delete this.game.numCapturing
|
|
1157
|
+
delete this.game.numCapturing;
|
|
1158
|
+
delete this.game.stageName;
|
|
1159
|
+
delete this.game.numCapturing;
|
|
1160
|
+
delete this.game.activeZone;
|
|
1079
1161
|
}
|
|
1080
1162
|
|
|
1081
|
-
if (this.game.gameModeId
|
|
1163
|
+
if (this.game.gameModeId == GameModes.ffa) {
|
|
1082
1164
|
delete this.game.teamScore;
|
|
1083
1165
|
}
|
|
1084
1166
|
}
|
|
@@ -1155,6 +1237,9 @@ export class Bot {
|
|
|
1155
1237
|
const hb = CommIn.unPackInt8U();
|
|
1156
1238
|
const hp = CommIn.unPackInt8U();
|
|
1157
1239
|
|
|
1240
|
+
CommIn.unPackFloat();
|
|
1241
|
+
CommIn.unPackFloat();
|
|
1242
|
+
|
|
1158
1243
|
this.me.hpShield = hb;
|
|
1159
1244
|
this.me.hp = hp;
|
|
1160
1245
|
|
|
@@ -1208,25 +1293,33 @@ export class Bot {
|
|
|
1208
1293
|
// console.log('owner reset game');
|
|
1209
1294
|
|
|
1210
1295
|
this.me.kills = 0;
|
|
1211
|
-
this.game.teamScore = [0, 0, 0];
|
|
1212
1296
|
|
|
1213
|
-
this.game.
|
|
1214
|
-
this.game.spatula.controlledByTeam = 0;
|
|
1215
|
-
this.game.spatula.coords = { x: 0, y: 0, z: 0 };
|
|
1297
|
+
if (this.game.gameModeId !== GameModes.ffa) this.game.teamScore = [0, 0, 0];
|
|
1216
1298
|
|
|
1217
|
-
this.game.
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
this.game.
|
|
1299
|
+
if (this.game.gameModeId === GameModes.spatula) {
|
|
1300
|
+
this.game.spatula.controlledBy = 0;
|
|
1301
|
+
this.game.spatula.controlledByTeam = 0;
|
|
1302
|
+
this.game.spatula.coords = { x: 0, y: 0, z: 0 };
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
if (this.game.gameModeId === GameModes.kotc) {
|
|
1306
|
+
this.game.stage = CoopStates.capturing;
|
|
1307
|
+
this.game.zoneNumber = 0;
|
|
1308
|
+
this.game.activeZone = null;
|
|
1309
|
+
this.game.capturing = 0;
|
|
1310
|
+
this.game.captureProgress = 0;
|
|
1311
|
+
this.game.numCapturing = 0;
|
|
1312
|
+
this.game.stageName = CoopStagesById[CoopStates.capturing];
|
|
1313
|
+
this.game.capturePercent = 0.0;
|
|
1314
|
+
}
|
|
1224
1315
|
|
|
1225
1316
|
this.#emit('gameReset');
|
|
1226
1317
|
}
|
|
1227
1318
|
}
|
|
1228
1319
|
|
|
1229
1320
|
#processPingPacket() {
|
|
1321
|
+
if (!this.intents.includes(this.Intents.PING)) return;
|
|
1322
|
+
|
|
1230
1323
|
const oldPing = this.ping;
|
|
1231
1324
|
|
|
1232
1325
|
this.ping = Date.now() - this.lastPingTime;
|
|
@@ -1236,7 +1329,7 @@ export class Bot {
|
|
|
1236
1329
|
setTimeout(() => {
|
|
1237
1330
|
const out = CommOut.getBuffer();
|
|
1238
1331
|
out.packInt8(CommCode.ping);
|
|
1239
|
-
out.send(this.
|
|
1332
|
+
out.send(this.game.socket);
|
|
1240
1333
|
this.lastPingTime = Date.now();
|
|
1241
1334
|
}, this.pingInterval);
|
|
1242
1335
|
}
|
|
@@ -1268,12 +1361,18 @@ export class Bot {
|
|
|
1268
1361
|
const grenadeIdx = CommIn.unPackInt16U();
|
|
1269
1362
|
const meleeIdx = CommIn.unPackInt16U();
|
|
1270
1363
|
|
|
1364
|
+
CommIn.unPackInt8();
|
|
1365
|
+
CommIn.unPackInt8();
|
|
1366
|
+
|
|
1367
|
+
const findCosmetics = this.intents.includes(this.Intents.COSMETIC_DATA);
|
|
1368
|
+
|
|
1271
1369
|
const primaryWeaponItem = findItemById(primaryWeaponIdx);
|
|
1272
|
-
|
|
1273
|
-
const
|
|
1274
|
-
const
|
|
1275
|
-
const
|
|
1276
|
-
const
|
|
1370
|
+
|
|
1371
|
+
const secondaryWeaponItem = findCosmetics ? findItemById(secondaryWeaponIdx) : secondaryWeaponIdx;
|
|
1372
|
+
const hatItem = findCosmetics ? findItemById(hatIdx) : hatIdx;
|
|
1373
|
+
const stampItem = findCosmetics ? findItemById(stampIdx) : stampIdx;
|
|
1374
|
+
const grenadeItem = findCosmetics ? findItemById(grenadeIdx) : grenadeIdx;
|
|
1375
|
+
const meleeItem = findCosmetics ? findItemById(meleeIdx) : meleeIdx;
|
|
1277
1376
|
|
|
1278
1377
|
const player = this.players[id];
|
|
1279
1378
|
if (player) {
|
|
@@ -1316,7 +1415,8 @@ export class Bot {
|
|
|
1316
1415
|
if (player) this.#emit('playerMelee', player);
|
|
1317
1416
|
}
|
|
1318
1417
|
|
|
1319
|
-
// we do this since reload doesn't get emitted
|
|
1418
|
+
// we do this since reload doesn't get emitted for the bot itself
|
|
1419
|
+
// so we simulate it when calling a reload dispatch
|
|
1320
1420
|
processReloadPacket(customPlayer, iUnderstandThisIsForInternalUseOnlyAndIShouldNotBeCallingThis) {
|
|
1321
1421
|
if (!iUnderstandThisIsForInternalUseOnlyAndIShouldNotBeCallingThis)
|
|
1322
1422
|
throw new Error('processReloadPacket is exposed for internal use only. do not call it.');
|
|
@@ -1341,140 +1441,407 @@ export class Bot {
|
|
|
1341
1441
|
this.#emit('playerReload', player, playerActiveWeapon);
|
|
1342
1442
|
}
|
|
1343
1443
|
|
|
1444
|
+
#processGameRequestOptionsPacket() {
|
|
1445
|
+
const out = CommOut.getBuffer();
|
|
1446
|
+
out.packInt8(CommCode.gameOptions);
|
|
1447
|
+
out.packInt8(this.game.options.gravity * 4);
|
|
1448
|
+
out.packInt8(this.game.options.damage * 4);
|
|
1449
|
+
out.packInt8(this.game.options.healthRegen * 4);
|
|
1450
|
+
|
|
1451
|
+
const flags =
|
|
1452
|
+
(this.game.options.locked ? 1 : 0) |
|
|
1453
|
+
(this.game.options.noTeamChange ? 2 : 0) |
|
|
1454
|
+
(this.game.options.noTeamShuffle ? 4 : 0);
|
|
1455
|
+
|
|
1456
|
+
out.packInt8(flags);
|
|
1457
|
+
|
|
1458
|
+
this.game.options.weaponsDisabled.forEach((v) => {
|
|
1459
|
+
out.packInt8(v ? 1 : 0);
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
#processExplodePacket() {
|
|
1464
|
+
const itemType = CommIn.unPackInt8U();
|
|
1465
|
+
let item = CommIn.unPackInt16U();
|
|
1466
|
+
const x = CommIn.unPackFloat();
|
|
1467
|
+
const y = CommIn.unPackFloat();
|
|
1468
|
+
const z = CommIn.unPackFloat();
|
|
1469
|
+
const damage = CommIn.unPackInt8U();
|
|
1470
|
+
const radius = CommIn.unPackFloat();
|
|
1471
|
+
|
|
1472
|
+
if (this.intents.includes(this.Intents.COSMETIC_DATA))
|
|
1473
|
+
item = findItemById(item);
|
|
1474
|
+
|
|
1475
|
+
if (itemType == ItemTypes.Grenade) this.#emit('grenadeExploded', item, { x, y, z }, damage, radius);
|
|
1476
|
+
else this.#emit('rocketHit', { x, y, z }, damage, radius);
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
#processThrowGrenadePacket() {
|
|
1480
|
+
const id = CommIn.unPackInt8U();
|
|
1481
|
+
const x = CommIn.unPackFloat();
|
|
1482
|
+
const y = CommIn.unPackFloat();
|
|
1483
|
+
const z = CommIn.unPackFloat();
|
|
1484
|
+
const dx = CommIn.unPackFloat();
|
|
1485
|
+
const dy = CommIn.unPackFloat();
|
|
1486
|
+
const dz = CommIn.unPackFloat();
|
|
1487
|
+
|
|
1488
|
+
const player = this.players[id];
|
|
1489
|
+
|
|
1490
|
+
if (player) {
|
|
1491
|
+
player.grenades--;
|
|
1492
|
+
this.#emit('playerThrowGrenade', player, { x, y, z }, { x: dx, y: dy, z: dz });
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1344
1496
|
#handlePacket(packet) {
|
|
1345
1497
|
CommIn.init(packet);
|
|
1346
|
-
this.#emit('packet', packet);
|
|
1347
|
-
const cmd = CommIn.unPackInt8U();
|
|
1348
|
-
switch (cmd) {
|
|
1349
|
-
case CommCode.chat:
|
|
1350
|
-
this.#processChatPacket(packet);
|
|
1351
|
-
break;
|
|
1352
1498
|
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
break;
|
|
1499
|
+
let lastCommand = 0;
|
|
1500
|
+
let abort = false;
|
|
1356
1501
|
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
break;
|
|
1502
|
+
while (CommIn.isMoreDataAvailable() && !abort) {
|
|
1503
|
+
const cmd = CommIn.unPackInt8U();
|
|
1360
1504
|
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1505
|
+
switch (cmd) {
|
|
1506
|
+
case CommCode.syncThem:
|
|
1507
|
+
this.#processExternalSyncPacket(packet);
|
|
1508
|
+
break;
|
|
1364
1509
|
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1510
|
+
case CommCode.fire:
|
|
1511
|
+
this.#processFirePacket(packet);
|
|
1512
|
+
break;
|
|
1368
1513
|
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1514
|
+
case CommCode.hitThem:
|
|
1515
|
+
this.#processHitThemPacket(packet);
|
|
1516
|
+
break;
|
|
1372
1517
|
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1518
|
+
case CommCode.syncMe:
|
|
1519
|
+
this.#processSyncMePacket(packet);
|
|
1520
|
+
break;
|
|
1376
1521
|
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1522
|
+
case CommCode.hitMe:
|
|
1523
|
+
this.#processHitMePacket(packet);
|
|
1524
|
+
break;
|
|
1380
1525
|
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1526
|
+
case CommCode.swapWeapon:
|
|
1527
|
+
this.#processSwapWeaponPacket(packet);
|
|
1528
|
+
break;
|
|
1384
1529
|
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1530
|
+
case CommCode.collectItem:
|
|
1531
|
+
this.#processCollectPacket(packet);
|
|
1532
|
+
break;
|
|
1388
1533
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1534
|
+
case CommCode.respawn:
|
|
1535
|
+
this.#processRespawnPacket(packet);
|
|
1536
|
+
break;
|
|
1392
1537
|
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1538
|
+
case CommCode.die:
|
|
1539
|
+
this.#processDeathPacket(packet);
|
|
1540
|
+
break;
|
|
1396
1541
|
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1542
|
+
case CommCode.pause:
|
|
1543
|
+
this.#processPausePacket(packet);
|
|
1544
|
+
break;
|
|
1400
1545
|
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1546
|
+
case CommCode.chat:
|
|
1547
|
+
this.#processChatPacket(packet);
|
|
1548
|
+
break;
|
|
1404
1549
|
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1550
|
+
case CommCode.addPlayer:
|
|
1551
|
+
this.#processAddPlayerPacket(packet);
|
|
1552
|
+
break;
|
|
1408
1553
|
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1554
|
+
case CommCode.removePlayer:
|
|
1555
|
+
this.#processRemovePlayerPacket(packet);
|
|
1556
|
+
break;
|
|
1412
1557
|
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1558
|
+
case CommCode.eventModifier:
|
|
1559
|
+
this.#processEventModifierPacket(packet);
|
|
1560
|
+
break;
|
|
1416
1561
|
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1562
|
+
case CommCode.metaGameState:
|
|
1563
|
+
this.#processGameStatePacket(packet);
|
|
1564
|
+
break;
|
|
1420
1565
|
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1566
|
+
case CommCode.beginShellStreak:
|
|
1567
|
+
this.#processBeginStreakPacket(packet);
|
|
1568
|
+
break;
|
|
1424
1569
|
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1570
|
+
case CommCode.endShellStreak:
|
|
1571
|
+
this.#processEndStreakPacket(packet);
|
|
1572
|
+
break;
|
|
1428
1573
|
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1574
|
+
case CommCode.hitMeHardBoiled:
|
|
1575
|
+
this.#processHitShieldPacket(packet);
|
|
1576
|
+
break;
|
|
1432
1577
|
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1578
|
+
case CommCode.gameOptions:
|
|
1579
|
+
this.#processGameOptionsPacket(packet);
|
|
1580
|
+
break;
|
|
1436
1581
|
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1582
|
+
case CommCode.ping:
|
|
1583
|
+
this.#processPingPacket(packet);
|
|
1584
|
+
break;
|
|
1440
1585
|
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1586
|
+
case CommCode.switchTeam:
|
|
1587
|
+
this.#processSwitchTeamPacket(packet);
|
|
1588
|
+
break;
|
|
1444
1589
|
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1590
|
+
case CommCode.changeCharacter:
|
|
1591
|
+
this.#processChangeCharacterPacket(packet);
|
|
1592
|
+
break;
|
|
1448
1593
|
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1594
|
+
case CommCode.reload:
|
|
1595
|
+
this.processReloadPacket(null, true);
|
|
1596
|
+
break;
|
|
1452
1597
|
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1598
|
+
case CommCode.explode:
|
|
1599
|
+
this.#processExplodePacket();
|
|
1600
|
+
break;
|
|
1456
1601
|
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1602
|
+
case CommCode.throwGrenade:
|
|
1603
|
+
this.#processThrowGrenadePacket();
|
|
1604
|
+
break;
|
|
1605
|
+
|
|
1606
|
+
case CommCode.spawnItem:
|
|
1607
|
+
this.#processSpawnItemPacket();
|
|
1608
|
+
break;
|
|
1609
|
+
|
|
1610
|
+
case CommCode.melee:
|
|
1611
|
+
this.#processMeleePacket();
|
|
1612
|
+
break;
|
|
1613
|
+
|
|
1614
|
+
case CommCode.updateBalance:
|
|
1615
|
+
this.#processUpdateBalancePacket(packet);
|
|
1616
|
+
break;
|
|
1617
|
+
|
|
1618
|
+
case CommCode.gameAction:
|
|
1619
|
+
this.#processGameActionPacket(packet);
|
|
1620
|
+
break;
|
|
1621
|
+
|
|
1622
|
+
case CommCode.requestGameOptions:
|
|
1623
|
+
this.#processGameRequestOptionsPacket();
|
|
1624
|
+
break;
|
|
1625
|
+
|
|
1626
|
+
case CommCode.respawnDenied:
|
|
1627
|
+
this.#processRespawnDeniedPacket(packet);
|
|
1628
|
+
break;
|
|
1460
1629
|
|
|
1461
|
-
case CommCode.clientReady:
|
|
1462
|
-
case CommCode.expireUpgrade:
|
|
1463
|
-
case CommCode.musicInfo:
|
|
1464
|
-
case CommCode.challengeCompleted:
|
|
1465
1630
|
// we do not plan to implement these
|
|
1466
1631
|
// for more info, see comm/codes.js
|
|
1467
|
-
|
|
1632
|
+
case CommCode.clientReady:
|
|
1633
|
+
case CommCode.expireUpgrade:
|
|
1634
|
+
break;
|
|
1468
1635
|
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
break;
|
|
1636
|
+
case CommCode.musicInfo:
|
|
1637
|
+
CommIn.unPackLongString();
|
|
1638
|
+
break;
|
|
1473
1639
|
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1640
|
+
case CommCode.challengeCompleted:
|
|
1641
|
+
CommIn.unPackInt8U();
|
|
1642
|
+
CommIn.unPackInt8U();
|
|
1643
|
+
break;
|
|
1644
|
+
|
|
1645
|
+
default:
|
|
1646
|
+
console.error(`handlePacket: I got but did not handle a: ${Object.keys(CommCode).find(k => CommCode[k] === cmd)}`);
|
|
1647
|
+
if (lastCommand) console.error(`handlePacket: It may be a result of the ${lastCommand} command.`);
|
|
1648
|
+
abort = true
|
|
1649
|
+
break;
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
lastCommand = Object.keys(CommCode).find(k => CommCode[k] === cmd);
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
async checkChiknWinner() {
|
|
1657
|
+
const response = await queryServices({
|
|
1658
|
+
cmd: 'chicknWinnerReady',
|
|
1659
|
+
id: this.account.id,
|
|
1660
|
+
sessionId: this.account.sessionId
|
|
1661
|
+
});
|
|
1662
|
+
|
|
1663
|
+
this.account.cw.limit = response.limit;
|
|
1664
|
+
this.account.cw.atLimit = response.limit > 3;
|
|
1665
|
+
|
|
1666
|
+
// if there is a "span", that means that it's under the daily limit and you can play again soon
|
|
1667
|
+
// if there is a "period", that means that the account is done for the day and must wait a long time
|
|
1668
|
+
this.account.cw.secondsUntilPlay = response.span || response.period || 0;
|
|
1669
|
+
this.account.cw.canPlayAgain = Date.now() + (this.account.cw.secondsUntilPlay * 1000);
|
|
1670
|
+
|
|
1671
|
+
return this.account.cw;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
async playChiknWinner() {
|
|
1675
|
+
if (this.account.cw.atLimit || this.account.cw.limit > ChiknWinnerDailyLimit) return 'hit_daily_limit';
|
|
1676
|
+
if (this.account.cw.canPlayAgain > Date.now()) return 'on_cooldown';
|
|
1677
|
+
|
|
1678
|
+
const response = await queryServices({
|
|
1679
|
+
cmd: 'incentivizedVideoReward',
|
|
1680
|
+
firebaseId: this.account.firebaseId,
|
|
1681
|
+
id: this.account.id,
|
|
1682
|
+
sessionId: this.account.sessionId,
|
|
1683
|
+
token: null
|
|
1684
|
+
}, this.proxy, this.instance);
|
|
1685
|
+
|
|
1686
|
+
if (response.error) {
|
|
1687
|
+
if (response.error == 'RATELIMITED') {
|
|
1688
|
+
await this.checkChiknWinner();
|
|
1689
|
+
return 'on_cooldown';
|
|
1690
|
+
} else if (response.error == 'SESSION_EXPIRED') {
|
|
1691
|
+
return 'session_expired';
|
|
1692
|
+
} else {
|
|
1693
|
+
console.error('Unknown Chikn Winner response', response);
|
|
1694
|
+
return 'unknown_error';
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
if (response.reward) {
|
|
1699
|
+
this.account.eggBalance += response.reward.eggsGiven;
|
|
1700
|
+
response.reward.itemIds.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1701
|
+
|
|
1702
|
+
await this.checkChiknWinner();
|
|
1703
|
+
|
|
1704
|
+
return response.reward;
|
|
1477
1705
|
}
|
|
1706
|
+
|
|
1707
|
+
console.error('Unknown Chikn Winner response', response);
|
|
1708
|
+
return 'unknown_error';
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
async resetChiknWinner() {
|
|
1712
|
+
if (this.account.eggBalance < 200) return 'not_enough_eggs';
|
|
1713
|
+
if (!this.account.cw.atLimit) return 'not_at_limit';
|
|
1714
|
+
|
|
1715
|
+
const response = await queryServices({
|
|
1716
|
+
cmd: 'chwReset',
|
|
1717
|
+
sessionId: this.account.sessionId
|
|
1718
|
+
});
|
|
1719
|
+
|
|
1720
|
+
if (response.result !== 'SUCCESS') {
|
|
1721
|
+
console.error('Unknown Chikn Winner reset response', response);
|
|
1722
|
+
return 'unknown_error';
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
this.account.eggBalance -= 200;
|
|
1726
|
+
await this.checkChiknWinner();
|
|
1727
|
+
|
|
1728
|
+
return this.account.cw;
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
canSee(target) {
|
|
1732
|
+
if (!this.intents.includes(this.Intents.PATHFINDING)) throw new Error('You must have the PATHFINDING intent to use this method.');
|
|
1733
|
+
return this.pathing.nodeList.hasLineOfSight(this.me.position, target.position);
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
getBestTarget() {
|
|
1737
|
+
const options = Object.values(this.players)
|
|
1738
|
+
.filter((player) => player)
|
|
1739
|
+
.filter((player) => player !== this.me)
|
|
1740
|
+
.filter((player) => player.playing)
|
|
1741
|
+
.filter((player) => player.hp > 0)
|
|
1742
|
+
.filter((player) => player.name !== this.me.name)
|
|
1743
|
+
.filter((player) => this.me.team === 0 || player.team !== this.me.team)
|
|
1744
|
+
.filter((player) => this.canSee(player));
|
|
1745
|
+
|
|
1746
|
+
let minDistance = 200;
|
|
1747
|
+
let targetPlayer = null;
|
|
1748
|
+
|
|
1749
|
+
for (const player of options) {
|
|
1750
|
+
const dx = player.position.x - this.me.position.x;
|
|
1751
|
+
const dy = player.position.y - this.me.position.y;
|
|
1752
|
+
const dz = player.position.z - this.me.position.z;
|
|
1753
|
+
|
|
1754
|
+
const distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
1755
|
+
|
|
1756
|
+
if (distance < minDistance) {
|
|
1757
|
+
minDistance = distance;
|
|
1758
|
+
targetPlayer = player;
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
return targetPlayer;
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
async refreshBalance() {
|
|
1766
|
+
const result = await queryServices({
|
|
1767
|
+
cmd: 'checkBalance',
|
|
1768
|
+
firebaseId: this.account.firebaseId,
|
|
1769
|
+
sessionId: this.account.sessionId
|
|
1770
|
+
}, this.proxy, this.instance);
|
|
1771
|
+
|
|
1772
|
+
this.account.eggBalance = result.currentBalance;
|
|
1773
|
+
|
|
1774
|
+
return result.currentBalance;
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
async redeemCode(code) {
|
|
1778
|
+
const result = await queryServices({
|
|
1779
|
+
cmd: 'redeem',
|
|
1780
|
+
firebaseId: this.account.firebaseId,
|
|
1781
|
+
sessionId: this.account.sessionId,
|
|
1782
|
+
id: this.account.id,
|
|
1783
|
+
code
|
|
1784
|
+
}, this.proxy, this.instance);
|
|
1785
|
+
|
|
1786
|
+
if (result.result === 'SUCCESS') {
|
|
1787
|
+
this.account.eggBalance = result.eggs_given;
|
|
1788
|
+
result.item_ids.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1789
|
+
|
|
1790
|
+
return {
|
|
1791
|
+
result,
|
|
1792
|
+
eggsGiven: result.eggs_given,
|
|
1793
|
+
itemIds: result.item_ids
|
|
1794
|
+
};
|
|
1795
|
+
} else return result;
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
async claimURLReward(reward) {
|
|
1799
|
+
const result = await queryServices({
|
|
1800
|
+
cmd: 'urlRewardParams',
|
|
1801
|
+
firebaseId: this.account.firebaseId,
|
|
1802
|
+
sessionId: this.account.sessionId,
|
|
1803
|
+
reward
|
|
1804
|
+
}, this.proxy, this.instance);
|
|
1805
|
+
|
|
1806
|
+
if (result.result === 'SUCCESS') {
|
|
1807
|
+
this.account.eggBalance += result.eggsGiven;
|
|
1808
|
+
result.itemIds.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
return result;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
async claimSocialReward(rewardTag) {
|
|
1815
|
+
const result = await queryServices({
|
|
1816
|
+
cmd: 'reward',
|
|
1817
|
+
firebaseId: this.account.firebaseId,
|
|
1818
|
+
sessionId: this.account.sessionId,
|
|
1819
|
+
rewardTag
|
|
1820
|
+
}, this.proxy, this.instance);
|
|
1821
|
+
|
|
1822
|
+
if (result.result === 'SUCCESS') {
|
|
1823
|
+
this.account.eggBalance += result.eggsGiven;
|
|
1824
|
+
result.itemIds.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
return result;
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
async buyItem(itemId) {
|
|
1831
|
+
const result = await queryServices({
|
|
1832
|
+
cmd: 'buy',
|
|
1833
|
+
firebaseId: this.account.firebaseId,
|
|
1834
|
+
sessionId: this.account.sessionId,
|
|
1835
|
+
itemId,
|
|
1836
|
+
save: true
|
|
1837
|
+
}, this.proxy, this.instance);
|
|
1838
|
+
|
|
1839
|
+
if (result.result === 'SUCCESS') {
|
|
1840
|
+
this.account.eggBalance = result.currentBalance;
|
|
1841
|
+
this.account.ownedItemIds.push(result.itemId);
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
return result;
|
|
1478
1845
|
}
|
|
1479
1846
|
}
|
|
1480
1847
|
|