yolkbot 0.1.3 → 0.1.4-alpha.1
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/browser/build/global.js +1 -1
- package/browser/build/module.js +1 -1
- package/dist/api.js +3 -0
- package/dist/bot/GamePlayer.js +3 -0
- package/dist/bot.js +3 -0
- package/dist/comm/Codes.js +3 -0
- package/dist/comm/CommIn.js +3 -0
- package/dist/comm/CommOut.js +3 -0
- package/dist/comm/OutBuffer.js +3 -0
- package/dist/comm/Pool.js +3 -0
- package/dist/comm/index.js +3 -0
- package/dist/constants/challenges.js +3 -0
- package/dist/constants/changelog.js +3 -0
- package/dist/constants/codes.js +3 -0
- package/dist/constants/guns.js +3 -0
- package/dist/constants/housePromo.js +3 -0
- package/dist/constants/index.js +3 -0
- package/dist/constants/items.js +3 -0
- package/dist/constants/language.js +3 -0
- package/dist/constants/maps.js +3 -0
- package/dist/constants/shellNews.js +3 -0
- package/dist/constants/shellYoutube.js +3 -0
- package/dist/constants/shopItems.js +3 -0
- package/dist/constants/sounds.js +3 -0
- package/dist/dispatches/BootPlayerDispatch.js +3 -0
- package/dist/dispatches/ChatDispatch.js +3 -0
- package/dist/dispatches/FireDispatch.js +3 -0
- package/dist/dispatches/GameOptionsDispatch.js +3 -0
- package/dist/dispatches/GoToAmmoDispatch.js +3 -0
- package/dist/dispatches/GoToCoopDispatch.js +3 -0
- package/dist/dispatches/GoToGrenadeDispatch.js +3 -0
- package/dist/dispatches/GoToPlayerDispatch.js +3 -0
- package/dist/dispatches/GoToSpatulaDispatch.js +3 -0
- package/dist/dispatches/LookAtDispatch.js +3 -0
- package/dist/dispatches/LookAtPosDispatch.js +3 -0
- package/dist/dispatches/MeleeDispatch.js +3 -0
- package/dist/dispatches/MovementDispatch.js +3 -0
- package/dist/dispatches/PauseDispatch.js +3 -0
- package/dist/dispatches/ReloadDispatch.js +3 -0
- package/dist/dispatches/ReportPlayerDispatch.js +3 -0
- package/dist/dispatches/SaveLoadoutDispatch.js +3 -0
- package/dist/dispatches/SpawnDispatch.js +3 -0
- package/dist/dispatches/SwapWeaponDispatch.js +3 -0
- package/dist/dispatches/SwitchTeamDispatch.js +3 -0
- package/dist/dispatches/ThrowGrenadeDispatch.js +3 -0
- package/dist/dispatches/index.js +3 -0
- package/dist/globals.js +3 -0
- package/dist/index.js +10 -0
- package/dist/matchmaker.js +3 -0
- package/dist/pathing/astar.js +3 -0
- package/dist/pathing/binaryheap.js +3 -0
- package/dist/pathing/mapnode.js +3 -0
- package/dist/socket.js +3 -0
- package/package.json +28 -28
- package/src/.DS_Store +0 -0
- package/src/api.js +0 -235
- package/src/bot/GamePlayer.js +0 -88
- package/src/bot.js +0 -1998
- package/src/comm/Codes.js +0 -99
- package/src/comm/CommIn.js +0 -84
- package/src/comm/CommOut.js +0 -16
- package/src/comm/OutBuffer.js +0 -60
- package/src/comm/Pool.js +0 -55
- package/src/comm/index.js +0 -16
- package/src/constants/challenges.js +0 -1822
- package/src/constants/changelog.js +0 -19
- package/src/constants/codes.js +0 -45
- package/src/constants/guns.js +0 -368
- package/src/constants/housePromo.js +0 -727
- package/src/constants/index.js +0 -121
- package/src/constants/items.js +0 -42533
- package/src/constants/language.js +0 -1669
- package/src/constants/maps.js +0 -1095
- package/src/constants/shellNews.js +0 -59
- package/src/constants/shellYoutube.js +0 -93
- package/src/constants/shopItems.js +0 -2032
- package/src/constants/sounds.js +0 -1160
- package/src/dispatches/BootPlayerDispatch.js +0 -21
- package/src/dispatches/ChatDispatch.js +0 -30
- package/src/dispatches/FireDispatch.js +0 -20
- package/src/dispatches/GameOptionsDispatch.js +0 -46
- package/src/dispatches/GoToAmmoDispatch.js +0 -44
- package/src/dispatches/GoToCoopDispatch.js +0 -44
- package/src/dispatches/GoToGrenadeDispatch.js +0 -44
- package/src/dispatches/GoToPlayerDispatch.js +0 -38
- package/src/dispatches/GoToSpatulaDispatch.js +0 -32
- package/src/dispatches/LookAtDispatch.js +0 -48
- package/src/dispatches/LookAtPosDispatch.js +0 -33
- package/src/dispatches/MeleeDispatch.js +0 -28
- package/src/dispatches/MovementDispatch.js +0 -19
- package/src/dispatches/PauseDispatch.js +0 -18
- package/src/dispatches/ReloadDispatch.js +0 -36
- package/src/dispatches/ReportPlayerDispatch.js +0 -51
- package/src/dispatches/SaveLoadoutDispatch.js +0 -119
- package/src/dispatches/SpawnDispatch.js +0 -21
- package/src/dispatches/SwapWeaponDispatch.js +0 -19
- package/src/dispatches/SwitchTeamDispatch.js +0 -34
- package/src/dispatches/ThrowGrenadeDispatch.js +0 -26
- package/src/dispatches/index.js +0 -69
- package/src/globals.js +0 -15
- package/src/index.js +0 -14
- package/src/matchmaker.js +0 -206
- package/src/pathing/astar.js +0 -71
- package/src/pathing/binaryheap.js +0 -117
- package/src/pathing/mapnode.js +0 -236
- package/src/socket.js +0 -19
- /package/{src → dist}/types/api.d.ts +0 -0
- /package/{src → dist}/types/bot/GamePlayer.d.ts +0 -0
- /package/{src → dist}/types/bot.d.ts +0 -0
- /package/{src → dist}/types/constants/challenges.d.ts +0 -0
- /package/{src → dist}/types/constants/guns.d.ts +0 -0
- /package/{src → dist}/types/constants/index.d.ts +0 -0
- /package/{src → dist}/types/constants/items.d.ts +0 -0
- /package/{src → dist}/types/constants/maps.d.ts +0 -0
- /package/{src → dist}/types/dispatches/BootPlayerDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/ChatDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/FireDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/GameOptionsDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/GoToAmmoDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/GoToCoopDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/GoToGrenadeDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/GoToPlayerDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/GoToSpatulaDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/LookAtDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/LookAtPosDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/MeleeDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/MovementDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/PauseDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/ReloadDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/ReportPlayerDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/SaveLoadoutDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/SpawnDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/SwapWeaponDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/SwitchTeamDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/ThrowGrenadeDispatch.d.ts +0 -0
- /package/{src → dist}/types/dispatches/index.d.ts +0 -0
- /package/{src → dist}/types/matchmaker.d.ts +0 -0
- /package/{src → dist}/types/socket.d.ts +0 -0
package/src/bot.js
DELETED
|
@@ -1,1998 +0,0 @@
|
|
|
1
|
-
import { createAccount, loginAnonymously, loginWithCredentials, loginWithRefreshToken, queryServices } from './api.js';
|
|
2
|
-
|
|
3
|
-
import CommIn from './comm/CommIn.js';
|
|
4
|
-
import CommOut from './comm/CommOut.js';
|
|
5
|
-
import { CommCode } from './constants/codes.js';
|
|
6
|
-
|
|
7
|
-
import GamePlayer from './bot/GamePlayer.js';
|
|
8
|
-
import Matchmaker from './matchmaker.js';
|
|
9
|
-
import yolkws from './socket.js';
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
ChiknWinnerDailyLimit,
|
|
13
|
-
CollectTypes,
|
|
14
|
-
CoopStates,
|
|
15
|
-
findItemById,
|
|
16
|
-
GameActions,
|
|
17
|
-
GameModes,
|
|
18
|
-
GameOptionFlags,
|
|
19
|
-
GunList,
|
|
20
|
-
IsBrowser,
|
|
21
|
-
ItemTypes,
|
|
22
|
-
Movements,
|
|
23
|
-
PlayTypes,
|
|
24
|
-
ProxiesEnabled,
|
|
25
|
-
ShellStreaks
|
|
26
|
-
} from './constants/index.js';
|
|
27
|
-
|
|
28
|
-
import LookAtPosDispatch from './dispatches/LookAtPosDispatch.js';
|
|
29
|
-
import MovementDispatch from './dispatches/MovementDispatch.js';
|
|
30
|
-
|
|
31
|
-
import { NodeList } from './pathing/mapnode.js';
|
|
32
|
-
|
|
33
|
-
import { Challenges } from './constants/challenges.js';
|
|
34
|
-
import { Maps } from './constants/maps.js';
|
|
35
|
-
|
|
36
|
-
const CoopStagesById = Object.fromEntries(Object.entries(CoopStates).map(([key, value]) => [value, key]));
|
|
37
|
-
const GameModesById = Object.fromEntries(Object.entries(GameModes).map(([key, value]) => [value, key]));
|
|
38
|
-
|
|
39
|
-
const intents = {
|
|
40
|
-
CHALLENGES: 1,
|
|
41
|
-
STATS: 2,
|
|
42
|
-
PATHFINDING: 3,
|
|
43
|
-
BUFFERS: 4,
|
|
44
|
-
PING: 5,
|
|
45
|
-
COSMETIC_DATA: 6,
|
|
46
|
-
PLAYER_HEALTH: 7,
|
|
47
|
-
PACKET_HOOK: 8,
|
|
48
|
-
MONITOR: 9
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export class Bot {
|
|
52
|
-
static Intents = intents;
|
|
53
|
-
Intents = intents;
|
|
54
|
-
|
|
55
|
-
constructor(params = {}) {
|
|
56
|
-
if (params.proxy && !ProxiesEnabled)
|
|
57
|
-
throw new Error('proxies do not work and hence are not supported in the browser');
|
|
58
|
-
|
|
59
|
-
this.intents = params.intents || [];
|
|
60
|
-
|
|
61
|
-
this.instance = params.instance || 'shellshock.io';
|
|
62
|
-
this.proxy = params.proxy || '';
|
|
63
|
-
|
|
64
|
-
this.autoUpdate = params.doUpdate || true;
|
|
65
|
-
this.updateInterval = params.updateInterval || 16.5;
|
|
66
|
-
|
|
67
|
-
this._hooks = {};
|
|
68
|
-
this._globalHooks = [];
|
|
69
|
-
this._liveCallbacks = [];
|
|
70
|
-
|
|
71
|
-
// private information NOT FOR OTHER PLAYERS!!
|
|
72
|
-
this.state = {
|
|
73
|
-
// kept for specifying various params
|
|
74
|
-
name: '',
|
|
75
|
-
weaponIdx: 0,
|
|
76
|
-
|
|
77
|
-
// tracking for dispatch checks
|
|
78
|
-
reloading: false,
|
|
79
|
-
swappingGun: false,
|
|
80
|
-
usingMelee: false,
|
|
81
|
-
|
|
82
|
-
// shots fired ezzz
|
|
83
|
-
shotsFired: 0,
|
|
84
|
-
|
|
85
|
-
// holy glitch
|
|
86
|
-
quit: false
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
this.players = {}
|
|
90
|
-
this.me = new GamePlayer(this.id, 0, {})
|
|
91
|
-
|
|
92
|
-
this.game = {
|
|
93
|
-
raw: {}, // matchmaker response
|
|
94
|
-
code: '',
|
|
95
|
-
socket: null,
|
|
96
|
-
|
|
97
|
-
// data given on sign in
|
|
98
|
-
gameModeId: 0, // assume ffa
|
|
99
|
-
gameMode: GameModesById[0], // assume ffa
|
|
100
|
-
mapIdx: 0,
|
|
101
|
-
map: {
|
|
102
|
-
filename: '',
|
|
103
|
-
hash: '',
|
|
104
|
-
name: '',
|
|
105
|
-
modes: {
|
|
106
|
-
FFA: false,
|
|
107
|
-
Teams: false,
|
|
108
|
-
Spatula: false,
|
|
109
|
-
King: false
|
|
110
|
-
},
|
|
111
|
-
availability: 'both',
|
|
112
|
-
numPlayers: '18',
|
|
113
|
-
|
|
114
|
-
raw: {},
|
|
115
|
-
nodes: {},
|
|
116
|
-
zones: []
|
|
117
|
-
},
|
|
118
|
-
playerLimit: 0,
|
|
119
|
-
isGameOwner: false,
|
|
120
|
-
isPrivate: true,
|
|
121
|
-
|
|
122
|
-
// game options
|
|
123
|
-
options: {
|
|
124
|
-
gravity: 1,
|
|
125
|
-
damage: 1,
|
|
126
|
-
healthRegen: 1,
|
|
127
|
-
locked: false,
|
|
128
|
-
noTeamChange: false,
|
|
129
|
-
noTeamShuffle: false,
|
|
130
|
-
// array of weapons from eggk to trihard
|
|
131
|
-
// false = alloed to use
|
|
132
|
-
// true = cannot use
|
|
133
|
-
weaponsDisabled: Array(7).fill(false),
|
|
134
|
-
mustUseSecondary: false // if weaponsDisabled is ALL true
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
// ammos/grenades on the ground that can be picked up
|
|
138
|
-
collectables: [[], []],
|
|
139
|
-
|
|
140
|
-
// data from metaGame
|
|
141
|
-
teamScore: [0, 0, 0], // [0, blue, red] - no clue what 1st index is for
|
|
142
|
-
|
|
143
|
-
// data from spatula game
|
|
144
|
-
spatula: {
|
|
145
|
-
coords: { x: 0, y: 0, z: 0 },
|
|
146
|
-
controlledBy: 0,
|
|
147
|
-
controlledByTeam: 0
|
|
148
|
-
},
|
|
149
|
-
|
|
150
|
-
// data from kotc
|
|
151
|
-
stage: CoopStates.capturing,
|
|
152
|
-
zoneNumber: 0,
|
|
153
|
-
activeZone: [],
|
|
154
|
-
capturing: 0,
|
|
155
|
-
captureProgress: 0,
|
|
156
|
-
numCapturing: 0,
|
|
157
|
-
stageName: '',
|
|
158
|
-
capturePercent: 0.0,
|
|
159
|
-
|
|
160
|
-
// egg org
|
|
161
|
-
eggOrg: {
|
|
162
|
-
evil: 0,
|
|
163
|
-
good: 0
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
this.account = {
|
|
168
|
-
// used for auth
|
|
169
|
-
id: 0,
|
|
170
|
-
firebaseId: '',
|
|
171
|
-
sessionId: '',
|
|
172
|
-
session: '',
|
|
173
|
-
|
|
174
|
-
// raw login params
|
|
175
|
-
email: '',
|
|
176
|
-
password: '',
|
|
177
|
-
|
|
178
|
-
// chikn winner related info
|
|
179
|
-
cw: {
|
|
180
|
-
atLimit: false,
|
|
181
|
-
limit: 0,
|
|
182
|
-
secondsUntilPlay: 0, // short cooldown, in seconds
|
|
183
|
-
canPlayAgain: Date.now()
|
|
184
|
-
},
|
|
185
|
-
|
|
186
|
-
// used for skin changing
|
|
187
|
-
loadout: {
|
|
188
|
-
hatId: null,
|
|
189
|
-
meleeId: 0,
|
|
190
|
-
stampId: null,
|
|
191
|
-
classIdx: 0,
|
|
192
|
-
colorIdx: 0,
|
|
193
|
-
grenadeId: 0,
|
|
194
|
-
primaryId: [
|
|
195
|
-
3100, 3600,
|
|
196
|
-
3400, 3800,
|
|
197
|
-
4000, 4200,
|
|
198
|
-
4500
|
|
199
|
-
],
|
|
200
|
-
secondaryId: new Array(7).fill(3000),
|
|
201
|
-
stampPositionX: 0,
|
|
202
|
-
stampPositionY: 0
|
|
203
|
-
},
|
|
204
|
-
ownedItemIds: [],
|
|
205
|
-
vip: false,
|
|
206
|
-
|
|
207
|
-
// used for chat checking
|
|
208
|
-
accountAge: 0,
|
|
209
|
-
emailVerified: false,
|
|
210
|
-
|
|
211
|
-
// balance is tracked
|
|
212
|
-
eggBalance: 0,
|
|
213
|
-
|
|
214
|
-
// egg org side
|
|
215
|
-
eggOrgSide: 'none',
|
|
216
|
-
|
|
217
|
-
// raw login
|
|
218
|
-
rawLoginData: {}
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
this._dispatches = [];
|
|
222
|
-
this._packetQueue = [];
|
|
223
|
-
|
|
224
|
-
this.matchmaker = null;
|
|
225
|
-
|
|
226
|
-
this.ping = 0;
|
|
227
|
-
this.lastPingTime = -1;
|
|
228
|
-
|
|
229
|
-
this.lastDeathTime = -1;
|
|
230
|
-
this.lastChatTime = -1;
|
|
231
|
-
this.lastUpdateTime = -1;
|
|
232
|
-
|
|
233
|
-
this.controlKeys = 0;
|
|
234
|
-
|
|
235
|
-
this.pathing = {
|
|
236
|
-
nodeList: null,
|
|
237
|
-
followingPath: false,
|
|
238
|
-
activePath: null,
|
|
239
|
-
activeNode: null,
|
|
240
|
-
activeNodeIdx: 0
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (this.intents.includes(this.Intents.PLAYER_HEALTH)) this.healthIntervalId = setInterval(() => {
|
|
244
|
-
if (!this.players) return;
|
|
245
|
-
|
|
246
|
-
for (const player of Object.values(this.players)) {
|
|
247
|
-
if (player.playing && player.hp > 0) {
|
|
248
|
-
const regenSpeed = 0.1 * (this.game.isPrivate ? this.game.options.healthRegen : 1);
|
|
249
|
-
|
|
250
|
-
if (player.streakRewards.includes(ShellStreaks.OverHeal)) {
|
|
251
|
-
player.hp = Math.max(100, player.hp - regenSpeed);
|
|
252
|
-
} else {
|
|
253
|
-
player.hp = Math.min(100, player.hp + regenSpeed);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}, 33);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
dispatch(disp) {
|
|
261
|
-
this._dispatches.push(disp);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
async createAccount(email, pass) {
|
|
265
|
-
this.account.email = email;
|
|
266
|
-
this.account.password = pass;
|
|
267
|
-
|
|
268
|
-
const loginData = await createAccount(email, pass, this.proxy, this.instance);
|
|
269
|
-
return await this.#processLoginData(loginData.playerOutput);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
async login(email, pass) {
|
|
273
|
-
this.account.email = email;
|
|
274
|
-
this.account.password = pass;
|
|
275
|
-
|
|
276
|
-
const loginData = await loginWithCredentials(email, pass, this.proxy, this.instance);
|
|
277
|
-
return await this.#processLoginData(loginData.playerOutput);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
async loginWithRefreshToken(refreshToken) {
|
|
281
|
-
const loginData = await loginWithRefreshToken(refreshToken, this.proxy, this.instance);
|
|
282
|
-
return await this.#processLoginData(loginData.playerOutput);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
async loginAnonymously() {
|
|
286
|
-
delete this.account.email;
|
|
287
|
-
delete this.account.password;
|
|
288
|
-
|
|
289
|
-
const loginData = await loginAnonymously(this.proxy, this.instance);
|
|
290
|
-
return await this.#processLoginData(loginData.playerOutput);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
async #processLoginData(loginData) {
|
|
294
|
-
if (typeof loginData !== 'object') {
|
|
295
|
-
this.emit('authFail', loginData);
|
|
296
|
-
return false;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
if (loginData.banRemaining) {
|
|
300
|
-
this.emit('banned', loginData.banRemaining);
|
|
301
|
-
return false;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
this.account.rawLoginData = loginData;
|
|
305
|
-
|
|
306
|
-
this.account.accountAge = loginData.accountAge;
|
|
307
|
-
this.account.eggBalance = loginData.currentBalance;
|
|
308
|
-
this.account.eggOrgSide = loginData.eggOrgNeedsFaction === 'rew_eggfu' ? 'good' : 'evil';
|
|
309
|
-
this.account.emailVerified = loginData.emailVerified;
|
|
310
|
-
this.account.firebaseId = loginData.firebaseId;
|
|
311
|
-
this.account.id = loginData.id;
|
|
312
|
-
this.account.loadout = loginData.loadout;
|
|
313
|
-
this.account.ownedItemIds = loginData.ownedItemIds;
|
|
314
|
-
this.account.session = loginData.session;
|
|
315
|
-
this.account.sessionId = loginData.sessionId;
|
|
316
|
-
this.account.vip = loginData.upgradeProductId && !loginData.upgradeIsExpired;
|
|
317
|
-
|
|
318
|
-
if (this.intents.includes(this.Intents.STATS)) this.account.stats = {
|
|
319
|
-
lifetime: loginData.statsLifetime,
|
|
320
|
-
monthly: loginData.statsCurrent
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
if (this.intents.includes(this.Intents.CHALLENGES))
|
|
324
|
-
this.#importChallenges(loginData.challenges);
|
|
325
|
-
|
|
326
|
-
return this.account;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
#importChallenges(challengeArray) {
|
|
330
|
-
this.account.challenges = [];
|
|
331
|
-
|
|
332
|
-
for (const challengeData of challengeArray) {
|
|
333
|
-
const challengeInfo = Challenges.find(c => c.id == challengeData.challengeId);
|
|
334
|
-
if (!challengeInfo) continue;
|
|
335
|
-
|
|
336
|
-
delete challengeData.playerId;
|
|
337
|
-
|
|
338
|
-
this.account.challenges.push({
|
|
339
|
-
raw: { challengeInfo, challengeData },
|
|
340
|
-
id: challengeData.challengeId,
|
|
341
|
-
name: challengeInfo.loc.title,
|
|
342
|
-
desc: challengeInfo.loc.desc,
|
|
343
|
-
rewardEggs: challengeInfo.reward,
|
|
344
|
-
isRerolled: !!challengeData.reset,
|
|
345
|
-
isClaimed: !!challengeData.claimed,
|
|
346
|
-
isCompleted: !!challengeData.completed,
|
|
347
|
-
progressNum: challengeData.progress,
|
|
348
|
-
goalNum: challengeInfo.goal
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
async initMatchmaker() {
|
|
354
|
-
if (this.account.id == 0) {
|
|
355
|
-
// console.log('Not logged in, attempting to create anonymous user...');
|
|
356
|
-
const anonLogin = await this.loginAnonymously();
|
|
357
|
-
if (!anonLogin) return false;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
if (!this.matchmaker) {
|
|
361
|
-
// console.log('No matchmaker, creating instance')
|
|
362
|
-
this.matchmaker = new Matchmaker({
|
|
363
|
-
sessionId: this.account.sessionId,
|
|
364
|
-
proxy: this.proxy,
|
|
365
|
-
instance: this.instance
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
this.matchmaker.on('authFail', (data) => this.emit('authFail', data));
|
|
369
|
-
|
|
370
|
-
await this.matchmaker.getRegions();
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return true;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
async #joinGameWithCode(code) {
|
|
377
|
-
if (!await this.initMatchmaker()) return false;
|
|
378
|
-
|
|
379
|
-
return await new Promise((resolve) => {
|
|
380
|
-
const listener = (mes) => {
|
|
381
|
-
if (mes.command == 'gameFound') {
|
|
382
|
-
this.matchmaker.off('msg', listener);
|
|
383
|
-
|
|
384
|
-
this.game.raw = mes;
|
|
385
|
-
this.game.code = mes.id;
|
|
386
|
-
|
|
387
|
-
resolve();
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
if (mes.error && mes.error == 'gameNotFound')
|
|
391
|
-
throw new Error(`Game ${code} not found (likely expired).`)
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
this.matchmaker.on('msg', listener);
|
|
395
|
-
|
|
396
|
-
this.matchmaker.send({
|
|
397
|
-
command: 'joinGame',
|
|
398
|
-
id: code,
|
|
399
|
-
observe: false,
|
|
400
|
-
sessionId: this.account.sessionId
|
|
401
|
-
})
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// region - a region id ('useast', 'germany', etc)
|
|
406
|
-
// mode - a mode name that corresponds to a GameMode id
|
|
407
|
-
// map - the name of a map
|
|
408
|
-
async createPrivateGame(opts = {}) {
|
|
409
|
-
if (!await this.initMatchmaker()) return false;
|
|
410
|
-
|
|
411
|
-
if (!opts.region) throw new Error('pass a region: createPrivateGame({ region: "useast", ... })')
|
|
412
|
-
if (!this.matchmaker.regionList.find(r => r.id == opts.region))
|
|
413
|
-
throw new Error('invalid region, see <bot>.matchmaker.regionList for a region list (pass an "id")')
|
|
414
|
-
|
|
415
|
-
if (!opts.mode) throw new Error('pass a mode: createPrivateGame({ mode: "ffa", ... })')
|
|
416
|
-
if (GameModes[opts.mode] == undefined) throw new Error('invalid mode, see GameModes for a list')
|
|
417
|
-
|
|
418
|
-
if (!opts.map) throw new Error('pass a map: createPrivateGame({ map: "downfall", ... })')
|
|
419
|
-
|
|
420
|
-
const map = Maps.find(m => m.name.toLowerCase() == opts.map.toLowerCase());
|
|
421
|
-
const mapIdx = Maps.indexOf(map);
|
|
422
|
-
|
|
423
|
-
if (mapIdx == -1) throw new Error('invalid map, see the Maps constant for a list')
|
|
424
|
-
|
|
425
|
-
await new Promise((resolve) => {
|
|
426
|
-
const listener = (msg) => {
|
|
427
|
-
if (msg.command == 'gameFound') {
|
|
428
|
-
this.matchmaker.off('msg', listener);
|
|
429
|
-
|
|
430
|
-
this.game.raw = msg;
|
|
431
|
-
this.game.code = this.game.raw.id;
|
|
432
|
-
|
|
433
|
-
resolve();
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
this.matchmaker.on('msg', listener);
|
|
438
|
-
|
|
439
|
-
this.matchmaker.send({
|
|
440
|
-
command: 'findGame',
|
|
441
|
-
region: opts.region,
|
|
442
|
-
playType: PlayTypes.createPrivate,
|
|
443
|
-
gameType: GameModes[opts.mode],
|
|
444
|
-
sessionId: this.account.sessionId,
|
|
445
|
-
noobLobby: false,
|
|
446
|
-
map: mapIdx
|
|
447
|
-
});
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
return this.game.raw;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
async join(name, data) {
|
|
454
|
-
this.state.name = name || 'yolkbot';
|
|
455
|
-
|
|
456
|
-
if (typeof data == 'string') {
|
|
457
|
-
if (data.includes('#')) data = data.split('#')[1]; // stupid shell kids put in full links
|
|
458
|
-
// this is a string code that we can pass and get the needed info from
|
|
459
|
-
await this.#joinGameWithCode(data);
|
|
460
|
-
} else if (typeof data == 'object') {
|
|
461
|
-
if (this.account.id == 0) {
|
|
462
|
-
// console.log('passed an object but you still need to be logged in!!')
|
|
463
|
-
await this.loginAnonymously();
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// this is a game object that we can pass and get the needed info from
|
|
467
|
-
this.game.raw = data;
|
|
468
|
-
this.game.code = this.game.raw.id;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
if (!this.game.raw.id || !this.game.raw.subdomain)
|
|
472
|
-
throw new Error('invalid game data passed to <bot>.join');
|
|
473
|
-
|
|
474
|
-
// console.log(`Joining ${this.game.raw.id} using proxy ${this.proxy || 'none'}`);
|
|
475
|
-
|
|
476
|
-
const attempt = async () => {
|
|
477
|
-
try {
|
|
478
|
-
this.game.socket = new yolkws(`wss://${this.game.raw.subdomain}.${this.instance}/game/${this.game.raw.id}`, this.proxy);
|
|
479
|
-
this.game.socket.onerror = async (e) => {
|
|
480
|
-
console.error(e);
|
|
481
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
482
|
-
return await attempt();
|
|
483
|
-
}
|
|
484
|
-
} catch {
|
|
485
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
486
|
-
await attempt();
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
await attempt();
|
|
491
|
-
|
|
492
|
-
this.game.socket.binaryType = 'arraybuffer';
|
|
493
|
-
|
|
494
|
-
this.game.socket.onopen = () => {
|
|
495
|
-
this.game.socket.onerror = null;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
this.game.socket.onmessage = (msg) => this.processPacket(msg.data);
|
|
499
|
-
|
|
500
|
-
this.game.socket.onclose = (e) => {
|
|
501
|
-
// console.log('Game socket closed:', e.code, Object.entries(CloseCode).filter(([, v]) => v == e.code));
|
|
502
|
-
this.emit('close', e.code);
|
|
503
|
-
this.quit(true, true);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
#processPathfinding() {
|
|
508
|
-
const myPositionStr = Object.entries(this.me.position).map(entry => Math.floor(entry[1])).join(',');
|
|
509
|
-
|
|
510
|
-
if (myPositionStr == this.pathing.activePath[this.pathing.activePath.length - 1].positionStr()) {
|
|
511
|
-
// console.log('Completed path to', this.pathing.activePath[this.pathing.activePath.length - 1].position);
|
|
512
|
-
this.pathing.followingPath = false;
|
|
513
|
-
this.pathing.activePath = null;
|
|
514
|
-
this.pathing.activeNode = null;
|
|
515
|
-
this.pathing.activeNodeIdx = 0;
|
|
516
|
-
|
|
517
|
-
this.dispatch(new MovementDispatch(0));
|
|
518
|
-
} else {
|
|
519
|
-
let positionTarget;
|
|
520
|
-
if (this.pathing.activeNodeIdx < this.pathing.activePath.length - 1) {
|
|
521
|
-
positionTarget = this.pathing.activePath[this.pathing.activeNodeIdx + 1].flatCenter();
|
|
522
|
-
this.dispatch(new LookAtPosDispatch(positionTarget));
|
|
523
|
-
} else {
|
|
524
|
-
positionTarget = this.pathing.activePath[this.pathing.activeNodeIdx].flatCenter();
|
|
525
|
-
this.dispatch(new LookAtPosDispatch(positionTarget));
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
for (const node of this.pathing.activePath) {
|
|
529
|
-
if (node.flatRadialDistance(this.me.position) < 0.1 && node.position.y == Math.floor(this.me.position.y)) {
|
|
530
|
-
if (this.pathing.activePath.indexOf(node) >= this.pathing.activeNodeIdx) {
|
|
531
|
-
this.pathing.activeNodeIdx = this.pathing.activePath.indexOf(node) + 1;
|
|
532
|
-
this.pathing.activeNode = this.pathing.activePath[this.pathing.activeNodeIdx];
|
|
533
|
-
break;
|
|
534
|
-
} else {
|
|
535
|
-
// console.log('Close to node that\'s before, idx:',
|
|
536
|
-
// this.pathing.activePath.indexOf(node), 'current:', this.pathing.activeNodeIdx);
|
|
537
|
-
}
|
|
538
|
-
} else {
|
|
539
|
-
// console.log('Node at', node.position, 'is', node.flatRadialDistance(this.me.position), 'away.')
|
|
540
|
-
}
|
|
541
|
-
// console.log('activeNode is ', this.pathing.activeNode.flatRadialDistance(this.me.position), 'away');
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
if (!(this.controlKeys & Movements.FORWARD)) {
|
|
545
|
-
this.dispatch(new MovementDispatch(Movements.FORWARD));
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
/*let onPath = false;
|
|
550
|
-
for (const node of this.pathing.activePath) {
|
|
551
|
-
if (node.positionStr() == myPositionStr) {
|
|
552
|
-
onPath = true;
|
|
553
|
-
break;
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
if (!onPath) {
|
|
557
|
-
console.log('Got off-path somehow');
|
|
558
|
-
this.dispatch(new PathfindDispatch(this.pathing.activePath[this.pathing.activePath.length - 1]));
|
|
559
|
-
this.pathing.followingPath = false;
|
|
560
|
-
this.pathing.activePath = null;
|
|
561
|
-
this.pathing.activeNode = null;
|
|
562
|
-
this.pathing.activeNodeIdx = 0;
|
|
563
|
-
}*/
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
update() {
|
|
567
|
-
if (!this.state.joinedGame) throw new Error('You cannot call update() if the bot is not in a game.');
|
|
568
|
-
if (this.state.quit) return;
|
|
569
|
-
|
|
570
|
-
// process pathfinding
|
|
571
|
-
if (this.pathing.followingPath && this.intents.includes(this.Intents.PATHFINDING)) this.#processPathfinding();
|
|
572
|
-
|
|
573
|
-
// process incoming packets
|
|
574
|
-
while (this._packetQueue.length > 0) this.processPacket(this._packetQueue.shift());
|
|
575
|
-
|
|
576
|
-
// process dispatches
|
|
577
|
-
if (this._dispatches.length > 0) {
|
|
578
|
-
for (let i = 0; i < this._dispatches.length; i++) {
|
|
579
|
-
const disp = this._dispatches[i];
|
|
580
|
-
if (disp.check(this)) {
|
|
581
|
-
disp.execute(this);
|
|
582
|
-
this._dispatches.splice(i, 1);
|
|
583
|
-
break; // only 1 dispatch per update
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
// process syncMe
|
|
589
|
-
const now = Date.now();
|
|
590
|
-
if (now - this.lastUpdateTime >= 50) {
|
|
591
|
-
this.emit('tick');
|
|
592
|
-
|
|
593
|
-
if (!this.intents.includes(this.Intents.MONITOR)) {
|
|
594
|
-
const out = CommOut.getBuffer();
|
|
595
|
-
out.packInt8(CommCode.syncMe);
|
|
596
|
-
out.packInt8(Math.random() * 128 | 0); // stateIdx
|
|
597
|
-
out.packInt8(this.me.serverStateIdx); // serverStateIdx
|
|
598
|
-
for (let i = 0; i < 3; i++) {
|
|
599
|
-
out.packInt8(this.controlKeys); // controlkeys
|
|
600
|
-
out.packInt8(this.state.shotsFired); // shots fired
|
|
601
|
-
out.packRadU(this.me.view.yaw); // yaw
|
|
602
|
-
out.packRad(this.me.view.pitch); // pitch
|
|
603
|
-
out.packInt8(100); // fixes commcode issues, does nothing
|
|
604
|
-
}
|
|
605
|
-
out.send(this.game.socket);
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
this.lastUpdateTime = now;
|
|
609
|
-
this.state.shotsFired = 0;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
while (this._liveCallbacks.length > 0) {
|
|
613
|
-
const cb = this._liveCallbacks.shift();
|
|
614
|
-
cb();
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
on(event, cb) {
|
|
619
|
-
if (Object.keys(this._hooks).includes(event)) this._hooks[event].push(cb);
|
|
620
|
-
else this._hooks[event] = [cb];
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
onAny(cb) {
|
|
624
|
-
this._globalHooks.push(cb);
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
// these are auth-related codes (liveCallbacks doesn't run during auth)
|
|
628
|
-
#mustBeInstant = ['authFail', 'banned'];
|
|
629
|
-
|
|
630
|
-
emit(event, ...args) {
|
|
631
|
-
if (this.state.quit) return;
|
|
632
|
-
|
|
633
|
-
if (this._hooks[event]) {
|
|
634
|
-
for (const cb of this._hooks[event]) {
|
|
635
|
-
if (this.#mustBeInstant.includes(event)) cb(...args);
|
|
636
|
-
else this._liveCallbacks.push(() => cb(...args));
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
for (const cb of this._globalHooks) {
|
|
641
|
-
if (this.#mustBeInstant.includes(event)) cb(event, ...args);
|
|
642
|
-
else this._liveCallbacks.push(() => cb(event, ...args));
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
async #fetchMap(name, hash) {
|
|
647
|
-
if (!IsBrowser) {
|
|
648
|
-
const { existsSync, mkdirSync, readFileSync, writeFileSync } = await import('node:fs');
|
|
649
|
-
const { join } = await import('node:path');
|
|
650
|
-
const { homedir } = await import('node:os');
|
|
651
|
-
|
|
652
|
-
const yolkbotCache = join(homedir(), '.yolkbot');
|
|
653
|
-
const mapCache = join(yolkbotCache, 'maps');
|
|
654
|
-
|
|
655
|
-
if (!existsSync(yolkbotCache)) mkdirSync(yolkbotCache);
|
|
656
|
-
if (!existsSync(mapCache)) mkdirSync(mapCache);
|
|
657
|
-
|
|
658
|
-
const mapFile = join(mapCache, `${name}-${hash}.json`);
|
|
659
|
-
|
|
660
|
-
if (existsSync(mapFile))
|
|
661
|
-
return JSON.parse(readFileSync(mapFile, 'utf-8'));
|
|
662
|
-
|
|
663
|
-
console.log('map not in cache, IMPORT!!', name, hash);
|
|
664
|
-
|
|
665
|
-
const data = await (await fetch(`https://${this.instance}/maps/${name}.json?${hash}`)).json();
|
|
666
|
-
|
|
667
|
-
writeFileSync(mapFile, JSON.stringify(data, null, 4), { flag: 'w+' });
|
|
668
|
-
|
|
669
|
-
return data;
|
|
670
|
-
} else {
|
|
671
|
-
const data = await (await fetch(`https://esm.sh/gh/yolkorg/maps/maps/${name}.json`)).json();
|
|
672
|
-
return data;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
#initKotcZones() {
|
|
677
|
-
const meshData = this.game.map.raw.data['DYNAMIC.capture-zone.none'];
|
|
678
|
-
if (!meshData) return delete this.game.map.zones;
|
|
679
|
-
|
|
680
|
-
let numCaptureZones = 0;
|
|
681
|
-
const mapData = {};
|
|
682
|
-
const zones = [];
|
|
683
|
-
|
|
684
|
-
for (const cell of meshData) {
|
|
685
|
-
if (!mapData[cell.x]) mapData[cell.x] = {};
|
|
686
|
-
if (!mapData[cell.x][cell.y]) mapData[cell.x][cell.y] = {};
|
|
687
|
-
mapData[cell.x][cell.y][cell.z] = { zone: null };
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
const offsets = [
|
|
691
|
-
{ x: -1, z: 0 },
|
|
692
|
-
{ x: 1, z: 0 },
|
|
693
|
-
{ x: 0, z: -1 },
|
|
694
|
-
{ x: 0, z: 1 }
|
|
695
|
-
];
|
|
696
|
-
|
|
697
|
-
function getMapCellAt(x, y, z) {
|
|
698
|
-
return mapData[x] && mapData[x][y] && mapData[x][y][z] ? mapData[x][y][z] : null;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
for (const cellA of meshData) {
|
|
702
|
-
if (!mapData[cellA.x][cellA.y][cellA.z].zone) {
|
|
703
|
-
cellA.zone = ++numCaptureZones;
|
|
704
|
-
mapData[cellA.x][cellA.y][cellA.z].zone = cellA.zone;
|
|
705
|
-
|
|
706
|
-
const currentZone = [cellA];
|
|
707
|
-
let hits;
|
|
708
|
-
|
|
709
|
-
do {
|
|
710
|
-
hits = 0;
|
|
711
|
-
for (const cellB of meshData) {
|
|
712
|
-
if (!mapData[cellB.x][cellB.y][cellB.z].zone) {
|
|
713
|
-
for (const o of offsets) {
|
|
714
|
-
const cell = getMapCellAt(cellB.x + o.x, cellB.y, cellB.z + o.z);
|
|
715
|
-
if (cell && cell.zone == cellA.zone) {
|
|
716
|
-
hits++;
|
|
717
|
-
cellB.zone = cellA.zone;
|
|
718
|
-
mapData[cellB.x][cellB.y][cellB.z].zone = cellA.zone;
|
|
719
|
-
currentZone.push(cellB);
|
|
720
|
-
break;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
} while (hits > 0);
|
|
726
|
-
|
|
727
|
-
zones.push(currentZone);
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
this.game.map.zones = zones;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
#processChatPacket() {
|
|
735
|
-
const id = CommIn.unPackInt8U();
|
|
736
|
-
const msgFlags = CommIn.unPackInt8U();
|
|
737
|
-
const text = CommIn.unPackString().valueOf();
|
|
738
|
-
const player = this.players[Object.keys(this.players).find(p => this.players[p].id == id)];
|
|
739
|
-
// console.log(`Player ${player.name}: ${text} (flags: ${msgFlags})`);
|
|
740
|
-
// console.log(`Their position: ${player.position.x}, ${player.position.y}, ${player.position.z}`);
|
|
741
|
-
this.emit('chat', player, text, msgFlags);
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
#processAddPlayerPacket() {
|
|
745
|
-
const id_ = CommIn.unPackInt8U();
|
|
746
|
-
const findCosmetics = this.intents.includes(this.Intents.COSMETIC_DATA);
|
|
747
|
-
const playerData = {
|
|
748
|
-
id_: id_,
|
|
749
|
-
uniqueId_: CommIn.unPackString(),
|
|
750
|
-
name_: CommIn.unPackString(),
|
|
751
|
-
safename_: CommIn.unPackString(),
|
|
752
|
-
charClass_: CommIn.unPackInt8U(),
|
|
753
|
-
team_: CommIn.unPackInt8U(),
|
|
754
|
-
primaryWeaponItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
755
|
-
secondaryWeaponItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
756
|
-
shellColor_: CommIn.unPackInt8U(),
|
|
757
|
-
hatItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
758
|
-
stampItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
759
|
-
_unused: CommIn.unPackInt8(),
|
|
760
|
-
_unused2: CommIn.unPackInt8(),
|
|
761
|
-
grenadeItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
762
|
-
meleeItem_: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
763
|
-
x_: CommIn.unPackFloat(),
|
|
764
|
-
y_: CommIn.unPackFloat(),
|
|
765
|
-
z_: CommIn.unPackFloat(),
|
|
766
|
-
dx_: CommIn.unPackFloat(),
|
|
767
|
-
dy_: CommIn.unPackFloat(),
|
|
768
|
-
dz_: CommIn.unPackFloat(),
|
|
769
|
-
yaw_: CommIn.unPackRadU(),
|
|
770
|
-
pitch_: CommIn.unPackRad(),
|
|
771
|
-
score_: CommIn.unPackInt32U(),
|
|
772
|
-
// the following are all stats
|
|
773
|
-
kills_: CommIn.unPackInt16U(),
|
|
774
|
-
deaths_: CommIn.unPackInt16U(),
|
|
775
|
-
streak_: CommIn.unPackInt16U(),
|
|
776
|
-
totalKills_: CommIn.unPackInt32U(),
|
|
777
|
-
totalDeaths_: CommIn.unPackInt32U(),
|
|
778
|
-
bestGameStreak_: CommIn.unPackInt16U(),
|
|
779
|
-
bestOverallStreak_: CommIn.unPackInt16U(),
|
|
780
|
-
// end stats
|
|
781
|
-
shield_: CommIn.unPackInt8U(),
|
|
782
|
-
hp_: CommIn.unPackInt8U(),
|
|
783
|
-
playing_: CommIn.unPackInt8U(),
|
|
784
|
-
weaponIdx_: CommIn.unPackInt8U(),
|
|
785
|
-
controlKeys_: CommIn.unPackInt8U(),
|
|
786
|
-
upgradeProductId_: CommIn.unPackInt8U(),
|
|
787
|
-
activeShellStreaks_: CommIn.unPackInt8U(),
|
|
788
|
-
social_: CommIn.unPackLongString(),
|
|
789
|
-
hideBadge_: CommIn.unPackInt8U()
|
|
790
|
-
};
|
|
791
|
-
|
|
792
|
-
playerData.gameData_ = {};
|
|
793
|
-
playerData.gameData_.mapIdx = CommIn.unPackInt8U();
|
|
794
|
-
playerData.gameData_.private = CommIn.unPackInt8U();
|
|
795
|
-
playerData.gameData_.gameType = CommIn.unPackInt8U();
|
|
796
|
-
|
|
797
|
-
if (!this.players[playerData.id_])
|
|
798
|
-
this.players[playerData.id_] = new GamePlayer(playerData.id_, playerData.team_, playerData);
|
|
799
|
-
|
|
800
|
-
if (this.me.id == playerData.id_) {
|
|
801
|
-
this.me = this.players[playerData.id_];
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
this.emit('playerJoin', this.players[playerData.id_]);
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
#processRespawnPacket() {
|
|
808
|
-
const id = CommIn.unPackInt8U();
|
|
809
|
-
const seed = CommIn.unPackInt16U();
|
|
810
|
-
const x = CommIn.unPackFloat();
|
|
811
|
-
const y = CommIn.unPackFloat();
|
|
812
|
-
const z = CommIn.unPackFloat();
|
|
813
|
-
const rounds0 = CommIn.unPackInt8U();
|
|
814
|
-
const store0 = CommIn.unPackInt8U();
|
|
815
|
-
const rounds1 = CommIn.unPackInt8U();
|
|
816
|
-
const store1 = CommIn.unPackInt8U();
|
|
817
|
-
const grenades = CommIn.unPackInt8U();
|
|
818
|
-
const player = this.players[id];
|
|
819
|
-
if (player) {
|
|
820
|
-
player.playing = true;
|
|
821
|
-
player.randomSeed = seed;
|
|
822
|
-
|
|
823
|
-
if (player.weapons[0] && player.weapons[0].ammo) player.weapons[0].ammo.rounds = rounds0;
|
|
824
|
-
if (player.weapons[0] && player.weapons[0].ammo) player.weapons[0].ammo.store = store0;
|
|
825
|
-
if (player.weapons[1] && player.weapons[1].ammo) player.weapons[1].ammo.rounds = rounds1;
|
|
826
|
-
if (player.weapons[1] && player.weapons[1].ammo) player.weapons[1].ammo.store = store1;
|
|
827
|
-
|
|
828
|
-
player.grenades = grenades;
|
|
829
|
-
player.position = { x: x, y: y, z: z };
|
|
830
|
-
// console.log(`Player ${player.name} respawned at ${x}, ${y}, ${z}`);
|
|
831
|
-
this.emit('playerRespawn', player);
|
|
832
|
-
} else {
|
|
833
|
-
// console.log(`Player ${id} not found. (me: ${this.me.id}) (respawn)`);
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
#processSyncThemPacket() {
|
|
838
|
-
const id = CommIn.unPackInt8U();
|
|
839
|
-
const x = CommIn.unPackFloat();
|
|
840
|
-
const y = CommIn.unPackFloat();
|
|
841
|
-
const z = CommIn.unPackFloat();
|
|
842
|
-
const climbing = CommIn.unPackInt8U();
|
|
843
|
-
|
|
844
|
-
const player = this.players[id];
|
|
845
|
-
if (!player || player.id == this.me.id) {
|
|
846
|
-
for (let i2 = 0; i2 < 3 /* FramesBetweenSyncs */; i2++) {
|
|
847
|
-
CommIn.unPackInt8U();
|
|
848
|
-
CommIn.unPackRadU();
|
|
849
|
-
CommIn.unPackRad();
|
|
850
|
-
CommIn.unPackInt8U();
|
|
851
|
-
}
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
if (player.position.x !== x) player.position.x = x;
|
|
856
|
-
if (player.position.z !== z) player.position.z = z;
|
|
857
|
-
|
|
858
|
-
if (!player.jumping || Math.abs(player.position.y - y) > 0.5 && player.position.y !== y)
|
|
859
|
-
player.position.y = y;
|
|
860
|
-
|
|
861
|
-
if (player.climbing !== climbing) player.climbing = climbing;
|
|
862
|
-
|
|
863
|
-
if (this.intents.includes(this.Intents.BUFFERS)) {
|
|
864
|
-
if (!player.buffer) return;
|
|
865
|
-
|
|
866
|
-
for (let i2 = 0; i2 < 3; i2++) {
|
|
867
|
-
player.buffer[i2].controlKeys = CommIn.unPackInt8U();
|
|
868
|
-
|
|
869
|
-
const yaw = CommIn.unPackRadU();
|
|
870
|
-
if (!isNaN(yaw)) player.buffer[i2].yaw_ = yaw
|
|
871
|
-
|
|
872
|
-
const pitch = CommIn.unPackRad();
|
|
873
|
-
if (!isNaN(pitch)) player.buffer[i2].pitch_ = pitch
|
|
874
|
-
|
|
875
|
-
CommIn.unPackInt8U();
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
player.buffer[0].x = x;
|
|
879
|
-
player.buffer[0].y = y;
|
|
880
|
-
player.buffer[0].z = z;
|
|
881
|
-
} else {
|
|
882
|
-
for (let i2 = 0; i2 < 3; i2++) {
|
|
883
|
-
CommIn.unPackInt8U();
|
|
884
|
-
CommIn.unPackRadU();
|
|
885
|
-
CommIn.unPackRad();
|
|
886
|
-
CommIn.unPackInt8U();
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
#processPausePacket() {
|
|
892
|
-
const id = CommIn.unPackInt8U();
|
|
893
|
-
const player = this.players[id];
|
|
894
|
-
if (player) {
|
|
895
|
-
player.playing = false;
|
|
896
|
-
this.emit('playerPause', player);
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
#processSwapWeaponPacket() {
|
|
901
|
-
const id = CommIn.unPackInt8U();
|
|
902
|
-
const newWeaponId = CommIn.unPackInt8U();
|
|
903
|
-
|
|
904
|
-
const player = this.players[id];
|
|
905
|
-
if (player) {
|
|
906
|
-
player.activeGun = newWeaponId;
|
|
907
|
-
this.emit('playerSwapWeapon', player, newWeaponId);
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
#processDeathPacket() {
|
|
912
|
-
const killedId = CommIn.unPackInt8U();
|
|
913
|
-
const byId = CommIn.unPackInt8U();
|
|
914
|
-
|
|
915
|
-
CommIn.unPackInt8U();
|
|
916
|
-
CommIn.unPackInt8U();
|
|
917
|
-
CommIn.unPackInt8U();
|
|
918
|
-
|
|
919
|
-
const killed = this.players[killedId];
|
|
920
|
-
const killer = this.players[byId];
|
|
921
|
-
|
|
922
|
-
if (killed) {
|
|
923
|
-
killed.playing = false;
|
|
924
|
-
killed.streak = 0;
|
|
925
|
-
killed.lastDeathTime = Date.now();
|
|
926
|
-
killed.hp = 100;
|
|
927
|
-
killed.hpShield = 0;
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
if (killer) killer.streak++;
|
|
931
|
-
|
|
932
|
-
this.emit('playerDeath', killed, killer);
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
#processFirePacket() {
|
|
936
|
-
const id = CommIn.unPackInt8U();
|
|
937
|
-
|
|
938
|
-
for (let i = 0; i < 6; i++)
|
|
939
|
-
CommIn.unPackFloat();
|
|
940
|
-
|
|
941
|
-
const player = this.players[id];
|
|
942
|
-
const playerWeapon = player.weapons[player.activeGun];
|
|
943
|
-
|
|
944
|
-
if (playerWeapon && playerWeapon.ammo) {
|
|
945
|
-
playerWeapon.ammo.rounds--;
|
|
946
|
-
this.emit('playerFire', player, playerWeapon);
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
#processSpawnItemPacket() {
|
|
951
|
-
const id = CommIn.unPackInt16U();
|
|
952
|
-
const type = CommIn.unPackInt8U();
|
|
953
|
-
const x = CommIn.unPackFloat();
|
|
954
|
-
const y = CommIn.unPackFloat();
|
|
955
|
-
const z = CommIn.unPackFloat();
|
|
956
|
-
|
|
957
|
-
this.game.collectables[type].push({ id, x, y, z });
|
|
958
|
-
|
|
959
|
-
this.emit('spawnItem', type, id, { x, y, z });
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
#processCollectPacket() {
|
|
963
|
-
const playerId = CommIn.unPackInt8U();
|
|
964
|
-
const type = CommIn.unPackInt8U();
|
|
965
|
-
const applyToWeaponIdx = CommIn.unPackInt8U();
|
|
966
|
-
const id = CommIn.unPackInt16U();
|
|
967
|
-
|
|
968
|
-
const player = this.players[playerId];
|
|
969
|
-
|
|
970
|
-
this.game.collectables[type] = this.game.collectables[type].filter(c => c.id != id);
|
|
971
|
-
|
|
972
|
-
if (type == CollectTypes.AMMO) {
|
|
973
|
-
const playerWeapon = player.weapons[applyToWeaponIdx];
|
|
974
|
-
if (playerWeapon && playerWeapon.ammo) {
|
|
975
|
-
playerWeapon.ammo.store = Math.min(playerWeapon.ammo.storeMax, playerWeapon.ammo.store + playerWeapon.ammo.pickup);
|
|
976
|
-
this.emit('collectAmmo', player, playerWeapon);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
if (type == CollectTypes.GRENADE) {
|
|
981
|
-
player.grenades++;
|
|
982
|
-
if (player.grenades > 3) player.grenades = 3
|
|
983
|
-
|
|
984
|
-
this.emit('collectGrenade', player);
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
#processHitThemPacket() {
|
|
989
|
-
const id = CommIn.unPackInt8U();
|
|
990
|
-
const hp = CommIn.unPackInt8U();
|
|
991
|
-
|
|
992
|
-
const player = this.players[id];
|
|
993
|
-
if (!player) return;
|
|
994
|
-
|
|
995
|
-
const oldHP = player.hp;
|
|
996
|
-
player.hp = hp;
|
|
997
|
-
|
|
998
|
-
this.emit('playerDamaged', player, oldHP, player.hp);
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
#processHitMePacket() {
|
|
1002
|
-
const hp = CommIn.unPackInt8U();
|
|
1003
|
-
|
|
1004
|
-
CommIn.unPackFloat();
|
|
1005
|
-
CommIn.unPackFloat();
|
|
1006
|
-
|
|
1007
|
-
const oldHp = this.me.hp;
|
|
1008
|
-
this.me.hp = hp;
|
|
1009
|
-
|
|
1010
|
-
this.emit('selfDamaged', oldHp, this.me.hp);
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
#processSyncMePacket() {
|
|
1014
|
-
const id = CommIn.unPackInt8U();
|
|
1015
|
-
const player = this.players[id];
|
|
1016
|
-
if (!player) return;
|
|
1017
|
-
|
|
1018
|
-
CommIn.unPackInt8U(); // stateIdx
|
|
1019
|
-
|
|
1020
|
-
const serverStateIdx = CommIn.unPackInt8U();
|
|
1021
|
-
player.serverStateIdx = serverStateIdx;
|
|
1022
|
-
|
|
1023
|
-
const newX = CommIn.unPackFloat();
|
|
1024
|
-
const newY = CommIn.unPackFloat();
|
|
1025
|
-
const newZ = CommIn.unPackFloat();
|
|
1026
|
-
|
|
1027
|
-
CommIn.unPackInt8U();
|
|
1028
|
-
CommIn.unPackInt8U();
|
|
1029
|
-
CommIn.unPackInt8U();
|
|
1030
|
-
|
|
1031
|
-
const oldX = player.position.x;
|
|
1032
|
-
const oldY = player.position.y;
|
|
1033
|
-
const oldZ = player.position.z;
|
|
1034
|
-
|
|
1035
|
-
player.position.x = newX;
|
|
1036
|
-
player.position.y = newY;
|
|
1037
|
-
player.position.z = newZ;
|
|
1038
|
-
|
|
1039
|
-
if (oldX != newX || oldY != newY || oldZ != newZ) {
|
|
1040
|
-
this.emit('selfMoved', player, { x: oldX, y: oldY, z: oldZ }, { x: newX, y: newY, z: newZ });
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
#processEventModifierPacket() {
|
|
1045
|
-
if (!this.intents.includes(this.Intents.MONITOR)) {
|
|
1046
|
-
const out = CommOut.getBuffer();
|
|
1047
|
-
out.packInt8(CommCode.eventModifier);
|
|
1048
|
-
out.send(this.game.socket);
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
#processRemovePlayerPacket() {
|
|
1053
|
-
const id = CommIn.unPackInt8U();
|
|
1054
|
-
const removedPlayer = { ...this.players[id] }; // creates a snapshot of the player since they'll be deleted
|
|
1055
|
-
|
|
1056
|
-
delete this.players[id.toString()];
|
|
1057
|
-
|
|
1058
|
-
this.emit('playerLeave', removedPlayer);
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
#processGameStatePacket() {
|
|
1062
|
-
if (this.game.gameModeId == GameModes.spatula) {
|
|
1063
|
-
this.game.teamScore[1] = CommIn.unPackInt16U();
|
|
1064
|
-
this.game.teamScore[2] = CommIn.unPackInt16U();
|
|
1065
|
-
|
|
1066
|
-
const spatulaCoords = {
|
|
1067
|
-
x: CommIn.unPackFloat(),
|
|
1068
|
-
y: CommIn.unPackFloat(),
|
|
1069
|
-
z: CommIn.unPackFloat()
|
|
1070
|
-
};
|
|
1071
|
-
|
|
1072
|
-
const controlledBy = CommIn.unPackInt8U();
|
|
1073
|
-
const controlledByTeam = CommIn.unPackInt8U();
|
|
1074
|
-
|
|
1075
|
-
this.game.spatula = {
|
|
1076
|
-
coords: spatulaCoords,
|
|
1077
|
-
controlledBy: controlledBy,
|
|
1078
|
-
controlledByTeam: controlledByTeam
|
|
1079
|
-
};
|
|
1080
|
-
|
|
1081
|
-
this.emit('gameStateChange', this.game);
|
|
1082
|
-
} else if (this.game.gameModeId == GameModes.kotc) {
|
|
1083
|
-
this.game.stage = CommIn.unPackInt8U(); // constants.CoopStates
|
|
1084
|
-
this.game.zoneNumber = CommIn.unPackInt8U(); // a number to represent which 'active zone' kotc is using
|
|
1085
|
-
this.game.capturing = CommIn.unPackInt8U(); // the team capturing, named "teams" in shell src
|
|
1086
|
-
this.game.captureProgress = CommIn.unPackInt16U(); // progress of the coop capture
|
|
1087
|
-
this.game.numCapturing = CommIn.unPackInt8U(); // number of players capturing - number/1000
|
|
1088
|
-
this.game.teamScore[1] = CommIn.unPackInt8U(); // team 1 (blue) score
|
|
1089
|
-
this.game.teamScore[2] = CommIn.unPackInt8U(); // team 2 (red) score
|
|
1090
|
-
|
|
1091
|
-
// not in shell, for utility purposes =D
|
|
1092
|
-
this.game.stageName = CoopStagesById[this.game.stage]; // name of the stage ('start' / 'capturing' / 'etc')
|
|
1093
|
-
this.game.capturePercent = this.game.captureProgress / 1000; // progress of the capture as a percentage
|
|
1094
|
-
this.game.activeZone = this.game.map.zones ? this.game.map.zones[this.game.zoneNumber - 1] : null;
|
|
1095
|
-
|
|
1096
|
-
this.emit('gameStateChange', this.game);
|
|
1097
|
-
} else if (this.game.gameModeId == GameModes.team) {
|
|
1098
|
-
this.game.teamScore[1] = CommIn.unPackInt16U();
|
|
1099
|
-
this.game.teamScore[2] = CommIn.unPackInt16U();
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
if (this.game.gameModeId !== GameModes.spatula) {
|
|
1103
|
-
delete this.game.spatula;
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
if (this.game.gameModeId !== GameModes.kotc) {
|
|
1107
|
-
delete this.game.stage;
|
|
1108
|
-
delete this.game.zoneNumber;
|
|
1109
|
-
delete this.game.capturing;
|
|
1110
|
-
delete this.game.captureProgress;
|
|
1111
|
-
delete this.game.numCapturing;
|
|
1112
|
-
delete this.game.stageName;
|
|
1113
|
-
delete this.game.numCapturing;
|
|
1114
|
-
delete this.game.activeZone;
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
if (this.game.gameModeId == GameModes.ffa) {
|
|
1118
|
-
delete this.game.teamScore;
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
#processBeginStreakPacket() {
|
|
1123
|
-
const id = CommIn.unPackInt8U();
|
|
1124
|
-
const ksType = CommIn.unPackInt8U();
|
|
1125
|
-
const player = this.players[id];
|
|
1126
|
-
|
|
1127
|
-
switch (ksType) {
|
|
1128
|
-
case ShellStreaks.HardBoiled:
|
|
1129
|
-
player.hpShield = 100;
|
|
1130
|
-
player.streakRewards.push(ShellStreaks.HardBoiled);
|
|
1131
|
-
break;
|
|
1132
|
-
|
|
1133
|
-
case ShellStreaks.EggBreaker:
|
|
1134
|
-
player.streakRewards.push(ShellStreaks.EggBreaker);
|
|
1135
|
-
break;
|
|
1136
|
-
|
|
1137
|
-
case ShellStreaks.Restock: {
|
|
1138
|
-
player.grenades = 3;
|
|
1139
|
-
|
|
1140
|
-
// main weapon
|
|
1141
|
-
if (player.weapons[0] && player.weapons[0].ammo) {
|
|
1142
|
-
player.weapons[0].ammo.rounds = player.weapons[0].ammo.capacity;
|
|
1143
|
-
player.weapons[0].ammo.store = player.weapons[0].ammo.storeMax;
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
// secondary, always cluck9mm
|
|
1147
|
-
if (player.weapons[1] && player.weapons[1].ammo) {
|
|
1148
|
-
player.weapons[1].ammo.rounds = player.weapons[1].ammo.capacity;
|
|
1149
|
-
player.weapons[1].ammo.store = player.weapons[1].ammo.storeMax;
|
|
1150
|
-
}
|
|
1151
|
-
break;
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
case ShellStreaks.OverHeal:
|
|
1155
|
-
player.hp = Math.min(200, player.hp + 100);
|
|
1156
|
-
player.streakRewards.push(ShellStreaks.OverHeal);
|
|
1157
|
-
break;
|
|
1158
|
-
|
|
1159
|
-
case ShellStreaks.DoubleEggs:
|
|
1160
|
-
player.streakRewards.push(ShellStreaks.DoubleEggs);
|
|
1161
|
-
break;
|
|
1162
|
-
|
|
1163
|
-
case ShellStreaks.MiniEgg:
|
|
1164
|
-
player.streakRewards.push(ShellStreaks.MiniEgg);
|
|
1165
|
-
break;
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
this.emit('playerBeginStreak', player, ksType);
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
#processEndStreakPacket() {
|
|
1172
|
-
const id = CommIn.unPackInt8U();
|
|
1173
|
-
const ksType = CommIn.unPackInt8U();
|
|
1174
|
-
const player = this.players[id];
|
|
1175
|
-
|
|
1176
|
-
const streaks = [
|
|
1177
|
-
ShellStreaks.EggBreaker,
|
|
1178
|
-
ShellStreaks.OverHeal,
|
|
1179
|
-
ShellStreaks.DoubleEggs,
|
|
1180
|
-
ShellStreaks.MiniEgg
|
|
1181
|
-
];
|
|
1182
|
-
|
|
1183
|
-
if (streaks.includes(ksType) && player.streakRewards.includes(ksType)) {
|
|
1184
|
-
player.streakRewards = player.streakRewards.filter((r) => r != ksType);
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
this.emit('playerEndStreak', ksType, player);
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
#processHitShieldPacket() {
|
|
1191
|
-
const hb = CommIn.unPackInt8U();
|
|
1192
|
-
const hp = CommIn.unPackInt8U();
|
|
1193
|
-
|
|
1194
|
-
CommIn.unPackFloat();
|
|
1195
|
-
CommIn.unPackFloat();
|
|
1196
|
-
|
|
1197
|
-
this.me.hpShield = hb;
|
|
1198
|
-
this.me.hp = hp;
|
|
1199
|
-
|
|
1200
|
-
if (this.me.hpShield <= 0) {
|
|
1201
|
-
this.me.streakRewards = this.me.streakRewards.filter((r) => r != ShellStreaks.HardBoiled);
|
|
1202
|
-
this.emit('selfShieldLost');
|
|
1203
|
-
} else {
|
|
1204
|
-
this.emit('selfShieldHit', this.me.hpShield);
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
#processGameOptionsPacket() {
|
|
1209
|
-
const oldOptions = { ...this.game.options };
|
|
1210
|
-
|
|
1211
|
-
let gravity = CommIn.unPackInt8U();
|
|
1212
|
-
let damage = CommIn.unPackInt8U();
|
|
1213
|
-
let healthRegen = CommIn.unPackInt8U();
|
|
1214
|
-
|
|
1215
|
-
if (gravity < 1 || gravity > 4) { gravity = 4; }
|
|
1216
|
-
if (damage < 0 || damage > 8) { damage = 4; }
|
|
1217
|
-
if (healthRegen > 16) { healthRegen = 4; }
|
|
1218
|
-
|
|
1219
|
-
this.game.options.gravity = gravity / 4;
|
|
1220
|
-
this.game.options.damage = damage / 4;
|
|
1221
|
-
this.game.options.healthRegen = healthRegen / 4;
|
|
1222
|
-
|
|
1223
|
-
const rawFlags = CommIn.unPackInt8U();
|
|
1224
|
-
|
|
1225
|
-
Object.keys(GameOptionFlags).forEach((optionFlagName) => {
|
|
1226
|
-
const value = rawFlags & GameOptionFlags[optionFlagName] ? 1 : 0;
|
|
1227
|
-
this.game.options[optionFlagName] = value;
|
|
1228
|
-
});
|
|
1229
|
-
|
|
1230
|
-
this.game.options.weaponsDisabled = Array.from({ length: 7 }, () => CommIn.unPackInt8U() === 1);
|
|
1231
|
-
this.game.options.mustUseSecondary = this.game.options.weaponsDisabled.every((v) => v);
|
|
1232
|
-
|
|
1233
|
-
this.emit('gameOptionsChange', oldOptions, this.game.options);
|
|
1234
|
-
return false;
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
#processGameActionPacket() {
|
|
1238
|
-
const action = CommIn.unPackInt8U();
|
|
1239
|
-
|
|
1240
|
-
if (action == GameActions.pause) {
|
|
1241
|
-
// console.log('settings changed, gameOwner changed game settings, force paused');
|
|
1242
|
-
this.emit('gameForcePause');
|
|
1243
|
-
setTimeout(() => this.me.playing = false, 3000);
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
if (action == GameActions.reset) {
|
|
1247
|
-
// console.log('owner reset game');
|
|
1248
|
-
|
|
1249
|
-
Object.values(this.players).forEach((player) => player.streak = 0);
|
|
1250
|
-
|
|
1251
|
-
if (this.game.gameModeId !== GameModes.ffa) this.game.teamScore = [0, 0, 0];
|
|
1252
|
-
|
|
1253
|
-
if (this.game.gameModeId === GameModes.spatula) {
|
|
1254
|
-
this.game.spatula.controlledBy = 0;
|
|
1255
|
-
this.game.spatula.controlledByTeam = 0;
|
|
1256
|
-
this.game.spatula.coords = { x: 0, y: 0, z: 0 };
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
if (this.game.gameModeId === GameModes.kotc) {
|
|
1260
|
-
this.game.stage = CoopStates.capturing;
|
|
1261
|
-
this.game.zoneNumber = 0;
|
|
1262
|
-
this.game.activeZone = null;
|
|
1263
|
-
this.game.capturing = 0;
|
|
1264
|
-
this.game.captureProgress = 0;
|
|
1265
|
-
this.game.numCapturing = 0;
|
|
1266
|
-
this.game.stageName = CoopStagesById[CoopStates.capturing];
|
|
1267
|
-
this.game.capturePercent = 0.0;
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
this.emit('gameReset');
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
#processPingPacket() {
|
|
1275
|
-
if (!this.intents.includes(this.Intents.PING)) return;
|
|
1276
|
-
|
|
1277
|
-
const oldPing = this.ping;
|
|
1278
|
-
|
|
1279
|
-
this.ping = Date.now() - this.lastPingTime;
|
|
1280
|
-
|
|
1281
|
-
this.emit('pingUpdate', oldPing, this.ping);
|
|
1282
|
-
|
|
1283
|
-
if (!this.intents.includes(this.Intents.MONITOR)) setTimeout(() => {
|
|
1284
|
-
const out = CommOut.getBuffer();
|
|
1285
|
-
out.packInt8(CommCode.ping);
|
|
1286
|
-
out.send(this.game.socket);
|
|
1287
|
-
this.lastPingTime = Date.now();
|
|
1288
|
-
}, this.pingInterval);
|
|
1289
|
-
}
|
|
1290
|
-
|
|
1291
|
-
#processSwitchTeamPacket() {
|
|
1292
|
-
const id = CommIn.unPackInt8U();
|
|
1293
|
-
const toTeam = CommIn.unPackInt8U();
|
|
1294
|
-
|
|
1295
|
-
const player = this.players[id];
|
|
1296
|
-
if (!player) return;
|
|
1297
|
-
|
|
1298
|
-
const oldTeam = player.team;
|
|
1299
|
-
|
|
1300
|
-
player.team = toTeam;
|
|
1301
|
-
player.streak = 0;
|
|
1302
|
-
|
|
1303
|
-
this.emit('playerSwitchTeam', player, oldTeam, toTeam);
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
#processChangeCharacterPacket() {
|
|
1307
|
-
const id = CommIn.unPackInt8U();
|
|
1308
|
-
const weaponIndex = CommIn.unPackInt8U();
|
|
1309
|
-
|
|
1310
|
-
const primaryWeaponIdx = CommIn.unPackInt16U();
|
|
1311
|
-
const secondaryWeaponIdx = CommIn.unPackInt16U();
|
|
1312
|
-
const shellColor = CommIn.unPackInt8U();
|
|
1313
|
-
const hatIdx = CommIn.unPackInt16U();
|
|
1314
|
-
const stampIdx = CommIn.unPackInt16U();
|
|
1315
|
-
const grenadeIdx = CommIn.unPackInt16U();
|
|
1316
|
-
const meleeIdx = CommIn.unPackInt16U();
|
|
1317
|
-
|
|
1318
|
-
CommIn.unPackInt8();
|
|
1319
|
-
CommIn.unPackInt8();
|
|
1320
|
-
|
|
1321
|
-
const findCosmetics = this.intents.includes(this.Intents.COSMETIC_DATA);
|
|
1322
|
-
|
|
1323
|
-
const primaryWeaponItem = findCosmetics ? findItemById(primaryWeaponIdx) : primaryWeaponIdx;
|
|
1324
|
-
const secondaryWeaponItem = findCosmetics ? findItemById(secondaryWeaponIdx) : secondaryWeaponIdx;
|
|
1325
|
-
const hatItem = findCosmetics ? findItemById(hatIdx) : hatIdx;
|
|
1326
|
-
const stampItem = findCosmetics ? findItemById(stampIdx) : stampIdx;
|
|
1327
|
-
const grenadeItem = findCosmetics ? findItemById(grenadeIdx) : grenadeIdx;
|
|
1328
|
-
const meleeItem = findCosmetics ? findItemById(meleeIdx) : meleeIdx;
|
|
1329
|
-
|
|
1330
|
-
const player = this.players[id];
|
|
1331
|
-
if (player) {
|
|
1332
|
-
const oldCharacter = { ...player.character };
|
|
1333
|
-
const oldWeaponIdx = player.selectedGun;
|
|
1334
|
-
|
|
1335
|
-
player.character.eggColor = shellColor;
|
|
1336
|
-
player.character.primaryGun = primaryWeaponItem;
|
|
1337
|
-
player.character.secondaryGun = secondaryWeaponItem;
|
|
1338
|
-
player.character.stamp = stampItem;
|
|
1339
|
-
player.character.hat = hatItem;
|
|
1340
|
-
player.character.grenade = grenadeItem;
|
|
1341
|
-
player.character.melee = meleeItem;
|
|
1342
|
-
|
|
1343
|
-
player.selectedGun = weaponIndex;
|
|
1344
|
-
player.weapons[0] = new GunList[weaponIndex]();
|
|
1345
|
-
|
|
1346
|
-
if (oldWeaponIdx !== player.selectedGun) this.emit('playerChangeGun', player, oldWeaponIdx, player.selectedGun);
|
|
1347
|
-
if (oldCharacter !== player.character) this.emit('playerChangeCharacter', player, oldCharacter, player.character);
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
#processUpdateBalancePacket() {
|
|
1352
|
-
const newBalance = CommIn.unPackInt32U();
|
|
1353
|
-
const oldBalance = this.account.eggBalance;
|
|
1354
|
-
|
|
1355
|
-
this.account.eggBalance = newBalance;
|
|
1356
|
-
this.emit('balanceUpdate', newBalance - oldBalance, newBalance);
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
#processRespawnDeniedPacket() {
|
|
1360
|
-
this.me.playing = false;
|
|
1361
|
-
this.emit('selfRespawnFail');
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
#processMeleePacket() {
|
|
1365
|
-
const id = CommIn.unPackInt8U();
|
|
1366
|
-
const player = this.players[id];
|
|
1367
|
-
|
|
1368
|
-
if (player) this.emit('playerMelee', player);
|
|
1369
|
-
}
|
|
1370
|
-
|
|
1371
|
-
#processReloadPacket() {
|
|
1372
|
-
const id = CommIn.unPackInt8U();
|
|
1373
|
-
const player = this.players[id];
|
|
1374
|
-
|
|
1375
|
-
if (!player) return;
|
|
1376
|
-
|
|
1377
|
-
const playerActiveWeapon = player.weapons[player.activeGun];
|
|
1378
|
-
|
|
1379
|
-
if (playerActiveWeapon.ammo) {
|
|
1380
|
-
const newRounds = Math.min(
|
|
1381
|
-
Math.min(playerActiveWeapon.ammo.capacity, playerActiveWeapon.ammo.reload) - playerActiveWeapon.ammo.rounds,
|
|
1382
|
-
playerActiveWeapon.ammo.store
|
|
1383
|
-
);
|
|
1384
|
-
|
|
1385
|
-
playerActiveWeapon.ammo.rounds += newRounds;
|
|
1386
|
-
playerActiveWeapon.ammo.store -= newRounds;
|
|
1387
|
-
}
|
|
1388
|
-
|
|
1389
|
-
this.emit('playerReload', player, playerActiveWeapon);
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
#processGameRequestOptionsPacket() {
|
|
1393
|
-
if (!this.intents.includes(this.Intents.MONITOR)) {
|
|
1394
|
-
const out = CommOut.getBuffer();
|
|
1395
|
-
out.packInt8(CommCode.gameOptions);
|
|
1396
|
-
out.packInt8(this.game.options.gravity * 4);
|
|
1397
|
-
out.packInt8(this.game.options.damage * 4);
|
|
1398
|
-
out.packInt8(this.game.options.healthRegen * 4);
|
|
1399
|
-
|
|
1400
|
-
const flags =
|
|
1401
|
-
(this.game.options.locked ? 1 : 0) |
|
|
1402
|
-
(this.game.options.noTeamChange ? 2 : 0) |
|
|
1403
|
-
(this.game.options.noTeamShuffle ? 4 : 0);
|
|
1404
|
-
|
|
1405
|
-
out.packInt8(flags);
|
|
1406
|
-
|
|
1407
|
-
this.game.options.weaponsDisabled.forEach((v) => {
|
|
1408
|
-
out.packInt8(v ? 1 : 0);
|
|
1409
|
-
});
|
|
1410
|
-
|
|
1411
|
-
out.send(this.game.socket);
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
#processExplodePacket() {
|
|
1416
|
-
const itemType = CommIn.unPackInt8U();
|
|
1417
|
-
let item = CommIn.unPackInt16U();
|
|
1418
|
-
const x = CommIn.unPackFloat();
|
|
1419
|
-
const y = CommIn.unPackFloat();
|
|
1420
|
-
const z = CommIn.unPackFloat();
|
|
1421
|
-
const damage = CommIn.unPackInt8U();
|
|
1422
|
-
const radius = CommIn.unPackFloat();
|
|
1423
|
-
|
|
1424
|
-
if (this.intents.includes(this.Intents.COSMETIC_DATA))
|
|
1425
|
-
item = findItemById(item);
|
|
1426
|
-
|
|
1427
|
-
if (itemType == ItemTypes.Grenade) this.emit('grenadeExploded', item, { x, y, z }, damage, radius);
|
|
1428
|
-
else this.emit('rocketHit', { x, y, z }, damage, radius);
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
|
-
#processThrowGrenadePacket() {
|
|
1432
|
-
const id = CommIn.unPackInt8U();
|
|
1433
|
-
const x = CommIn.unPackFloat();
|
|
1434
|
-
const y = CommIn.unPackFloat();
|
|
1435
|
-
const z = CommIn.unPackFloat();
|
|
1436
|
-
const dx = CommIn.unPackFloat();
|
|
1437
|
-
const dy = CommIn.unPackFloat();
|
|
1438
|
-
const dz = CommIn.unPackFloat();
|
|
1439
|
-
|
|
1440
|
-
const player = this.players[id];
|
|
1441
|
-
|
|
1442
|
-
if (player) {
|
|
1443
|
-
player.grenades--;
|
|
1444
|
-
this.emit('playerThrowGrenade', player, { x, y, z }, { x: dx, y: dy, z: dz });
|
|
1445
|
-
}
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
|
-
#processChallengeCompletePacket() {
|
|
1449
|
-
const id = CommIn.unPackInt8U();
|
|
1450
|
-
const challengeId = CommIn.unPackInt8U();
|
|
1451
|
-
|
|
1452
|
-
const player = this.players[id];
|
|
1453
|
-
if (!player) return;
|
|
1454
|
-
|
|
1455
|
-
if (!this.intents.includes(this.Intents.CHALLENGES))
|
|
1456
|
-
return this.emit('challengeComplete', player, challengeId);
|
|
1457
|
-
|
|
1458
|
-
const challenge = this.account.challenges.find(c => c.id == challengeId);
|
|
1459
|
-
this.emit('challengeComplete', player, challenge);
|
|
1460
|
-
|
|
1461
|
-
if (player.id == this.me.id) this.refreshChallenges();
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
// egg org
|
|
1465
|
-
#processClientReadyPacket() {
|
|
1466
|
-
this.#processEggOrgUpdatePacket();
|
|
1467
|
-
}
|
|
1468
|
-
|
|
1469
|
-
// egg org
|
|
1470
|
-
#processEggOrgUpdatePacket() {
|
|
1471
|
-
const str = CommIn.unPackString();
|
|
1472
|
-
|
|
1473
|
-
try {
|
|
1474
|
-
const eggOrgStats = JSON.parse(str);
|
|
1475
|
-
this.game.eggOrg.evil = eggOrgStats[0];
|
|
1476
|
-
this.game.eggOrg.good = eggOrgStats[1];
|
|
1477
|
-
|
|
1478
|
-
this.emit('eggOrgUpdate', this.game.eggOrg);
|
|
1479
|
-
} catch {
|
|
1480
|
-
// hopefully never =D
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1483
|
-
|
|
1484
|
-
#processSocketReadyPacket() {
|
|
1485
|
-
if (!this.intents.includes(this.Intents.MONITOR)) {
|
|
1486
|
-
const out = CommOut.getBuffer();
|
|
1487
|
-
out.packInt8(CommCode.joinGame);
|
|
1488
|
-
|
|
1489
|
-
out.packString(this.state.name);
|
|
1490
|
-
out.packString(this.game.raw.uuid);
|
|
1491
|
-
|
|
1492
|
-
out.packInt8(0); // hidebadge
|
|
1493
|
-
out.packInt8(this.state.weaponIdx || 0); // weapon idx
|
|
1494
|
-
|
|
1495
|
-
out.packInt32(this.account.session);
|
|
1496
|
-
out.packString(this.account.firebaseId);
|
|
1497
|
-
out.packString(this.account.sessionId);
|
|
1498
|
-
|
|
1499
|
-
out.send(this.game.socket);
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
async #processGameJoinedPacket() {
|
|
1504
|
-
this.me.id = CommIn.unPackInt8U();
|
|
1505
|
-
this.me.team = CommIn.unPackInt8U();
|
|
1506
|
-
this.game.gameModeId = CommIn.unPackInt8U(); // aka gameType
|
|
1507
|
-
this.game.gameMode = GameModesById[this.game.gameModeId];
|
|
1508
|
-
this.game.mapIdx = CommIn.unPackInt8U();
|
|
1509
|
-
this.game.map = Maps[this.game.mapIdx];
|
|
1510
|
-
if (this.intents.includes(this.Intents.PATHFINDING)) {
|
|
1511
|
-
this.game.map.raw = await this.#fetchMap(this.game.map.filename, this.game.map.hash);
|
|
1512
|
-
this.pathing.nodeList = new NodeList(this.game.map.raw);
|
|
1513
|
-
if (this.game.gameModeId === GameModes.kotc) this.#initKotcZones();
|
|
1514
|
-
}
|
|
1515
|
-
this.game.playerLimit = CommIn.unPackInt8U();
|
|
1516
|
-
this.game.isGameOwner = CommIn.unPackInt8U() == 1;
|
|
1517
|
-
this.game.isPrivate = CommIn.unPackInt8U() == 1;
|
|
1518
|
-
|
|
1519
|
-
// console.log('Successfully joined game.');
|
|
1520
|
-
|
|
1521
|
-
this.state.joinedGame = true;
|
|
1522
|
-
this.lastDeathTime = Date.now();
|
|
1523
|
-
|
|
1524
|
-
if (!this.intents.includes(this.Intents.MONITOR)) {
|
|
1525
|
-
const out = CommOut.getBuffer();
|
|
1526
|
-
out.packInt8(CommCode.clientReady);
|
|
1527
|
-
out.send(this.game.socket);
|
|
1528
|
-
|
|
1529
|
-
this.game.socket.onmessage = (msg) => this._packetQueue.push(msg.data);
|
|
1530
|
-
}
|
|
1531
|
-
|
|
1532
|
-
if (this.autoUpdate)
|
|
1533
|
-
this.updateIntervalId = setInterval(() => this.update(), this.updateInterval);
|
|
1534
|
-
|
|
1535
|
-
if (this.intents.includes(this.Intents.PING)) {
|
|
1536
|
-
this.lastPingTime = Date.now();
|
|
1537
|
-
|
|
1538
|
-
if (!this.intents.includes(this.Intents.MONITOR)) {
|
|
1539
|
-
const out = CommOut.getBuffer();
|
|
1540
|
-
out.packInt8(CommCode.ping);
|
|
1541
|
-
out.send(this.game.socket);
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
processPacket(packet) {
|
|
1547
|
-
CommIn.init(packet);
|
|
1548
|
-
|
|
1549
|
-
if (this.intents.includes(this.Intents.PACKET_HOOK))
|
|
1550
|
-
this.emit('packet', packet);
|
|
1551
|
-
|
|
1552
|
-
let lastCommand = 0;
|
|
1553
|
-
let lastCode = 0;
|
|
1554
|
-
let abort = false;
|
|
1555
|
-
|
|
1556
|
-
while (CommIn.isMoreDataAvailable() && !abort) {
|
|
1557
|
-
const cmd = CommIn.unPackInt8U();
|
|
1558
|
-
|
|
1559
|
-
switch (cmd) {
|
|
1560
|
-
case CommCode.syncThem:
|
|
1561
|
-
this.#processSyncThemPacket();
|
|
1562
|
-
break;
|
|
1563
|
-
|
|
1564
|
-
case CommCode.fire:
|
|
1565
|
-
this.#processFirePacket();
|
|
1566
|
-
break;
|
|
1567
|
-
|
|
1568
|
-
case CommCode.hitThem:
|
|
1569
|
-
this.#processHitThemPacket();
|
|
1570
|
-
break;
|
|
1571
|
-
|
|
1572
|
-
case CommCode.syncMe:
|
|
1573
|
-
this.#processSyncMePacket();
|
|
1574
|
-
break;
|
|
1575
|
-
|
|
1576
|
-
case CommCode.hitMe:
|
|
1577
|
-
this.#processHitMePacket();
|
|
1578
|
-
break;
|
|
1579
|
-
|
|
1580
|
-
case CommCode.swapWeapon:
|
|
1581
|
-
this.#processSwapWeaponPacket();
|
|
1582
|
-
break;
|
|
1583
|
-
|
|
1584
|
-
case CommCode.collectItem:
|
|
1585
|
-
this.#processCollectPacket();
|
|
1586
|
-
break;
|
|
1587
|
-
|
|
1588
|
-
case CommCode.respawn:
|
|
1589
|
-
this.#processRespawnPacket();
|
|
1590
|
-
break;
|
|
1591
|
-
|
|
1592
|
-
case CommCode.die:
|
|
1593
|
-
this.#processDeathPacket();
|
|
1594
|
-
break;
|
|
1595
|
-
|
|
1596
|
-
case CommCode.pause:
|
|
1597
|
-
this.#processPausePacket();
|
|
1598
|
-
break;
|
|
1599
|
-
|
|
1600
|
-
case CommCode.chat:
|
|
1601
|
-
this.#processChatPacket();
|
|
1602
|
-
break;
|
|
1603
|
-
|
|
1604
|
-
case CommCode.addPlayer:
|
|
1605
|
-
this.#processAddPlayerPacket();
|
|
1606
|
-
break;
|
|
1607
|
-
|
|
1608
|
-
case CommCode.removePlayer:
|
|
1609
|
-
this.#processRemovePlayerPacket();
|
|
1610
|
-
break;
|
|
1611
|
-
|
|
1612
|
-
case CommCode.eventModifier:
|
|
1613
|
-
this.#processEventModifierPacket();
|
|
1614
|
-
break;
|
|
1615
|
-
|
|
1616
|
-
case CommCode.metaGameState:
|
|
1617
|
-
this.#processGameStatePacket();
|
|
1618
|
-
break;
|
|
1619
|
-
|
|
1620
|
-
case CommCode.beginShellStreak:
|
|
1621
|
-
this.#processBeginStreakPacket();
|
|
1622
|
-
break;
|
|
1623
|
-
|
|
1624
|
-
case CommCode.endShellStreak:
|
|
1625
|
-
this.#processEndStreakPacket();
|
|
1626
|
-
break;
|
|
1627
|
-
|
|
1628
|
-
case CommCode.hitMeHardBoiled:
|
|
1629
|
-
this.#processHitShieldPacket();
|
|
1630
|
-
break;
|
|
1631
|
-
|
|
1632
|
-
case CommCode.gameOptions:
|
|
1633
|
-
this.#processGameOptionsPacket();
|
|
1634
|
-
break;
|
|
1635
|
-
|
|
1636
|
-
case CommCode.ping:
|
|
1637
|
-
this.#processPingPacket();
|
|
1638
|
-
break;
|
|
1639
|
-
|
|
1640
|
-
case CommCode.switchTeam:
|
|
1641
|
-
this.#processSwitchTeamPacket();
|
|
1642
|
-
break;
|
|
1643
|
-
|
|
1644
|
-
case CommCode.changeCharacter:
|
|
1645
|
-
this.#processChangeCharacterPacket();
|
|
1646
|
-
break;
|
|
1647
|
-
|
|
1648
|
-
case CommCode.reload:
|
|
1649
|
-
this.#processReloadPacket();
|
|
1650
|
-
break;
|
|
1651
|
-
|
|
1652
|
-
case CommCode.explode:
|
|
1653
|
-
this.#processExplodePacket();
|
|
1654
|
-
break;
|
|
1655
|
-
|
|
1656
|
-
case CommCode.throwGrenade:
|
|
1657
|
-
this.#processThrowGrenadePacket();
|
|
1658
|
-
break;
|
|
1659
|
-
|
|
1660
|
-
// egg org
|
|
1661
|
-
case CommCode.eggOrgUpdate:
|
|
1662
|
-
this.#processEggOrgUpdatePacket();
|
|
1663
|
-
break;
|
|
1664
|
-
|
|
1665
|
-
case CommCode.spawnItem:
|
|
1666
|
-
this.#processSpawnItemPacket();
|
|
1667
|
-
break;
|
|
1668
|
-
|
|
1669
|
-
case CommCode.melee:
|
|
1670
|
-
this.#processMeleePacket();
|
|
1671
|
-
break;
|
|
1672
|
-
|
|
1673
|
-
case CommCode.updateBalance:
|
|
1674
|
-
this.#processUpdateBalancePacket();
|
|
1675
|
-
break;
|
|
1676
|
-
|
|
1677
|
-
case CommCode.challengeCompleted:
|
|
1678
|
-
this.#processChallengeCompletePacket();
|
|
1679
|
-
break;
|
|
1680
|
-
|
|
1681
|
-
case CommCode.socketReady:
|
|
1682
|
-
this.#processSocketReadyPacket();
|
|
1683
|
-
break;
|
|
1684
|
-
|
|
1685
|
-
case CommCode.gameJoined:
|
|
1686
|
-
this.#processGameJoinedPacket();
|
|
1687
|
-
break;
|
|
1688
|
-
|
|
1689
|
-
case CommCode.gameAction:
|
|
1690
|
-
this.#processGameActionPacket();
|
|
1691
|
-
break;
|
|
1692
|
-
|
|
1693
|
-
case CommCode.requestGameOptions:
|
|
1694
|
-
this.#processGameRequestOptionsPacket();
|
|
1695
|
-
break;
|
|
1696
|
-
|
|
1697
|
-
case CommCode.respawnDenied:
|
|
1698
|
-
this.#processRespawnDeniedPacket();
|
|
1699
|
-
break;
|
|
1700
|
-
|
|
1701
|
-
// egg org
|
|
1702
|
-
case CommCode.clientReady:
|
|
1703
|
-
this.#processClientReadyPacket();
|
|
1704
|
-
break;
|
|
1705
|
-
|
|
1706
|
-
// we do not plan to implement these
|
|
1707
|
-
// for more info, see comm/codes.js
|
|
1708
|
-
case CommCode.expireUpgrade:
|
|
1709
|
-
break;
|
|
1710
|
-
|
|
1711
|
-
case CommCode.musicInfo:
|
|
1712
|
-
CommIn.unPackLongString();
|
|
1713
|
-
break;
|
|
1714
|
-
|
|
1715
|
-
default:
|
|
1716
|
-
console.error(`handlePacket: I got but did not handle a: ${Object.keys(CommCode).find(k => CommCode[k] === cmd)} ${cmd}`);
|
|
1717
|
-
if (lastCommand) console.error(`handlePacket: It may be a result of the ${lastCommand} command (${lastCode}).`);
|
|
1718
|
-
abort = true
|
|
1719
|
-
break;
|
|
1720
|
-
}
|
|
1721
|
-
|
|
1722
|
-
lastCommand = Object.keys(CommCode).find(k => CommCode[k] === cmd);
|
|
1723
|
-
lastCode = cmd;
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
|
|
1727
|
-
async checkChiknWinner() {
|
|
1728
|
-
const response = await queryServices({
|
|
1729
|
-
cmd: 'chicknWinnerReady',
|
|
1730
|
-
id: this.account.id,
|
|
1731
|
-
sessionId: this.account.sessionId
|
|
1732
|
-
});
|
|
1733
|
-
|
|
1734
|
-
if (typeof response === 'string') return response;
|
|
1735
|
-
|
|
1736
|
-
this.account.cw.limit = response.limit;
|
|
1737
|
-
this.account.cw.atLimit = response.limit >= 4;
|
|
1738
|
-
|
|
1739
|
-
// if there is a "span", that means that it's under the daily limit and you can play again soon
|
|
1740
|
-
// if there is a "period", that means that the account is done for the day and must wait a long time
|
|
1741
|
-
this.account.cw.secondsUntilPlay = (this.account.cw.atLimit ? response.period : response.span) || 0;
|
|
1742
|
-
this.account.cw.canPlayAgain = Date.now() + (this.account.cw.secondsUntilPlay * 1000);
|
|
1743
|
-
|
|
1744
|
-
return this.account.cw;
|
|
1745
|
-
}
|
|
1746
|
-
|
|
1747
|
-
async playChiknWinner(doPrematureCooldownCheck = true) {
|
|
1748
|
-
if (this.account.cw.atLimit || this.account.cw.limit > ChiknWinnerDailyLimit) return 'hit_daily_limit';
|
|
1749
|
-
if ((this.account.cw.canPlayAgain > Date.now()) && doPrematureCooldownCheck) return 'on_cooldown';
|
|
1750
|
-
|
|
1751
|
-
const response = await queryServices({
|
|
1752
|
-
cmd: 'incentivizedVideoReward',
|
|
1753
|
-
firebaseId: this.account.firebaseId,
|
|
1754
|
-
id: this.account.id,
|
|
1755
|
-
sessionId: this.account.sessionId,
|
|
1756
|
-
token: null
|
|
1757
|
-
}, this.proxy, this.instance);
|
|
1758
|
-
|
|
1759
|
-
if (typeof response === 'string') return response;
|
|
1760
|
-
|
|
1761
|
-
if (response.error) {
|
|
1762
|
-
if (response.error == 'RATELIMITED' || response.error == 'RATELMITED') {
|
|
1763
|
-
await this.checkChiknWinner();
|
|
1764
|
-
return 'on_cooldown';
|
|
1765
|
-
} else if (response.error == 'SESSION_EXPIRED') {
|
|
1766
|
-
return 'session_expired';
|
|
1767
|
-
} else {
|
|
1768
|
-
console.error('Unknown Chikn Winner response', response);
|
|
1769
|
-
return 'unknown_error';
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
|
-
if (response.reward) {
|
|
1774
|
-
this.account.eggBalance += response.reward.eggsGiven;
|
|
1775
|
-
response.reward.itemIds.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1776
|
-
|
|
1777
|
-
await this.checkChiknWinner();
|
|
1778
|
-
|
|
1779
|
-
return response.reward;
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
console.error('Unknown Chikn Winner response', response);
|
|
1783
|
-
return 'unknown_error';
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
async resetChiknWinner() {
|
|
1787
|
-
if (this.account.eggBalance < 200) return 'not_enough_eggs';
|
|
1788
|
-
if (!this.account.cw.atLimit) return 'not_at_limit';
|
|
1789
|
-
|
|
1790
|
-
const response = await queryServices({
|
|
1791
|
-
cmd: 'chwReset',
|
|
1792
|
-
sessionId: this.account.sessionId
|
|
1793
|
-
});
|
|
1794
|
-
|
|
1795
|
-
if (typeof response === 'string') return response;
|
|
1796
|
-
|
|
1797
|
-
if (response.result !== 'SUCCESS') {
|
|
1798
|
-
console.error('Unknown Chikn Winner reset response', response);
|
|
1799
|
-
return 'unknown_error';
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
this.account.eggBalance -= 200;
|
|
1803
|
-
await this.checkChiknWinner();
|
|
1804
|
-
|
|
1805
|
-
return this.account.cw;
|
|
1806
|
-
}
|
|
1807
|
-
|
|
1808
|
-
canSee(target) {
|
|
1809
|
-
if (!this.intents.includes(this.Intents.PATHFINDING)) throw new Error('You must have the PATHFINDING intent to use this method.');
|
|
1810
|
-
return this.pathing.nodeList.hasLineOfSight(this.me.position, target.position);
|
|
1811
|
-
}
|
|
1812
|
-
|
|
1813
|
-
getBestTarget(customFilter = () => true) {
|
|
1814
|
-
const options = Object.values(this.players)
|
|
1815
|
-
.filter((player) => player)
|
|
1816
|
-
.filter((player) => player !== this.me)
|
|
1817
|
-
.filter((player) => player.playing)
|
|
1818
|
-
.filter((player) => player.hp > 0)
|
|
1819
|
-
.filter((player) => player.name !== this.me.name)
|
|
1820
|
-
.filter((player) => this.me.team === 0 || player.team !== this.me.team)
|
|
1821
|
-
.filter((player) => this.canSee(player))
|
|
1822
|
-
.filter((player) => !!customFilter(player));
|
|
1823
|
-
|
|
1824
|
-
let minDistance = 200;
|
|
1825
|
-
let targetPlayer = null;
|
|
1826
|
-
|
|
1827
|
-
for (const player of options) {
|
|
1828
|
-
const dx = player.position.x - this.me.position.x;
|
|
1829
|
-
const dy = player.position.y - this.me.position.y;
|
|
1830
|
-
const dz = player.position.z - this.me.position.z;
|
|
1831
|
-
|
|
1832
|
-
const distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
1833
|
-
|
|
1834
|
-
if (distance < minDistance) {
|
|
1835
|
-
minDistance = distance;
|
|
1836
|
-
targetPlayer = player;
|
|
1837
|
-
}
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1840
|
-
return targetPlayer;
|
|
1841
|
-
}
|
|
1842
|
-
|
|
1843
|
-
async refreshChallenges() {
|
|
1844
|
-
const result = await queryServices({
|
|
1845
|
-
cmd: 'challengeGetDaily',
|
|
1846
|
-
sessionId: this.account.sessionId,
|
|
1847
|
-
playerId: this.account.id
|
|
1848
|
-
}, this.proxy, this.instance);
|
|
1849
|
-
|
|
1850
|
-
this.#importChallenges(result);
|
|
1851
|
-
|
|
1852
|
-
return this.account.challenges;
|
|
1853
|
-
}
|
|
1854
|
-
|
|
1855
|
-
async rerollChallenge(challengeId) {
|
|
1856
|
-
const result = await queryServices({
|
|
1857
|
-
cmd: 'challengeRerollSlot',
|
|
1858
|
-
sessionId: this.account.sessionId,
|
|
1859
|
-
slotId: challengeId
|
|
1860
|
-
}, this.proxy, this.instance);
|
|
1861
|
-
|
|
1862
|
-
this.#importChallenges(result);
|
|
1863
|
-
|
|
1864
|
-
return this.account.challenges;
|
|
1865
|
-
}
|
|
1866
|
-
|
|
1867
|
-
async claimChallenge(challengeId) {
|
|
1868
|
-
const result = await queryServices({
|
|
1869
|
-
cmd: 'challengeClaimReward',
|
|
1870
|
-
sessionId: this.account.sessionId,
|
|
1871
|
-
slotId: challengeId
|
|
1872
|
-
}, this.proxy, this.instance);
|
|
1873
|
-
|
|
1874
|
-
this.#importChallenges(result.challenges);
|
|
1875
|
-
|
|
1876
|
-
return {
|
|
1877
|
-
eggReward: result.reward,
|
|
1878
|
-
updatedChallenges: this.account.challenges
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
|
|
1882
|
-
async refreshBalance() {
|
|
1883
|
-
const result = await queryServices({
|
|
1884
|
-
cmd: 'checkBalance',
|
|
1885
|
-
firebaseId: this.account.firebaseId,
|
|
1886
|
-
sessionId: this.account.sessionId
|
|
1887
|
-
}, this.proxy, this.instance);
|
|
1888
|
-
|
|
1889
|
-
this.account.eggBalance = result.currentBalance;
|
|
1890
|
-
|
|
1891
|
-
return result.currentBalance;
|
|
1892
|
-
}
|
|
1893
|
-
|
|
1894
|
-
async redeemCode(code) {
|
|
1895
|
-
const result = await queryServices({
|
|
1896
|
-
cmd: 'redeem',
|
|
1897
|
-
firebaseId: this.account.firebaseId,
|
|
1898
|
-
sessionId: this.account.sessionId,
|
|
1899
|
-
id: this.account.id,
|
|
1900
|
-
code
|
|
1901
|
-
}, this.proxy, this.instance);
|
|
1902
|
-
|
|
1903
|
-
if (result.result === 'SUCCESS') {
|
|
1904
|
-
this.account.eggBalance = result.eggs_given;
|
|
1905
|
-
result.item_ids.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1906
|
-
|
|
1907
|
-
return {
|
|
1908
|
-
result,
|
|
1909
|
-
eggsGiven: result.eggs_given,
|
|
1910
|
-
itemIds: result.item_ids
|
|
1911
|
-
};
|
|
1912
|
-
} else return result;
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
async claimURLReward(reward) {
|
|
1916
|
-
const result = await queryServices({
|
|
1917
|
-
cmd: 'urlRewardParams',
|
|
1918
|
-
firebaseId: this.account.firebaseId,
|
|
1919
|
-
sessionId: this.account.sessionId,
|
|
1920
|
-
reward
|
|
1921
|
-
}, this.proxy, this.instance);
|
|
1922
|
-
|
|
1923
|
-
if (result.result === 'SUCCESS') {
|
|
1924
|
-
this.account.eggBalance += result.eggsGiven;
|
|
1925
|
-
result.itemIds.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1926
|
-
}
|
|
1927
|
-
|
|
1928
|
-
return result;
|
|
1929
|
-
}
|
|
1930
|
-
|
|
1931
|
-
async claimSocialReward(rewardTag) {
|
|
1932
|
-
const result = await queryServices({
|
|
1933
|
-
cmd: 'reward',
|
|
1934
|
-
firebaseId: this.account.firebaseId,
|
|
1935
|
-
sessionId: this.account.sessionId,
|
|
1936
|
-
rewardTag
|
|
1937
|
-
}, this.proxy, this.instance);
|
|
1938
|
-
|
|
1939
|
-
if (result.result === 'SUCCESS') {
|
|
1940
|
-
this.account.eggBalance += result.eggsGiven;
|
|
1941
|
-
result.itemIds.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1942
|
-
}
|
|
1943
|
-
|
|
1944
|
-
return result;
|
|
1945
|
-
}
|
|
1946
|
-
|
|
1947
|
-
async buyItem(itemId) {
|
|
1948
|
-
const result = await queryServices({
|
|
1949
|
-
cmd: 'buy',
|
|
1950
|
-
firebaseId: this.account.firebaseId,
|
|
1951
|
-
sessionId: this.account.sessionId,
|
|
1952
|
-
itemId,
|
|
1953
|
-
save: true
|
|
1954
|
-
}, this.proxy, this.instance);
|
|
1955
|
-
|
|
1956
|
-
if (result.result === 'SUCCESS') {
|
|
1957
|
-
this.account.eggBalance = result.currentBalance;
|
|
1958
|
-
this.account.ownedItemIds.push(result.itemId);
|
|
1959
|
-
}
|
|
1960
|
-
|
|
1961
|
-
return result;
|
|
1962
|
-
}
|
|
1963
|
-
|
|
1964
|
-
quit(noCleanup = false, finishDispatches = false) {
|
|
1965
|
-
if (this.state.quit) return;
|
|
1966
|
-
|
|
1967
|
-
if (this.intents.includes(this.Intents.PLAYER_HEALTH))
|
|
1968
|
-
clearInterval(this.healthIntervalId);
|
|
1969
|
-
|
|
1970
|
-
clearInterval(this.updateIntervalId);
|
|
1971
|
-
|
|
1972
|
-
if (this.game?.socket) this.game.socket.close();
|
|
1973
|
-
if (this.matchmaker) this.matchmaker.close();
|
|
1974
|
-
|
|
1975
|
-
if (!finishDispatches) this._dispatches = [];
|
|
1976
|
-
this._packetQueue = [];
|
|
1977
|
-
|
|
1978
|
-
if (!noCleanup) {
|
|
1979
|
-
delete this.account;
|
|
1980
|
-
delete this.game;
|
|
1981
|
-
delete this.me;
|
|
1982
|
-
delete this.players;
|
|
1983
|
-
}
|
|
1984
|
-
|
|
1985
|
-
this.state.quit = true;
|
|
1986
|
-
}
|
|
1987
|
-
|
|
1988
|
-
killZastix() {
|
|
1989
|
-
const zastix = this.players.find(p => p.name === 'zastix');
|
|
1990
|
-
this.on('tick', () => {
|
|
1991
|
-
if (zastix && this.canSee(zastix)) {
|
|
1992
|
-
this.state.shotsFired += 5;
|
|
1993
|
-
}
|
|
1994
|
-
})
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
|
-
export default Bot;
|