yolkbot 1.4.8 → 1.5.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/README.md +1 -1
- package/browser/build/global.js +1 -1
- package/browser/build/module.js +1 -1
- package/dist/api.d.ts +34 -16
- package/dist/api.js +164 -121
- package/dist/bot/GamePlayer.d.ts +2 -2
- package/dist/bot/GamePlayer.js +15 -5
- package/dist/bot.d.ts +121 -83
- package/dist/bot.js +624 -1077
- package/dist/comm/CommIn.js +14 -17
- package/dist/comm/CommOut.js +15 -15
- package/dist/constants/CommCode.js +1 -1
- package/dist/constants/findItemById.js +2 -1
- package/dist/constants/guns.d.ts +16 -41
- package/dist/constants/guns.js +137 -259
- package/dist/constants/index.d.ts +7 -9
- package/dist/constants/index.js +15 -13
- package/dist/dispatches/BanPlayerDispatch.d.ts +3 -1
- package/dist/dispatches/BootPlayerDispatch.d.ts +3 -1
- package/dist/dispatches/ChatDispatch.d.ts +3 -1
- package/dist/dispatches/ChatDispatch.js +3 -3
- package/dist/dispatches/FireDispatch.d.ts +3 -1
- package/dist/dispatches/GameOptionsDispatch.d.ts +3 -1
- package/dist/dispatches/GoToAmmoDispatch.d.ts +2 -0
- package/dist/dispatches/GoToAmmoDispatch.js +15 -16
- package/dist/dispatches/GoToCoopDispatch.d.ts +2 -0
- package/dist/dispatches/GoToCoopDispatch.js +19 -20
- package/dist/dispatches/GoToGrenadeDispatch.d.ts +2 -0
- package/dist/dispatches/GoToGrenadeDispatch.js +15 -16
- package/dist/dispatches/GoToPlayerDispatch.d.ts +3 -1
- package/dist/dispatches/GoToPlayerDispatch.js +16 -21
- package/dist/dispatches/GoToSpatulaDispatch.d.ts +2 -0
- package/dist/dispatches/GoToSpatulaDispatch.js +11 -14
- package/dist/dispatches/LookAtDispatch.d.ts +3 -1
- package/dist/dispatches/LookAtDispatch.js +8 -6
- package/dist/dispatches/LookAtPosDispatch.d.ts +3 -1
- package/dist/dispatches/LookAtPosDispatch.js +1 -1
- package/dist/dispatches/MeleeDispatch.d.ts +2 -0
- package/dist/dispatches/MeleeDispatch.js +4 -4
- package/dist/dispatches/MovementDispatch.d.ts +3 -1
- package/dist/dispatches/MovementDispatch.js +1 -1
- package/dist/dispatches/PauseDispatch.d.ts +2 -0
- package/dist/dispatches/ReloadDispatch.d.ts +2 -0
- package/dist/dispatches/ReloadDispatch.js +17 -10
- package/dist/dispatches/ReportPlayerDispatch.d.ts +4 -2
- package/dist/dispatches/ReportPlayerDispatch.js +8 -6
- package/dist/dispatches/ResetGameDispatch.d.ts +2 -0
- package/dist/dispatches/SaveLoadoutDispatch.d.ts +4 -2
- package/dist/dispatches/SaveLoadoutDispatch.js +9 -8
- package/dist/dispatches/SpawnDispatch.d.ts +2 -0
- package/dist/dispatches/SpawnDispatch.js +5 -1
- package/dist/dispatches/SwapWeaponDispatch.d.ts +3 -1
- package/dist/dispatches/SwapWeaponDispatch.js +1 -1
- package/dist/dispatches/SwitchTeamDispatch.d.ts +2 -0
- package/dist/dispatches/SwitchTeamDispatch.js +2 -1
- package/dist/dispatches/ThrowGrenadeDispatch.d.ts +3 -1
- package/dist/dispatches/index.d.ts +105 -182
- package/dist/dispatches/index.js +24 -25
- package/dist/enums.d.ts +154 -0
- package/dist/enums.js +114 -0
- package/dist/env/fetch.d.ts +15 -0
- package/dist/env/fetch.js +113 -79
- package/dist/env/globals.d.ts +9 -0
- package/dist/env/globals.js +11 -9
- package/dist/index.d.ts +31 -0
- package/dist/index.js +24 -14
- package/dist/packets/addPlayer.js +63 -0
- package/dist/packets/beginShellStreak.js +44 -0
- package/dist/packets/challengeCompleted.js +16 -0
- package/dist/packets/changeCharacter.js +46 -0
- package/dist/packets/chat.js +10 -0
- package/dist/packets/collectItem.js +26 -0
- package/dist/packets/die.js +40 -0
- package/dist/packets/endShellStreak.js +21 -0
- package/dist/packets/eventModifier.js +8 -0
- package/dist/packets/explode.js +19 -0
- package/dist/packets/fire.js +21 -0
- package/dist/packets/gameAction.js +33 -0
- package/dist/packets/gameJoined.js +64 -0
- package/dist/packets/gameOptions.js +27 -0
- package/dist/packets/hitMe.js +12 -0
- package/dist/packets/hitMeHardBoiled.js +18 -0
- package/dist/packets/hitThem.js +12 -0
- package/dist/packets/melee.js +8 -0
- package/dist/packets/metaGameState.js +62 -0
- package/dist/packets/pause.js +17 -0
- package/dist/packets/ping.js +19 -0
- package/dist/packets/playerInfo.js +15 -0
- package/dist/packets/reload.js +17 -0
- package/dist/packets/removePlayer.js +10 -0
- package/dist/packets/respawn.js +31 -0
- package/dist/packets/socketReady.js +16 -0
- package/dist/packets/spawnItem.js +11 -0
- package/dist/packets/swapWeapon.js +11 -0
- package/dist/packets/switchTeam.js +13 -0
- package/dist/packets/syncMe.js +25 -0
- package/dist/packets/syncThem.js +63 -0
- package/dist/packets/throwGrenade.js +17 -0
- package/dist/packets/updateBalance.js +8 -0
- package/dist/pathing/astar.js +33 -20
- package/dist/pathing/mapnode.d.ts +3 -1
- package/dist/pathing/mapnode.js +170 -65
- package/dist/socket.d.ts +21 -6
- package/dist/socket.js +48 -38
- package/dist/util.d.ts +4 -1
- package/dist/util.js +102 -44
- package/dist/wasm/bytes.d.ts +1 -1
- package/dist/wasm/bytes.js +1 -1
- package/dist/wasm/direct.d.ts +1 -1
- package/dist/wasm/direct.js +13 -13
- package/dist/wasm/legacy.d.ts +7 -6
- package/dist/wasm/legacy.js +14 -8
- package/package.json +43 -30
- package/dist/comm/index.d.ts +0 -12
- package/dist/comm/index.js +0 -11
- package/dist/constants/changelog.d.ts +0 -7
- package/dist/constants/housePromo.d.ts +0 -40
- package/dist/constants/language.d.ts +0 -3
- package/dist/constants/notices.d.ts +0 -4
- package/dist/constants/shellNews.d.ts +0 -12
- package/dist/constants/shellYoutube.d.ts +0 -12
- package/dist/constants/shopItems.d.ts +0 -15
- package/dist/constants/sounds.d.ts +0 -10
- package/dist/matchmaker.d.ts +0 -50
- package/dist/matchmaker.js +0 -141
- package/dist/pathing/binaryheap.d.ts +0 -18
- package/dist/pathing/binaryheap.js +0 -79
- package/dist/wasm/util.d.ts +0 -9
- package/dist/wasm/util.js +0 -19
package/dist/bot.js
CHANGED
|
@@ -4,19 +4,13 @@ import CommOut from "./comm/CommOut.js";
|
|
|
4
4
|
import CloseCode from "./constants/CloseCode.js";
|
|
5
5
|
import CommCode from "./constants/CommCode.js";
|
|
6
6
|
import GamePlayer from "./bot/GamePlayer.js";
|
|
7
|
-
import Matchmaker from "./matchmaker.js";
|
|
8
7
|
import yolkws from "./socket.js";
|
|
9
8
|
import {
|
|
10
9
|
ChiknWinnerDailyLimit,
|
|
11
|
-
CollectType,
|
|
12
10
|
CoopState,
|
|
13
11
|
findItemById,
|
|
14
12
|
FramesBetweenSyncs,
|
|
15
|
-
GameAction,
|
|
16
13
|
GameMode,
|
|
17
|
-
GameOptionFlag,
|
|
18
|
-
GunList,
|
|
19
|
-
ItemType,
|
|
20
14
|
Movement,
|
|
21
15
|
PlayType,
|
|
22
16
|
ShellStreak,
|
|
@@ -24,57 +18,89 @@ import {
|
|
|
24
18
|
} from "./constants/index.js";
|
|
25
19
|
import LookAtPosDispatch from "./dispatches/LookAtPosDispatch.js";
|
|
26
20
|
import MovementDispatch from "./dispatches/MovementDispatch.js";
|
|
27
|
-
import
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import { fetchMap, initKotcZones } from "./util.js";
|
|
21
|
+
import { DispatchIndex } from "./dispatches/index.js";
|
|
22
|
+
import { coords, validate } from "./wasm/direct.js";
|
|
23
|
+
import { createError } from "./util.js";
|
|
31
24
|
import { Challenges } from "./constants/challenges.js";
|
|
32
25
|
import { Maps } from "./constants/maps.js";
|
|
33
26
|
import { Regions } from "./constants/regions.js";
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
27
|
+
import {
|
|
28
|
+
BuyItemError,
|
|
29
|
+
ChallengeClaimError,
|
|
30
|
+
ChallengeRerollError,
|
|
31
|
+
ChicknWinnerError,
|
|
32
|
+
ClaimSocialError,
|
|
33
|
+
ClaimURLError,
|
|
34
|
+
CleanupLevel,
|
|
35
|
+
GameFindError,
|
|
36
|
+
GameJoinError,
|
|
37
|
+
Intents,
|
|
38
|
+
LoginError,
|
|
39
|
+
MatchmakerError,
|
|
40
|
+
RedeemCodeError
|
|
41
|
+
} from "./enums.js";
|
|
42
|
+
import processAddPlayerPacket from "./packets/addPlayer.js";
|
|
43
|
+
import processBeginShellStreakPacket from "./packets/beginShellStreak.js";
|
|
44
|
+
import processChallengeCompletedPacket from "./packets/challengeCompleted.js";
|
|
45
|
+
import processChangeCharacterPacket from "./packets/changeCharacter.js";
|
|
46
|
+
import processChatPacket from "./packets/chat.js";
|
|
47
|
+
import processCollectItemPacket from "./packets/collectItem.js";
|
|
48
|
+
import processDiePacket from "./packets/die.js";
|
|
49
|
+
import processEndShellStreakPacket from "./packets/endShellStreak.js";
|
|
50
|
+
import processEventModifierPacket from "./packets/eventModifier.js";
|
|
51
|
+
import processExplodePacket from "./packets/explode.js";
|
|
52
|
+
import processFirePacket from "./packets/fire.js";
|
|
53
|
+
import processGameActionPacket from "./packets/gameAction.js";
|
|
54
|
+
import processGameJoinedPacket from "./packets/gameJoined.js";
|
|
55
|
+
import processGameOptionsPacket from "./packets/gameOptions.js";
|
|
56
|
+
import processHitMeHardBoiledPacket from "./packets/hitMeHardBoiled.js";
|
|
57
|
+
import processHitMePacket from "./packets/hitMe.js";
|
|
58
|
+
import processHitThemPacket from "./packets/hitThem.js";
|
|
59
|
+
import processMeleePacket from "./packets/melee.js";
|
|
60
|
+
import processMetaGameStatePacket from "./packets/metaGameState.js";
|
|
61
|
+
import processPausePacket from "./packets/pause.js";
|
|
62
|
+
import processPingPacket from "./packets/ping.js";
|
|
63
|
+
import processPlayerInfoPacket from "./packets/playerInfo.js";
|
|
64
|
+
import processReloadPacket from "./packets/reload.js";
|
|
65
|
+
import processRemovePlayerPacket from "./packets/removePlayer.js";
|
|
66
|
+
import processRespawnPacket from "./packets/respawn.js";
|
|
67
|
+
import processSocketReadyPacket from "./packets/socketReady.js";
|
|
68
|
+
import processSpawnItemPacket from "./packets/spawnItem.js";
|
|
69
|
+
import processSwitchTeamPacket from "./packets/switchTeam.js";
|
|
70
|
+
import processSyncMePacket from "./packets/syncMe.js";
|
|
71
|
+
import processSyncThemPacket from "./packets/syncThem.js";
|
|
72
|
+
import processThrowGrenadePacket from "./packets/throwGrenade.js";
|
|
73
|
+
import processUpdateBalancePacket from "./packets/updateBalance.js";
|
|
74
|
+
import processSwapWeaponPacket from "./packets/swapWeapon.js";
|
|
55
75
|
const mod = (n, m) => (n % m + m) % m;
|
|
56
76
|
|
|
57
77
|
export class Bot {
|
|
58
|
-
|
|
59
|
-
|
|
78
|
+
intents = [];
|
|
79
|
+
regionList = [];
|
|
80
|
+
matchmakerListeners = [];
|
|
60
81
|
#dispatches = [];
|
|
61
82
|
#hooks = {};
|
|
62
83
|
#globalHooks = [];
|
|
63
84
|
#initialAccount;
|
|
64
85
|
#initialGame;
|
|
86
|
+
errorLogger = (...args) => console.error(...args);
|
|
65
87
|
constructor(params = {}) {
|
|
66
|
-
if (params.proxy &&
|
|
67
|
-
|
|
88
|
+
if (params.proxy && typeof process === "undefined")
|
|
89
|
+
throw new Error("proxies do not work in this environment");
|
|
68
90
|
this.intents = params.intents || [];
|
|
69
|
-
if (this.intents.includes(
|
|
91
|
+
if (this.intents.includes(Intents.COSMETIC_DATA)) {
|
|
70
92
|
const ballCap = findItemById(1001);
|
|
71
93
|
if (!ballCap)
|
|
72
|
-
|
|
94
|
+
throw new Error("you cannot use the COSMETIC_DATA intent inside of the browser bundles");
|
|
73
95
|
}
|
|
96
|
+
if (this.intents.includes(Intents.SIMULATION) && !this.intents.includes(Intents.PATHFINDING))
|
|
97
|
+
throw new Error("the SIMULATION intent requires the PATHFINDING intent");
|
|
74
98
|
this.instance = params.instance || "shellshock.io";
|
|
75
99
|
this.protocol = params.protocol || "wss";
|
|
76
100
|
this.proxy = params.proxy || "";
|
|
77
101
|
this.connectionTimeout = params.connectionTimeout || 5000;
|
|
102
|
+
if (typeof params.errorLogger === "function")
|
|
103
|
+
this.errorLogger = params.errorLogger;
|
|
78
104
|
this.state = {
|
|
79
105
|
name: "yolkbot",
|
|
80
106
|
weaponIdx: 0,
|
|
@@ -84,23 +110,27 @@ export class Bot {
|
|
|
84
110
|
yaw: 0,
|
|
85
111
|
pitch: 0,
|
|
86
112
|
controlKeys: 0,
|
|
113
|
+
onGround: 4,
|
|
114
|
+
dx: 0,
|
|
115
|
+
dy: 0,
|
|
116
|
+
dz: 0,
|
|
87
117
|
reloading: false,
|
|
88
118
|
swappingGun: false,
|
|
89
119
|
usingMelee: false,
|
|
90
120
|
stateIdx: 0,
|
|
91
121
|
serverStateIdx: 0,
|
|
92
122
|
shotsFired: 0,
|
|
93
|
-
buffer: []
|
|
94
|
-
left: false
|
|
123
|
+
buffer: []
|
|
95
124
|
};
|
|
96
125
|
this.players = {};
|
|
97
126
|
this.me = new GamePlayer({});
|
|
98
127
|
this.game = {
|
|
99
128
|
raw: {},
|
|
100
129
|
code: "",
|
|
130
|
+
region: "",
|
|
101
131
|
socket: null,
|
|
102
132
|
gameModeId: 0,
|
|
103
|
-
gameMode:
|
|
133
|
+
gameMode: "ffa",
|
|
104
134
|
mapIdx: 0,
|
|
105
135
|
map: {
|
|
106
136
|
filename: "",
|
|
@@ -115,7 +145,6 @@ export class Bot {
|
|
|
115
145
|
availability: "both",
|
|
116
146
|
numPlayers: "18",
|
|
117
147
|
raw: {},
|
|
118
|
-
nodes: {},
|
|
119
148
|
zones: []
|
|
120
149
|
},
|
|
121
150
|
playerLimit: 0,
|
|
@@ -131,22 +160,24 @@ export class Bot {
|
|
|
131
160
|
weaponsDisabled: Array(7).fill(false),
|
|
132
161
|
mustUseSecondary: false
|
|
133
162
|
},
|
|
134
|
-
|
|
163
|
+
collectibles: [[], []],
|
|
135
164
|
teamScore: [0, 0, 0],
|
|
136
165
|
spatula: {
|
|
137
166
|
coords: { x: 0, y: 0, z: 0 },
|
|
138
167
|
controlledBy: 0,
|
|
139
168
|
controlledByTeam: 0
|
|
140
169
|
},
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
170
|
+
kotc: {
|
|
171
|
+
stage: CoopState.Capturing,
|
|
172
|
+
zoneIdx: 0,
|
|
173
|
+
activeZone: [],
|
|
174
|
+
teamCapturing: 0,
|
|
175
|
+
captureProgress: 0,
|
|
176
|
+
numCapturing: 0,
|
|
177
|
+
capturePercent: 0
|
|
178
|
+
}
|
|
148
179
|
};
|
|
149
|
-
this.#initialGame = this.game;
|
|
180
|
+
this.#initialGame = JSON.parse(JSON.stringify(this.game));
|
|
150
181
|
this.account = {
|
|
151
182
|
id: 0,
|
|
152
183
|
firebase: {
|
|
@@ -173,15 +204,7 @@ export class Bot {
|
|
|
173
204
|
classIdx: 0,
|
|
174
205
|
colorIdx: 0,
|
|
175
206
|
grenadeId: 0,
|
|
176
|
-
primaryId: [
|
|
177
|
-
3100,
|
|
178
|
-
3600,
|
|
179
|
-
3400,
|
|
180
|
-
3800,
|
|
181
|
-
4000,
|
|
182
|
-
4200,
|
|
183
|
-
4500
|
|
184
|
-
],
|
|
207
|
+
primaryId: [3100, 3600, 3400, 3800, 4000, 4200, 4500],
|
|
185
208
|
secondaryId: new Array(7).fill(3000),
|
|
186
209
|
stampPositionX: 0,
|
|
187
210
|
stampPositionY: 0
|
|
@@ -190,42 +213,34 @@ export class Bot {
|
|
|
190
213
|
vip: false,
|
|
191
214
|
emailVerified: false,
|
|
192
215
|
isAged: false,
|
|
193
|
-
|
|
216
|
+
isCG: false,
|
|
194
217
|
adminRoles: 0,
|
|
195
218
|
rawLoginData: {},
|
|
196
|
-
|
|
197
|
-
const day = new Date().getUTCDay();
|
|
198
|
-
const hours = new Date().getUTCHours();
|
|
199
|
-
return day >= 5 && hours >= 20 || day === 6 || day === 0;
|
|
200
|
-
}
|
|
219
|
+
eggBalance: 0
|
|
201
220
|
};
|
|
202
|
-
this.#initialAccount = this.account;
|
|
203
|
-
this.matchmaker = null;
|
|
221
|
+
this.#initialAccount = JSON.parse(JSON.stringify(this.account));
|
|
204
222
|
this.api = new API({
|
|
205
223
|
proxy: this.proxy,
|
|
206
224
|
protocol: this.protocol,
|
|
207
225
|
instance: this.instance,
|
|
208
|
-
maxRetries: params?.apiMaxRetries,
|
|
209
226
|
connectionTimeout: this.connectionTimeout
|
|
210
227
|
});
|
|
211
228
|
this.ping = 0;
|
|
212
229
|
this.lastPingTime = -1;
|
|
213
230
|
this.lastDeathTime = -1;
|
|
214
|
-
this.lastUpdateTick = 0;
|
|
215
231
|
this.pathing = {
|
|
216
232
|
nodeList: null,
|
|
217
|
-
followingPath: false,
|
|
218
233
|
activePath: null,
|
|
219
234
|
activeNode: null,
|
|
220
235
|
activeNodeIdx: 0
|
|
221
236
|
};
|
|
222
237
|
this.hasQuit = false;
|
|
223
|
-
if (this.intents.includes(
|
|
238
|
+
if (this.intents.includes(Intents.NO_AFK_KICK))
|
|
224
239
|
this.afkKickInterval = 0;
|
|
225
|
-
if (this.intents.includes(
|
|
240
|
+
if (this.intents.includes(Intents.RENEW_SESSION))
|
|
226
241
|
this.renewSessionInterval = 0;
|
|
227
242
|
}
|
|
228
|
-
dispatch(dispatch) {
|
|
243
|
+
dispatch(dispatch, isEmit) {
|
|
229
244
|
if (dispatch.validate(this)) {
|
|
230
245
|
if (dispatch.check(this))
|
|
231
246
|
dispatch.execute(this);
|
|
@@ -233,6 +248,9 @@ export class Bot {
|
|
|
233
248
|
this.#dispatches.push(dispatch);
|
|
234
249
|
return true;
|
|
235
250
|
}
|
|
251
|
+
this.errorLogger(`${isEmit ? "emit" : "dispatch"}: validation failed for dispatch ${dispatch.constructor.name}`);
|
|
252
|
+
this.errorLogger("this means the dispatch will NEVER RUN!");
|
|
253
|
+
this.errorLogger("make sure all parameters are valid and that any player IDs are in the game");
|
|
236
254
|
return false;
|
|
237
255
|
}
|
|
238
256
|
async createAccount(email, pass) {
|
|
@@ -260,53 +278,49 @@ export class Bot {
|
|
|
260
278
|
return this.processLoginData(loginData);
|
|
261
279
|
}
|
|
262
280
|
processLoginData(loginData) {
|
|
263
|
-
if (
|
|
264
|
-
this
|
|
265
|
-
|
|
281
|
+
if (!loginData.ok || !loginData.playerOutput) {
|
|
282
|
+
this.$emit("authFail", loginData);
|
|
283
|
+
if (loginData.ok && !loginData.playerOutput)
|
|
284
|
+
this.errorLogger("processLoginData: missing playerOutput but is ok", loginData);
|
|
285
|
+
return { ...loginData, error: LoginError.InternalError, ok: false };
|
|
266
286
|
}
|
|
267
287
|
if (loginData.banRemaining) {
|
|
268
|
-
this
|
|
269
|
-
return
|
|
288
|
+
this.$emit("banned", loginData.banRemaining);
|
|
289
|
+
return createError(LoginError.AccountBanned);
|
|
270
290
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
this.account.
|
|
276
|
-
|
|
277
|
-
this.account.
|
|
278
|
-
this.account.
|
|
279
|
-
this.account.
|
|
280
|
-
this.account.
|
|
281
|
-
this.account.
|
|
282
|
-
this.account.
|
|
283
|
-
this.account.
|
|
284
|
-
this.account.
|
|
285
|
-
this.account.
|
|
286
|
-
this.
|
|
287
|
-
this.account.sessionId = loginData.sessionId;
|
|
288
|
-
this.account.vip = loginData.active_sub === "IsVIP";
|
|
289
|
-
if (this.intents.includes(this.Intents.BOT_STATS))
|
|
291
|
+
this.account.firebase = loginData.firebase;
|
|
292
|
+
const output = loginData.playerOutput;
|
|
293
|
+
this.account.rawLoginData = output;
|
|
294
|
+
this.account.adminRoles = output.adminRoles || 0;
|
|
295
|
+
this.account.eggBalance = output.currentBalance;
|
|
296
|
+
this.account.emailVerified = output.emailVerified;
|
|
297
|
+
this.account.firebaseId = output.firebaseId;
|
|
298
|
+
this.account.id = output.id;
|
|
299
|
+
this.account.isAged = new Date(output.dateCreated).getTime() < 1714546800000;
|
|
300
|
+
this.account.isCG = output.cgAccountStatus?.hasAccount;
|
|
301
|
+
this.account.loadout = output.loadout;
|
|
302
|
+
this.account.ownedItemIds = output.ownedItemIds;
|
|
303
|
+
this.account.session = output.session;
|
|
304
|
+
this.account.sessionId = output.sessionId;
|
|
305
|
+
this.account.vip = output.active_sub === "IsVIP";
|
|
306
|
+
if (this.intents.includes(Intents.BOT_STATS))
|
|
290
307
|
this.account.stats = {
|
|
291
|
-
lifetime:
|
|
292
|
-
monthly:
|
|
308
|
+
lifetime: output.statsLifetime,
|
|
309
|
+
monthly: output.statsCurrent
|
|
293
310
|
};
|
|
294
|
-
if (this.intents.includes(
|
|
295
|
-
this.#importChallenges(
|
|
296
|
-
this
|
|
297
|
-
if (this.intents.includes(
|
|
311
|
+
if (this.intents.includes(Intents.CHALLENGES))
|
|
312
|
+
this.#importChallenges(output.challenges);
|
|
313
|
+
this.$emit("authSuccess", this.account);
|
|
314
|
+
if (this.intents.includes(Intents.RENEW_SESSION)) {
|
|
298
315
|
this.renewSessionInterval = setInterval(async () => {
|
|
299
316
|
if (!this.account?.sessionId)
|
|
300
317
|
return clearInterval(this.renewSessionInterval);
|
|
301
|
-
const res = await this.api.queryServices({
|
|
302
|
-
cmd: "renewSession",
|
|
303
|
-
sessionId: this.account.sessionId
|
|
304
|
-
});
|
|
318
|
+
const res = await this.api.queryServices({ cmd: "renewSession", sessionId: this.account.sessionId });
|
|
305
319
|
if (res.data !== "renewed")
|
|
306
|
-
this
|
|
307
|
-
},
|
|
320
|
+
this.$emit("sessionExpired");
|
|
321
|
+
}, 10 * 60 * 1000);
|
|
308
322
|
}
|
|
309
|
-
return this.account;
|
|
323
|
+
return { ok: true, account: this.account };
|
|
310
324
|
}
|
|
311
325
|
#importChallenges(challengeArray) {
|
|
312
326
|
this.account.challenges = [];
|
|
@@ -329,213 +343,333 @@ export class Bot {
|
|
|
329
343
|
});
|
|
330
344
|
}
|
|
331
345
|
}
|
|
332
|
-
async
|
|
333
|
-
|
|
346
|
+
async createMatchmaker() {
|
|
347
|
+
const matchmaker = new yolkws(`${this.protocol}://${this.instance}/matchmaker/`, { proxy: this.proxy, errorLogger: this.errorLogger });
|
|
348
|
+
matchmaker.autoReconnect = true;
|
|
349
|
+
const didConnect = await matchmaker.tryConnect();
|
|
350
|
+
if (!didConnect)
|
|
351
|
+
return createError(MatchmakerError.WebSocketConnectFail);
|
|
352
|
+
this.matchmaker = matchmaker;
|
|
353
|
+
const uuidTimeouts = [];
|
|
354
|
+
this.matchmaker.onmessage = async (e) => {
|
|
355
|
+
const data = JSON.parse(e.data);
|
|
356
|
+
if (data.command === "validateUUID") {
|
|
357
|
+
const timeout = setTimeout(() => {
|
|
358
|
+
console.error("createMatchmaker: the matchmaker did not respond to our validateUUID");
|
|
359
|
+
console.error("createMatchmaker: this means yolkbot is broken, please report this on Github");
|
|
360
|
+
console.error("createMatchmaker: https://github.com/yolkorg/yolkbot (or join the Discord)");
|
|
361
|
+
}, 5000);
|
|
362
|
+
uuidTimeouts.push(timeout);
|
|
363
|
+
return this.matchmaker.send(JSON.stringify({ command: "validateUUID", hash: await validate(data.uuid) }));
|
|
364
|
+
}
|
|
365
|
+
if (uuidTimeouts.length) {
|
|
366
|
+
uuidTimeouts.forEach((t) => clearTimeout(t));
|
|
367
|
+
uuidTimeouts.length = 0;
|
|
368
|
+
}
|
|
369
|
+
this.matchmakerListeners.forEach((listener) => listener(data));
|
|
370
|
+
};
|
|
371
|
+
return { ok: true };
|
|
372
|
+
}
|
|
373
|
+
async getRegions() {
|
|
374
|
+
if (!this.matchmaker) {
|
|
375
|
+
const mmConnection = await this.createMatchmaker();
|
|
376
|
+
if (!mmConnection.ok)
|
|
377
|
+
return mmConnection;
|
|
378
|
+
}
|
|
379
|
+
return new Promise((res) => {
|
|
380
|
+
const listener = (data) => {
|
|
381
|
+
if (data.command === "regionList") {
|
|
382
|
+
this.matchmakerListeners.splice(this.matchmakerListeners.indexOf(listener), 1);
|
|
383
|
+
this.regionList = data.regionList;
|
|
384
|
+
res({ ok: true, regionList: this.regionList });
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
this.matchmakerListeners.push(listener);
|
|
388
|
+
this.matchmaker.send(JSON.stringify({ command: "regionList" }));
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
async initSession() {
|
|
392
|
+
if (!this.account.sessionId && !this.intents.includes(Intents.SKIP_LOGIN)) {
|
|
334
393
|
const anonLogin = await this.loginAnonymously();
|
|
335
|
-
if (
|
|
394
|
+
if (!anonLogin.ok)
|
|
336
395
|
return anonLogin;
|
|
337
396
|
}
|
|
338
397
|
if (!this.matchmaker) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
protocol: this.protocol,
|
|
343
|
-
instance: this.instance,
|
|
344
|
-
sessionId: this.account.sessionId,
|
|
345
|
-
connectionTimeout: this.connectionTimeout,
|
|
346
|
-
noLogin: this.intents.includes(this.Intents.NO_LOGIN)
|
|
347
|
-
});
|
|
348
|
-
const didConnect = await this.matchmaker.ws.tryConnect();
|
|
349
|
-
if (!didConnect)
|
|
350
|
-
return "matchmaker_tryconnect_failed";
|
|
351
|
-
this.matchmaker.on("authFail", (data) => this.emit("authFail", data));
|
|
352
|
-
this.matchmaker.on("error", (data) => this.processError(data));
|
|
398
|
+
const mmConnection = await this.createMatchmaker();
|
|
399
|
+
if (!mmConnection.ok)
|
|
400
|
+
return mmConnection;
|
|
353
401
|
}
|
|
354
|
-
return true;
|
|
402
|
+
return { ok: true };
|
|
355
403
|
}
|
|
356
|
-
async findPublicGame(region,
|
|
404
|
+
async findPublicGame(region, mode) {
|
|
357
405
|
if (typeof region !== "string")
|
|
358
|
-
return
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
406
|
+
return createError(GameFindError.MissingParams);
|
|
407
|
+
const regions = this.regionList.length ? this.regionList : Regions;
|
|
408
|
+
if (!regions.find((r) => r.id === region))
|
|
409
|
+
return createError(GameFindError.InvalidRegion);
|
|
410
|
+
let computedModeId;
|
|
411
|
+
if (typeof mode === "number") {
|
|
412
|
+
if (Object.values(GameMode).indexOf(mode) > -1)
|
|
413
|
+
computedModeId = mode;
|
|
414
|
+
else
|
|
415
|
+
return createError(GameFindError.InvalidMode);
|
|
416
|
+
} else if (typeof mode === "string") {
|
|
417
|
+
const modeEntry = Object.keys(GameMode).find((key) => key.toLowerCase() === mode.toLowerCase());
|
|
418
|
+
if (modeEntry)
|
|
419
|
+
computedModeId = GameMode[modeEntry];
|
|
420
|
+
else
|
|
421
|
+
return createError(GameFindError.InvalidMode);
|
|
422
|
+
} else
|
|
423
|
+
return createError(GameFindError.InvalidMode);
|
|
424
|
+
const initInfo = await this.initSession();
|
|
425
|
+
if (!initInfo.ok)
|
|
426
|
+
return initInfo;
|
|
367
427
|
const game = await new Promise((resolve) => {
|
|
368
428
|
const listener = (msg) => {
|
|
369
429
|
if (msg.command === "notice")
|
|
370
430
|
return;
|
|
371
|
-
this.
|
|
431
|
+
this.matchmakerListeners.splice(this.matchmakerListeners.indexOf(listener), 1);
|
|
372
432
|
if (msg.command === "gameFound") {
|
|
373
433
|
if (msg.useAltGameURL)
|
|
374
434
|
this.state.useAltGameURL = true;
|
|
375
435
|
return resolve(msg);
|
|
376
436
|
}
|
|
377
437
|
if (msg.error === "sessionNotFound")
|
|
378
|
-
return resolve(
|
|
379
|
-
this.
|
|
438
|
+
return resolve(createError(GameFindError.SessionExpired));
|
|
439
|
+
this.errorLogger("findPublicGame: unknown matchmaker response", JSON.stringify(msg));
|
|
440
|
+
resolve(createError(GameFindError.InternalError));
|
|
380
441
|
};
|
|
381
|
-
this.
|
|
382
|
-
this.matchmaker.send({
|
|
442
|
+
this.matchmakerListeners.push(listener);
|
|
443
|
+
this.matchmaker.send(JSON.stringify({
|
|
383
444
|
command: "findGame",
|
|
384
445
|
region,
|
|
385
446
|
playType: PlayType.JoinPublic,
|
|
386
|
-
gameType:
|
|
447
|
+
gameType: computedModeId,
|
|
387
448
|
sessionId: this.account.sessionId
|
|
388
|
-
});
|
|
449
|
+
}));
|
|
389
450
|
});
|
|
390
|
-
|
|
451
|
+
if (!game.ok)
|
|
452
|
+
return game;
|
|
453
|
+
return {
|
|
454
|
+
ok: true,
|
|
455
|
+
raw: game,
|
|
456
|
+
id: game.id,
|
|
457
|
+
uuid: game.uuid,
|
|
458
|
+
region: game.region,
|
|
459
|
+
private: game.private,
|
|
460
|
+
subdomain: game.subdomain
|
|
461
|
+
};
|
|
391
462
|
}
|
|
392
|
-
async createPrivateGame(region,
|
|
463
|
+
async createPrivateGame(region, mode, map) {
|
|
393
464
|
if (typeof region !== "string")
|
|
394
|
-
return
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
if (
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
465
|
+
return createError(GameFindError.MissingParams);
|
|
466
|
+
const regions = this.regionList.length ? this.regionList : Regions;
|
|
467
|
+
if (!regions.find((r) => r.id === region))
|
|
468
|
+
return createError(GameFindError.InvalidRegion);
|
|
469
|
+
let computedModeId;
|
|
470
|
+
if (typeof mode === "number") {
|
|
471
|
+
if (Object.values(GameMode).indexOf(mode) > -1)
|
|
472
|
+
computedModeId = mode;
|
|
473
|
+
else
|
|
474
|
+
return createError(GameFindError.InvalidMode);
|
|
475
|
+
} else if (typeof mode === "string") {
|
|
476
|
+
const modeEntry = Object.keys(GameMode).find((key) => key.toLowerCase() === mode.toLowerCase());
|
|
477
|
+
if (modeEntry)
|
|
478
|
+
computedModeId = GameMode[modeEntry];
|
|
479
|
+
else
|
|
480
|
+
return createError(GameFindError.InvalidMode);
|
|
481
|
+
} else
|
|
482
|
+
return createError(GameFindError.InvalidMode);
|
|
403
483
|
const mapIdx = Maps.findIndex((m) => m.name.toLowerCase() === map.toLowerCase());
|
|
404
484
|
if (mapIdx === -1)
|
|
405
|
-
return
|
|
406
|
-
|
|
407
|
-
|
|
485
|
+
return createError(GameFindError.InvalidMap);
|
|
486
|
+
const initInfo = await this.initSession();
|
|
487
|
+
if (!initInfo.ok)
|
|
488
|
+
return initInfo;
|
|
408
489
|
const game = await new Promise((resolve) => {
|
|
409
490
|
const listener = (msg) => {
|
|
410
491
|
if (msg.command === "notice")
|
|
411
492
|
return;
|
|
412
|
-
this.
|
|
493
|
+
this.matchmakerListeners.splice(this.matchmakerListeners.indexOf(listener), 1);
|
|
413
494
|
if (msg.command === "gameFound") {
|
|
414
495
|
if (msg.useAltGameURL)
|
|
415
496
|
this.state.useAltGameURL = true;
|
|
416
497
|
return resolve(msg);
|
|
417
498
|
}
|
|
418
499
|
if (msg.error === "sessionNotFound")
|
|
419
|
-
return resolve(
|
|
420
|
-
this.
|
|
500
|
+
return resolve(createError(GameFindError.SessionExpired));
|
|
501
|
+
this.errorLogger("createPrivateGame: unknown matchmaker response", JSON.stringify(msg));
|
|
502
|
+
resolve(createError(GameFindError.InternalError));
|
|
421
503
|
};
|
|
422
|
-
this.
|
|
423
|
-
this.matchmaker.send({
|
|
504
|
+
this.matchmakerListeners.push(listener);
|
|
505
|
+
this.matchmaker.send(JSON.stringify({
|
|
424
506
|
command: "findGame",
|
|
425
507
|
region,
|
|
426
508
|
playType: PlayType.CreatePrivate,
|
|
427
|
-
gameType:
|
|
509
|
+
gameType: computedModeId,
|
|
428
510
|
sessionId: this.account.sessionId,
|
|
429
511
|
noobLobby: false,
|
|
430
512
|
map: mapIdx
|
|
431
|
-
});
|
|
513
|
+
}));
|
|
432
514
|
});
|
|
433
|
-
|
|
515
|
+
if (!game.ok)
|
|
516
|
+
return game;
|
|
517
|
+
return {
|
|
518
|
+
ok: true,
|
|
519
|
+
raw: game,
|
|
520
|
+
id: game.id,
|
|
521
|
+
uuid: game.uuid,
|
|
522
|
+
region: game.region,
|
|
523
|
+
private: game.private,
|
|
524
|
+
subdomain: game.subdomain
|
|
525
|
+
};
|
|
434
526
|
}
|
|
435
527
|
async join(name, data) {
|
|
436
528
|
this.state.name = name || "yolkbot";
|
|
437
529
|
if (typeof data === "string") {
|
|
438
530
|
if (data.includes("#"))
|
|
439
531
|
data = data.split("#")[1];
|
|
440
|
-
|
|
441
|
-
|
|
532
|
+
const initInfo = await this.initSession();
|
|
533
|
+
if (!initInfo.ok)
|
|
534
|
+
return initInfo;
|
|
442
535
|
const joinResult = await new Promise((resolve) => {
|
|
443
536
|
const listener = (message) => {
|
|
444
537
|
if (message.command === "gameFound") {
|
|
445
|
-
this.
|
|
538
|
+
this.matchmakerListeners.splice(this.matchmakerListeners.indexOf(listener), 1);
|
|
446
539
|
this.game.raw = message;
|
|
447
540
|
this.game.code = message.id;
|
|
541
|
+
this.game.region = message.region;
|
|
448
542
|
resolve(message.id);
|
|
449
543
|
}
|
|
450
544
|
if (message.error && message.error === "gameNotFound") {
|
|
451
|
-
this.
|
|
452
|
-
|
|
453
|
-
return "gameNotFound";
|
|
545
|
+
this.matchmakerListeners.splice(this.matchmakerListeners.indexOf(listener), 1);
|
|
546
|
+
resolve("gameNotFound");
|
|
454
547
|
}
|
|
455
548
|
};
|
|
456
|
-
this.
|
|
457
|
-
this.matchmaker.send({
|
|
549
|
+
this.matchmakerListeners.push(listener);
|
|
550
|
+
this.matchmaker.send(JSON.stringify({
|
|
458
551
|
command: "joinGame",
|
|
459
552
|
id: data,
|
|
460
553
|
observe: false,
|
|
461
554
|
sessionId: this.account.sessionId
|
|
462
|
-
});
|
|
555
|
+
}));
|
|
463
556
|
});
|
|
464
557
|
if (joinResult === "gameNotFound")
|
|
465
|
-
return
|
|
466
|
-
if (!this.game.raw.id)
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
558
|
+
return createError(GameJoinError.GameNotFound);
|
|
559
|
+
if (!this.game.raw.id) {
|
|
560
|
+
this.errorLogger("join: invalid game data received from matchmaker:", this.game.raw);
|
|
561
|
+
return createError(GameJoinError.InternalError);
|
|
562
|
+
}
|
|
563
|
+
} else if (typeof data === "object") {
|
|
564
|
+
if (!data.id || !data.subdomain || !data.uuid || !data.region)
|
|
565
|
+
return createError(GameJoinError.InvalidObject);
|
|
566
|
+
if (this.account.id === 0) {
|
|
567
|
+
const anonAttempt = await this.loginAnonymously();
|
|
568
|
+
if (!anonAttempt.ok)
|
|
569
|
+
return anonAttempt;
|
|
570
|
+
}
|
|
472
571
|
this.game.raw = data;
|
|
473
572
|
this.game.code = this.game.raw.id;
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
return "invalid_game_object";
|
|
480
|
-
if (data.useAltGameURL)
|
|
481
|
-
this.state.useAltGameURL = true;
|
|
482
|
-
}
|
|
483
|
-
const host = this.state.useAltGameURL || this.host === "proxy.yolkbot.xyz" ? `${this.instance}/servers/${this.game.raw.subdomain}` : `${this.game.raw.subdomain}.${this.instance}`;
|
|
484
|
-
this.game.socket = new yolkws(`${this.protocol}://${host}/game/${this.game.raw.id}`, this.proxy);
|
|
573
|
+
this.game.region = this.game.raw.region;
|
|
574
|
+
} else
|
|
575
|
+
return createError(GameJoinError.MissingParams);
|
|
576
|
+
const host = this.state.useAltGameURL || this.instance === "proxy.yolkbot.xyz" ? `${this.instance}/servers/${this.game.raw.subdomain}` : `${this.game.raw.subdomain}.${this.instance}`;
|
|
577
|
+
this.game.socket = new yolkws(`${this.protocol}://${host}/game/${this.game.raw.id}`, { proxy: this.proxy, errorLogger: this.errorLogger });
|
|
485
578
|
this.game.socket.binaryType = "arraybuffer";
|
|
486
579
|
this.game.socket.connectionTimeout = this.connectionTimeout;
|
|
487
580
|
this.game.socket.onBeforeConnect = () => {
|
|
488
581
|
this.game.socket.onmessage = (msg) => this.processPacket(msg.data);
|
|
489
582
|
this.game.socket.onclose = (e) => {
|
|
490
|
-
if (this.state
|
|
491
|
-
this.
|
|
492
|
-
else {
|
|
493
|
-
this.emit("close", e.code);
|
|
583
|
+
if (this.state?.inGame) {
|
|
584
|
+
this.$emit("close", e.code);
|
|
494
585
|
this.leave(-1);
|
|
495
586
|
}
|
|
496
587
|
};
|
|
497
588
|
};
|
|
498
589
|
const didConnect = await this.game.socket.tryConnect();
|
|
499
590
|
if (!didConnect)
|
|
500
|
-
return
|
|
501
|
-
return true;
|
|
591
|
+
return createError(GameJoinError.WebSocketConnectFail);
|
|
592
|
+
return { ok: true };
|
|
593
|
+
}
|
|
594
|
+
#processMovement(ndx, ndy, ndz) {
|
|
595
|
+
this.state.onGround = Math.max(--this.state.onGround, 0);
|
|
596
|
+
this.me.position.x += ndx;
|
|
597
|
+
this.me.position.y += ndy;
|
|
598
|
+
this.me.position.z += ndz;
|
|
599
|
+
const thisBlockX = Math.floor(this.me.position.x);
|
|
600
|
+
const thisBlockY = Math.floor(this.me.position.y);
|
|
601
|
+
const thisBlockZ = Math.floor(this.me.position.z);
|
|
602
|
+
const blockInMyHitbox = this.pathing.nodeList.at(thisBlockX, thisBlockY, thisBlockZ);
|
|
603
|
+
if (blockInMyHitbox && !blockInMyHitbox.isAir()) {
|
|
604
|
+
if (!this.climbing && blockInMyHitbox.isLadder()) {}
|
|
605
|
+
}
|
|
606
|
+
if (this.me.climbing) {} else if (blockInMyHitbox && blockInMyHitbox.isJumpPad()) {
|
|
607
|
+
this.me.position.y += 0.26;
|
|
608
|
+
this.me.jumping = true;
|
|
609
|
+
this.state.onGround = 0;
|
|
610
|
+
}
|
|
502
611
|
}
|
|
503
612
|
#processPathfinding() {
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
613
|
+
const pathLen = this.pathing.activePath.length;
|
|
614
|
+
const lastNode = this.pathing.activePath[pathLen - 1];
|
|
615
|
+
const myPos = this.me.position;
|
|
616
|
+
const myFloorY = Math.floor(myPos.y);
|
|
617
|
+
const distToEndCenter = Math.hypot(myPos.x - lastNode.flatCenter.x, myPos.z - lastNode.flatCenter.z);
|
|
618
|
+
if (distToEndCenter < 0.3) {
|
|
507
619
|
this.pathing.activePath = null;
|
|
508
620
|
this.pathing.activeNode = null;
|
|
509
621
|
this.pathing.activeNodeIdx = 0;
|
|
510
622
|
this.dispatch(new MovementDispatch(0));
|
|
623
|
+
this.$emit("pathfindComplete");
|
|
511
624
|
} else {
|
|
512
|
-
let
|
|
513
|
-
if (this.pathing.activeNodeIdx <
|
|
514
|
-
|
|
515
|
-
this.
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
625
|
+
let shouldJump = false;
|
|
626
|
+
if (this.pathing.activeNodeIdx < pathLen - 1) {
|
|
627
|
+
const currentNode = this.pathing.activePath[this.pathing.activeNodeIdx];
|
|
628
|
+
const nextNode = this.pathing.activePath[this.pathing.activeNodeIdx + 1];
|
|
629
|
+
const dx = Math.abs(currentNode.x - nextNode.x);
|
|
630
|
+
const dz = Math.abs(currentNode.z - nextNode.z);
|
|
631
|
+
const isParkourJump = dx === 2 && dz === 0 || dx === 0 && dz === 2 || dx === 2 && dz === 1 || dx === 1 && dz === 2 || dx === 2 && dz === 2;
|
|
632
|
+
if (isParkourJump) {
|
|
633
|
+
const localX = myPos.x - Math.floor(myPos.x);
|
|
634
|
+
const localZ = myPos.z - Math.floor(myPos.z);
|
|
635
|
+
const headingX = nextNode.x > currentNode.x ? 1 : nextNode.x < currentNode.x ? -1 : 0;
|
|
636
|
+
const headingZ = nextNode.z > currentNode.z ? 1 : nextNode.z < currentNode.z ? -1 : 0;
|
|
637
|
+
let distToEdge = 0;
|
|
638
|
+
if (headingX > 0)
|
|
639
|
+
distToEdge = 1 - localX;
|
|
640
|
+
else if (headingX < 0)
|
|
641
|
+
distToEdge = localX;
|
|
642
|
+
else if (headingZ > 0)
|
|
643
|
+
distToEdge = 1 - localZ;
|
|
644
|
+
else if (headingZ < 0)
|
|
645
|
+
distToEdge = localZ;
|
|
646
|
+
if (distToEdge <= 0.04)
|
|
647
|
+
shouldJump = true;
|
|
648
|
+
}
|
|
519
649
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
650
|
+
if (this.pathing.activeNodeIdx < pathLen) {
|
|
651
|
+
const positionTarget = this.pathing.activePath[this.pathing.activeNodeIdx].flatCenter;
|
|
652
|
+
if (this.state.onGround)
|
|
653
|
+
this.dispatch(new LookAtPosDispatch(positionTarget));
|
|
654
|
+
}
|
|
655
|
+
for (let i = this.pathing.activeNodeIdx;i < pathLen; i++) {
|
|
656
|
+
const node = this.pathing.activePath[i];
|
|
657
|
+
if (node.flatRadialDistance(myPos) < 0.1 && node.y === myFloorY) {
|
|
658
|
+
this.pathing.activeNodeIdx = i + 1;
|
|
659
|
+
this.pathing.activeNode = this.pathing.activePath[this.pathing.activeNodeIdx];
|
|
660
|
+
break;
|
|
527
661
|
}
|
|
528
662
|
}
|
|
529
|
-
|
|
530
|
-
|
|
663
|
+
const movementKeys = Movement.Forward | (shouldJump ? Movement.Jump : 0);
|
|
664
|
+
this.dispatch(new MovementDispatch(movementKeys));
|
|
531
665
|
}
|
|
532
666
|
}
|
|
533
667
|
update() {
|
|
534
668
|
if (this.hasQuit)
|
|
535
669
|
return;
|
|
536
|
-
if (this.pathing.
|
|
670
|
+
if (this.pathing.activePath && this.intents.includes(Intents.PATHFINDING))
|
|
537
671
|
this.#processPathfinding();
|
|
538
|
-
for (let i =
|
|
672
|
+
for (let i = this.#dispatches.length - 1;i >= 0; i--) {
|
|
539
673
|
const disp = this.#dispatches[i];
|
|
540
674
|
if (disp.check(this)) {
|
|
541
675
|
disp.execute(this);
|
|
@@ -545,25 +679,99 @@ export class Bot {
|
|
|
545
679
|
this.state.chatLines = Math.max(0, this.state.chatLines - 1 / (30 * 4));
|
|
546
680
|
if (this.me.playing) {
|
|
547
681
|
const currentIdx = this.state.stateIdx;
|
|
548
|
-
|
|
682
|
+
const isBufferDebug = this.intents.includes(Intents.DEBUG_BUFFER);
|
|
683
|
+
if (isBufferDebug)
|
|
549
684
|
console.log("setting buffer for idx", currentIdx);
|
|
550
|
-
console.log("checking...shotsFired", this.state.shotsFired);
|
|
551
|
-
}
|
|
552
685
|
this.me.jumping = !!(this.state.controlKeys & Movement.Jump);
|
|
553
686
|
this.state.buffer[currentIdx] = {
|
|
554
687
|
controlKeys: this.state.controlKeys,
|
|
555
688
|
yaw: this.state.yaw,
|
|
556
689
|
pitch: this.state.pitch,
|
|
557
|
-
shotsFired: this.state.shotsFired
|
|
690
|
+
shotsFired: this.state.shotsFired,
|
|
691
|
+
position: isBufferDebug ? { ...this.me.position } : {}
|
|
558
692
|
};
|
|
559
693
|
this.state.shotsFired = 0;
|
|
560
|
-
if (this.
|
|
561
|
-
|
|
694
|
+
if (this.intents.includes(Intents.SIMULATION)) {
|
|
695
|
+
let dx = 0;
|
|
696
|
+
let dy = 0;
|
|
697
|
+
let dz = 0;
|
|
698
|
+
const state = this.state.buffer[currentIdx];
|
|
699
|
+
if (state.controlKeys & Movement.Left) {
|
|
700
|
+
dx -= Math.cos(state.yaw);
|
|
701
|
+
dz += Math.sin(state.yaw);
|
|
702
|
+
}
|
|
703
|
+
if (state.controlKeys & Movement.Right) {
|
|
704
|
+
dx += Math.cos(state.yaw);
|
|
705
|
+
dz -= Math.sin(state.yaw);
|
|
706
|
+
}
|
|
707
|
+
if (state.controlKeys & Movement.Forward) {
|
|
708
|
+
if (this.me.climbing)
|
|
709
|
+
dy += 1;
|
|
710
|
+
else {
|
|
711
|
+
dx -= Math.sin(state.yaw);
|
|
712
|
+
dz -= Math.cos(state.yaw);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
if (state.controlKeys & Movement.Backward) {
|
|
716
|
+
if (this.me.climbing)
|
|
717
|
+
dy -= 1;
|
|
718
|
+
else {
|
|
719
|
+
dx += Math.sin(state.yaw);
|
|
720
|
+
dz += Math.cos(state.yaw);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
if (state.controlKeys & Movement.Jump)
|
|
724
|
+
this.state.controlKeys ^= this.state.controlKeys & Movement.Jump;
|
|
725
|
+
if (this.me.climbing) {
|
|
726
|
+
this.me.jumping = false;
|
|
727
|
+
dy += dy * 0.028;
|
|
728
|
+
this.me.position.y += dy;
|
|
729
|
+
dy *= 0.5;
|
|
730
|
+
this.#processMovement(0, dy, 0);
|
|
731
|
+
} else {
|
|
732
|
+
const mag = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
733
|
+
if (mag > 0) {
|
|
734
|
+
const normDx = dx / mag;
|
|
735
|
+
const normDz = dz / mag;
|
|
736
|
+
dx = this.state.dx + normDx * 0.025;
|
|
737
|
+
dz = this.state.dz + normDz * 0.025;
|
|
738
|
+
} else {
|
|
739
|
+
dx = this.state.dx;
|
|
740
|
+
dz = this.state.dz;
|
|
741
|
+
}
|
|
742
|
+
dy = this.state.dy - this.game.options.gravity * 0.012;
|
|
743
|
+
dy = Math.max(-0.29, dy);
|
|
744
|
+
const oldX = this.me.position.x;
|
|
745
|
+
const oldY = this.me.position.y;
|
|
746
|
+
const oldZ = this.me.position.z;
|
|
747
|
+
this.#processMovement(dx, dy, dz);
|
|
748
|
+
dx = this.me.position.x - oldX;
|
|
749
|
+
dy = this.me.position.y - oldY;
|
|
750
|
+
dz = this.me.position.z - oldZ;
|
|
751
|
+
if (this.state.onGround && dy > 0) {
|
|
752
|
+
const normY = mag === 0 ? 0 : dy / mag;
|
|
753
|
+
const n = 1 - normY * 0.5;
|
|
754
|
+
dx *= n;
|
|
755
|
+
dz *= n;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
dx *= 0.64;
|
|
759
|
+
dz *= 0.64;
|
|
760
|
+
if (this.me.climbing)
|
|
761
|
+
dy *= 0.64;
|
|
762
|
+
this.state.dx = dx;
|
|
763
|
+
this.state.dy = dy;
|
|
764
|
+
this.state.dz = dz;
|
|
765
|
+
}
|
|
766
|
+
if (this.state.stateIdx % FramesBetweenSyncs === 0) {
|
|
767
|
+
this.$emit("tick");
|
|
562
768
|
const out = new CommOut;
|
|
563
769
|
out.packInt8(CommCode.syncMe);
|
|
564
770
|
out.packInt8(this.state.stateIdx);
|
|
565
771
|
out.packInt8(this.state.serverStateIdx);
|
|
566
772
|
const startIdx = mod(this.state.stateIdx - FramesBetweenSyncs + 1, StateBufferSize);
|
|
773
|
+
if (isBufferDebug)
|
|
774
|
+
console.log("--- START THIS SYNC LOGGING ---");
|
|
567
775
|
for (let i = 0;i < FramesBetweenSyncs; i++) {
|
|
568
776
|
const idx = mod(startIdx + i, StateBufferSize);
|
|
569
777
|
const frame = this.state.buffer[idx] || {};
|
|
@@ -571,28 +779,30 @@ export class Bot {
|
|
|
571
779
|
const shots = frame.shotsFired || 0;
|
|
572
780
|
const yaw = frame.yaw ?? this.state.yaw;
|
|
573
781
|
const pitch = frame.pitch ?? this.state.pitch;
|
|
574
|
-
if (
|
|
575
|
-
console.log("
|
|
782
|
+
if (isBufferDebug)
|
|
783
|
+
console.log("adding", this.state.stateIdx, startIdx, idx, frame);
|
|
576
784
|
out.packInt8(keys);
|
|
577
785
|
out.packInt8(shots);
|
|
578
786
|
out.packString(coords(yaw, pitch));
|
|
579
787
|
out.packInt8(100);
|
|
580
788
|
}
|
|
581
789
|
out.send(this.game.socket);
|
|
790
|
+
if (isBufferDebug)
|
|
791
|
+
console.log("--- END SYNC LOGGING ---");
|
|
582
792
|
this.state.buffer = [];
|
|
583
|
-
|
|
584
|
-
} else
|
|
585
|
-
this.lastUpdateTick++;
|
|
793
|
+
}
|
|
586
794
|
this.state.stateIdx = mod(this.state.stateIdx + 1, StateBufferSize);
|
|
587
795
|
}
|
|
588
|
-
if (!this.intents.includes(
|
|
796
|
+
if (!this.intents.includes(Intents.PLAYER_HEALTH))
|
|
589
797
|
return;
|
|
590
798
|
const regen = 0.1 * (this.game.isPrivate ? this.game.options.healthRegen : 1);
|
|
591
|
-
|
|
799
|
+
const players = Object.values(this.players);
|
|
800
|
+
for (let i = 0;i < players.length; i++) {
|
|
801
|
+
const player = players[i];
|
|
592
802
|
if (player.playing && player.hp > 0) {
|
|
593
|
-
const
|
|
594
|
-
player.hp +=
|
|
595
|
-
player.hp =
|
|
803
|
+
const hasOverHeal = player.streakRewards.includes(ShellStreak.OverHeal);
|
|
804
|
+
player.hp += hasOverHeal ? -regen : regen;
|
|
805
|
+
player.hp = hasOverHeal ? Math.max(100, player.hp) : Math.min(100, player.hp);
|
|
596
806
|
}
|
|
597
807
|
if (player.spawnShield > 0)
|
|
598
808
|
player.spawnShield -= 6;
|
|
@@ -604,13 +814,6 @@ export class Bot {
|
|
|
604
814
|
else
|
|
605
815
|
this.#hooks[event] = [cb];
|
|
606
816
|
}
|
|
607
|
-
once(event, cb) {
|
|
608
|
-
const onceCb = (...args) => {
|
|
609
|
-
cb(...args);
|
|
610
|
-
this.off(event, onceCb);
|
|
611
|
-
};
|
|
612
|
-
this.on(event, onceCb);
|
|
613
|
-
}
|
|
614
817
|
onAny(cb) {
|
|
615
818
|
this.#globalHooks.push(cb);
|
|
616
819
|
}
|
|
@@ -620,7 +823,7 @@ export class Bot {
|
|
|
620
823
|
else
|
|
621
824
|
this.#hooks[event] = [];
|
|
622
825
|
}
|
|
623
|
-
emit(event, ...args) {
|
|
826
|
+
$emit(event, ...args) {
|
|
624
827
|
if (this.hasQuit)
|
|
625
828
|
return;
|
|
626
829
|
if (this.#hooks[event])
|
|
@@ -629,589 +832,12 @@ export class Bot {
|
|
|
629
832
|
for (const cb of this.#globalHooks)
|
|
630
833
|
cb(event, ...args);
|
|
631
834
|
}
|
|
632
|
-
|
|
633
|
-
const
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
}
|
|
639
|
-
#processAddPlayerPacket() {
|
|
640
|
-
const id = CommIn.unPackInt8U();
|
|
641
|
-
const findCosmetics = this.intents.includes(this.Intents.COSMETIC_DATA);
|
|
642
|
-
const playerData = {
|
|
643
|
-
id,
|
|
644
|
-
uniqueId: CommIn.unPackString(),
|
|
645
|
-
name: CommIn.unPackString(),
|
|
646
|
-
safeName: CommIn.unPackString(),
|
|
647
|
-
charClass: CommIn.unPackInt8U(),
|
|
648
|
-
team: CommIn.unPackInt8U(),
|
|
649
|
-
primaryWeaponItem: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
650
|
-
secondaryWeaponItem: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
651
|
-
shellColor: CommIn.unPackInt8U(),
|
|
652
|
-
hatItem: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
653
|
-
stampItem: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
654
|
-
stampPosX: CommIn.unPackInt8(),
|
|
655
|
-
stampPosY: CommIn.unPackInt8(),
|
|
656
|
-
grenadeItem: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
657
|
-
meleeItem: findCosmetics ? findItemById(CommIn.unPackInt16U()) : CommIn.unPackInt16U(),
|
|
658
|
-
x: CommIn.unPackFloat(),
|
|
659
|
-
y: CommIn.unPackFloat(),
|
|
660
|
-
z: CommIn.unPackFloat(),
|
|
661
|
-
$dx: CommIn.unPackFloat(),
|
|
662
|
-
$dy: CommIn.unPackFloat(),
|
|
663
|
-
$dz: CommIn.unPackFloat(),
|
|
664
|
-
yaw: CommIn.unPackRadU(),
|
|
665
|
-
pitch: CommIn.unPackRad(),
|
|
666
|
-
score: CommIn.unPackInt32U(),
|
|
667
|
-
$kills: CommIn.unPackInt16U(),
|
|
668
|
-
$deaths: CommIn.unPackInt16U(),
|
|
669
|
-
$streak: CommIn.unPackInt16U(),
|
|
670
|
-
totalKills: CommIn.unPackInt32U(),
|
|
671
|
-
totalDeaths: CommIn.unPackInt32U(),
|
|
672
|
-
bestStreak: CommIn.unPackInt16U(),
|
|
673
|
-
$bestOverallStreak: CommIn.unPackInt16U(),
|
|
674
|
-
shield: CommIn.unPackInt8U(),
|
|
675
|
-
hp: CommIn.unPackInt8U(),
|
|
676
|
-
playing: CommIn.unPackInt8U(),
|
|
677
|
-
weaponIdx: CommIn.unPackInt8U(),
|
|
678
|
-
$controlKeys: CommIn.unPackInt8U(),
|
|
679
|
-
upgradeProductId: CommIn.unPackInt8U(),
|
|
680
|
-
activeShellStreaks: CommIn.unPackInt8U(),
|
|
681
|
-
social: CommIn.unPackLongString(),
|
|
682
|
-
hideBadge: CommIn.unPackInt8U()
|
|
683
|
-
};
|
|
684
|
-
this.game.mapIdx = CommIn.unPackInt8U();
|
|
685
|
-
this.game.isPrivate = CommIn.unPackInt8U() === 1;
|
|
686
|
-
this.game.gameModeId = CommIn.unPackInt8U();
|
|
687
|
-
const player = new GamePlayer(playerData, this.game.gameMode === GameMode.KOTC ? this.game.activeZone : null);
|
|
688
|
-
if (!this.players[playerData.id])
|
|
689
|
-
this.players[playerData.id] = player;
|
|
690
|
-
this.emit("playerJoin", player);
|
|
691
|
-
if (this.me.id === playerData.id) {
|
|
692
|
-
this.me = player;
|
|
693
|
-
this.emit("botJoin", this.me);
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
#processRespawnPacket() {
|
|
697
|
-
const id = CommIn.unPackInt8U();
|
|
698
|
-
const seed = CommIn.unPackInt16U();
|
|
699
|
-
const x = CommIn.unPackFloat();
|
|
700
|
-
const y = CommIn.unPackFloat();
|
|
701
|
-
const z = CommIn.unPackFloat();
|
|
702
|
-
const rounds0 = CommIn.unPackInt8U();
|
|
703
|
-
const store0 = CommIn.unPackInt8U();
|
|
704
|
-
const rounds1 = CommIn.unPackInt8U();
|
|
705
|
-
const store1 = CommIn.unPackInt8U();
|
|
706
|
-
const grenades = CommIn.unPackInt8U();
|
|
707
|
-
const player = this.players[id];
|
|
708
|
-
if (player) {
|
|
709
|
-
player.playing = true;
|
|
710
|
-
player.randomSeed = seed;
|
|
711
|
-
if (player.weapons[0] && player.weapons[0].ammo)
|
|
712
|
-
player.weapons[0].ammo.rounds = rounds0;
|
|
713
|
-
if (player.weapons[0] && player.weapons[0].ammo)
|
|
714
|
-
player.weapons[0].ammo.store = store0;
|
|
715
|
-
if (player.weapons[1] && player.weapons[1].ammo)
|
|
716
|
-
player.weapons[1].ammo.rounds = rounds1;
|
|
717
|
-
if (player.weapons[1] && player.weapons[1].ammo)
|
|
718
|
-
player.weapons[1].ammo.store = store1;
|
|
719
|
-
player.grenades = grenades;
|
|
720
|
-
player.position = { x, y, z };
|
|
721
|
-
player.spawnShield = 120;
|
|
722
|
-
this.emit("playerRespawn", player);
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
#processSyncThemPacket() {
|
|
726
|
-
const id = CommIn.unPackInt8U();
|
|
727
|
-
const x = CommIn.unPackFloat();
|
|
728
|
-
const y = CommIn.unPackFloat();
|
|
729
|
-
const z = CommIn.unPackFloat();
|
|
730
|
-
const climbing = CommIn.unPackInt8U();
|
|
731
|
-
const player = this.players[id];
|
|
732
|
-
if (!player || player.id === this.me.id) {
|
|
733
|
-
for (let i2 = 0;i2 < FramesBetweenSyncs; i2++) {
|
|
734
|
-
CommIn.unPackInt8U();
|
|
735
|
-
CommIn.unPackRadU();
|
|
736
|
-
CommIn.unPackRad();
|
|
737
|
-
CommIn.unPackInt8U();
|
|
738
|
-
}
|
|
739
|
-
return;
|
|
740
|
-
}
|
|
741
|
-
for (let i2 = 0;i2 < FramesBetweenSyncs; i2++) {
|
|
742
|
-
const controlKeys = CommIn.unPackInt8U();
|
|
743
|
-
if (controlKeys & Movement.Jump)
|
|
744
|
-
player.jumping = true;
|
|
745
|
-
else
|
|
746
|
-
player.jumping = false;
|
|
747
|
-
if (controlKeys & Movement.Scope)
|
|
748
|
-
player.scoping = true;
|
|
749
|
-
else
|
|
750
|
-
player.scoping = false;
|
|
751
|
-
const oldView = { ...player.view };
|
|
752
|
-
player.view.yaw = CommIn.unPackRadU();
|
|
753
|
-
player.view.pitch = CommIn.unPackRad();
|
|
754
|
-
if (player.view.yaw !== oldView.yaw || player.view.pitch !== oldView.pitch)
|
|
755
|
-
this.emit("playerRotate", player, oldView, player.view);
|
|
756
|
-
player.scale = CommIn.unPackInt8U();
|
|
757
|
-
}
|
|
758
|
-
const px = player.position;
|
|
759
|
-
const posChanged = px.x !== x || px.y !== y || px.z !== z;
|
|
760
|
-
const climbingChanged = player.climbing !== climbing;
|
|
761
|
-
const didChange = posChanged || climbingChanged;
|
|
762
|
-
const oldPosition = didChange ? { ...px } : null;
|
|
763
|
-
if (px.x !== x)
|
|
764
|
-
px.x = x;
|
|
765
|
-
if (px.z !== z)
|
|
766
|
-
px.z = z;
|
|
767
|
-
if (!player.jumping || Math.abs(px.y - y) > 0.5)
|
|
768
|
-
px.y = y;
|
|
769
|
-
if (climbingChanged)
|
|
770
|
-
player.climbing = climbing;
|
|
771
|
-
if (!didChange)
|
|
772
|
-
return;
|
|
773
|
-
this.emit("playerMove", player, oldPosition, px);
|
|
774
|
-
if (this.game.gameModeId !== GameMode.KOTC)
|
|
775
|
-
return;
|
|
776
|
-
const zone = this.game.activeZone;
|
|
777
|
-
const wasIn = !!player.inKotcZone;
|
|
778
|
-
if (!zone && wasIn) {
|
|
779
|
-
player.inKotcZone = false;
|
|
780
|
-
this.emit("playerLeaveZone", player);
|
|
781
|
-
return;
|
|
782
|
-
}
|
|
783
|
-
player.updateKotcZone(zone);
|
|
784
|
-
const nowIn = !!player.inKotcZone;
|
|
785
|
-
if (wasIn !== nowIn) {
|
|
786
|
-
player.inKotcZone = nowIn;
|
|
787
|
-
this.emit(nowIn ? "playerEnterZone" : "playerLeaveZone", player);
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
#processPausePacket() {
|
|
791
|
-
const id = CommIn.unPackInt8U();
|
|
792
|
-
const player = this.players[id];
|
|
793
|
-
if (player) {
|
|
794
|
-
player.playing = false;
|
|
795
|
-
if (player.streakRewards)
|
|
796
|
-
player.streakRewards = [];
|
|
797
|
-
this.emit("playerPause", player);
|
|
798
|
-
if (player.inKotcZone) {
|
|
799
|
-
player.inKotcZone = false;
|
|
800
|
-
this.emit("playerLeaveZone", player);
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
#processSwapWeaponPacket() {
|
|
805
|
-
const id = CommIn.unPackInt8U();
|
|
806
|
-
const newWeaponId = CommIn.unPackInt8U();
|
|
807
|
-
const player = this.players[id];
|
|
808
|
-
if (player) {
|
|
809
|
-
player.activeGun = newWeaponId;
|
|
810
|
-
this.emit("playerSwapWeapon", player, newWeaponId);
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
#processDeathPacket() {
|
|
814
|
-
const killedId = CommIn.unPackInt8U();
|
|
815
|
-
const killerId = CommIn.unPackInt8U();
|
|
816
|
-
CommIn.unPackInt8U();
|
|
817
|
-
CommIn.unPackInt8U();
|
|
818
|
-
const damageCauseInt = CommIn.unPackInt8U();
|
|
819
|
-
const killed = this.players[killedId];
|
|
820
|
-
const killer = this.players[killerId];
|
|
821
|
-
const oldKilled = killed ? { ...killed } : null;
|
|
822
|
-
if (killed) {
|
|
823
|
-
if (killed.id === this.me.id)
|
|
824
|
-
this.lastDeathTime = Date.now();
|
|
825
|
-
killed.playing = false;
|
|
826
|
-
killed.streak = 0;
|
|
827
|
-
killed.hp = 100;
|
|
828
|
-
killed.spawnShield = 0;
|
|
829
|
-
killed.stats.totalDeaths++;
|
|
830
|
-
killed.inKotcZone = false;
|
|
831
|
-
this.emit("playerLeaveZone", killed);
|
|
832
|
-
}
|
|
833
|
-
if (killer) {
|
|
834
|
-
killer.streak++;
|
|
835
|
-
killer.stats.totalKills++;
|
|
836
|
-
if (killer.streak > killer.stats.bestStreak)
|
|
837
|
-
killer.stats.bestStreak = killer.streak;
|
|
838
|
-
}
|
|
839
|
-
this.emit("playerDeath", killed, killer, oldKilled, damageCauseInt);
|
|
840
|
-
}
|
|
841
|
-
#processFirePacket() {
|
|
842
|
-
const id = CommIn.unPackInt8U();
|
|
843
|
-
const bullet = {
|
|
844
|
-
posX: CommIn.unPackFloat(),
|
|
845
|
-
posY: CommIn.unPackFloat(),
|
|
846
|
-
posZ: CommIn.unPackFloat(),
|
|
847
|
-
dirX: CommIn.unPackFloat(),
|
|
848
|
-
dirY: CommIn.unPackFloat(),
|
|
849
|
-
dirZ: CommIn.unPackFloat()
|
|
850
|
-
};
|
|
851
|
-
const player = this.players[id];
|
|
852
|
-
if (!player)
|
|
853
|
-
return;
|
|
854
|
-
const playerWeapon = player.weapons[player.activeGun];
|
|
855
|
-
if (playerWeapon && playerWeapon.ammo) {
|
|
856
|
-
playerWeapon.ammo.rounds--;
|
|
857
|
-
this.emit("playerFire", player, playerWeapon, bullet);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
#processSpawnItemPacket() {
|
|
861
|
-
const id = CommIn.unPackInt16U();
|
|
862
|
-
const type = CommIn.unPackInt8U();
|
|
863
|
-
const x = CommIn.unPackFloat();
|
|
864
|
-
const y = CommIn.unPackFloat();
|
|
865
|
-
const z = CommIn.unPackFloat();
|
|
866
|
-
this.game.collectables[type].push({ id, x, y, z });
|
|
867
|
-
this.emit("spawnItem", type, { x, y, z }, id);
|
|
868
|
-
}
|
|
869
|
-
#processCollectPacket() {
|
|
870
|
-
const playerId = CommIn.unPackInt8U();
|
|
871
|
-
const type = CommIn.unPackInt8U();
|
|
872
|
-
const applyToWeaponIdx = CommIn.unPackInt8U();
|
|
873
|
-
const id = CommIn.unPackInt16U();
|
|
874
|
-
const player = this.players[playerId];
|
|
875
|
-
if (!player)
|
|
876
|
-
return;
|
|
877
|
-
this.game.collectables[type] = this.game.collectables[type].filter((c) => c.id !== id);
|
|
878
|
-
if (type === CollectType.Ammo) {
|
|
879
|
-
const playerWeapon = player.weapons[applyToWeaponIdx];
|
|
880
|
-
if (playerWeapon && playerWeapon.ammo) {
|
|
881
|
-
playerWeapon.ammo.store = Math.min(playerWeapon.ammo.storeMax, playerWeapon.ammo.store + playerWeapon.ammo.pickup);
|
|
882
|
-
this.emit("playerCollectAmmo", player, playerWeapon, id);
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
if (type === CollectType.Grenade) {
|
|
886
|
-
player.grenades++;
|
|
887
|
-
if (player.grenades > 3)
|
|
888
|
-
player.grenades = 3;
|
|
889
|
-
this.emit("playerCollectGrenade", player, id);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
#processHitThemPacket() {
|
|
893
|
-
const id = CommIn.unPackInt8U();
|
|
894
|
-
const hp = CommIn.unPackInt8U();
|
|
895
|
-
const player = this.players[id];
|
|
896
|
-
if (!player)
|
|
897
|
-
return;
|
|
898
|
-
const oldHealth = player.hp;
|
|
899
|
-
player.hp = hp;
|
|
900
|
-
this.emit("playerDamage", player, oldHealth, player.hp);
|
|
901
|
-
}
|
|
902
|
-
#processHitMePacket() {
|
|
903
|
-
const hp = CommIn.unPackInt8U();
|
|
904
|
-
CommIn.unPackFloat();
|
|
905
|
-
CommIn.unPackFloat();
|
|
906
|
-
const oldHealth = this.me.hp;
|
|
907
|
-
this.me.hp = hp;
|
|
908
|
-
this.emit("playerDamage", this.me, oldHealth, this.me.hp);
|
|
909
|
-
}
|
|
910
|
-
#processSyncMePacket() {
|
|
911
|
-
const id = CommIn.unPackInt8U();
|
|
912
|
-
const player = this.players[id];
|
|
913
|
-
CommIn.unPackInt8U();
|
|
914
|
-
const serverStateIdx = CommIn.unPackInt8U();
|
|
915
|
-
const newX = CommIn.unPackFloat();
|
|
916
|
-
const newY = CommIn.unPackFloat();
|
|
917
|
-
const newZ = CommIn.unPackFloat();
|
|
918
|
-
this.me.climbing = !!CommIn.unPackInt8U();
|
|
919
|
-
CommIn.unPackInt8U();
|
|
920
|
-
CommIn.unPackInt8U();
|
|
921
|
-
if (!player)
|
|
922
|
-
return;
|
|
923
|
-
this.state.serverStateIdx = serverStateIdx;
|
|
924
|
-
const oldX = player.position.x;
|
|
925
|
-
const oldY = player.position.y;
|
|
926
|
-
const oldZ = player.position.z;
|
|
927
|
-
player.position.x = newX;
|
|
928
|
-
player.position.y = newY;
|
|
929
|
-
player.position.z = newZ;
|
|
930
|
-
if (oldX !== newX || oldY !== newY || oldZ !== newZ)
|
|
931
|
-
this.emit("playerMove", player, { x: oldX, y: oldY, z: oldZ }, { x: newX, y: newY, z: newZ });
|
|
932
|
-
}
|
|
933
|
-
#processEventModifierPacket() {
|
|
934
|
-
const out = new CommOut;
|
|
935
|
-
out.packInt8(CommCode.eventModifier);
|
|
936
|
-
out.send(this.game.socket);
|
|
937
|
-
}
|
|
938
|
-
#processRemovePlayerPacket() {
|
|
939
|
-
const id = CommIn.unPackInt8U();
|
|
940
|
-
const removedPlayer = { ...this.players[id] };
|
|
941
|
-
delete this.players[id];
|
|
942
|
-
this.emit("playerLeave", removedPlayer);
|
|
943
|
-
}
|
|
944
|
-
#processGameStatePacket() {
|
|
945
|
-
if (this.game.gameModeId === GameMode.Spatula) {
|
|
946
|
-
const oldGame = { ...this.game };
|
|
947
|
-
this.game.teamScore[1] = CommIn.unPackInt16U();
|
|
948
|
-
this.game.teamScore[2] = CommIn.unPackInt16U();
|
|
949
|
-
const spatulaCoords = {
|
|
950
|
-
x: CommIn.unPackFloat(),
|
|
951
|
-
y: CommIn.unPackFloat(),
|
|
952
|
-
z: CommIn.unPackFloat()
|
|
953
|
-
};
|
|
954
|
-
const controlledBy = CommIn.unPackInt8U();
|
|
955
|
-
const controlledByTeam = CommIn.unPackInt8U();
|
|
956
|
-
this.game.spatula = { coords: spatulaCoords, controlledBy, controlledByTeam };
|
|
957
|
-
this.emit("gameStateChange", oldGame, this.game);
|
|
958
|
-
} else if (this.game.gameModeId === GameMode.KOTC) {
|
|
959
|
-
const oldGame = { ...this.game };
|
|
960
|
-
this.game.stage = CommIn.unPackInt8U();
|
|
961
|
-
this.game.zoneNumber = CommIn.unPackInt8U();
|
|
962
|
-
this.game.capturing = CommIn.unPackInt8U();
|
|
963
|
-
this.game.captureProgress = CommIn.unPackInt16U();
|
|
964
|
-
this.game.numCapturing = CommIn.unPackInt8U();
|
|
965
|
-
this.game.teamScore[1] = CommIn.unPackInt8U();
|
|
966
|
-
this.game.teamScore[2] = CommIn.unPackInt8U();
|
|
967
|
-
this.game.capturePercent = this.game.captureProgress / 1000;
|
|
968
|
-
this.game.activeZone = this.game.map.zones ? this.game.map.zones[this.game.zoneNumber - 1] : null;
|
|
969
|
-
const oldPlayersOnZone = Object.values(this.players).filter((p) => p.inKotcZone && p.playing);
|
|
970
|
-
if (this.game.activeZone)
|
|
971
|
-
Object.values(this.players).forEach((player) => player.updateKotcZone(this.game.activeZone));
|
|
972
|
-
if (this.game.numCapturing <= 0)
|
|
973
|
-
Object.values(this.players).forEach((player) => {
|
|
974
|
-
player.inKotcZone = false;
|
|
975
|
-
this.emit("playerLeaveZone", player);
|
|
976
|
-
});
|
|
977
|
-
this.emit("gameStateChange", oldGame, this.game, oldPlayersOnZone);
|
|
978
|
-
} else if (this.game.gameModeId === GameMode.Team) {
|
|
979
|
-
this.game.teamScore[1] = CommIn.unPackInt16U();
|
|
980
|
-
this.game.teamScore[2] = CommIn.unPackInt16U();
|
|
981
|
-
}
|
|
982
|
-
if (this.game.gameModeId !== GameMode.Spatula)
|
|
983
|
-
delete this.game.spatula;
|
|
984
|
-
if (this.game.gameModeId !== GameMode.KOTC) {
|
|
985
|
-
delete this.game.stage;
|
|
986
|
-
delete this.game.zoneNumber;
|
|
987
|
-
delete this.game.capturing;
|
|
988
|
-
delete this.game.captureProgress;
|
|
989
|
-
delete this.game.numCapturing;
|
|
990
|
-
delete this.game.numCapturing;
|
|
991
|
-
delete this.game.activeZone;
|
|
992
|
-
}
|
|
993
|
-
if (this.game.gameModeId === GameMode.FFA)
|
|
994
|
-
delete this.game.teamScore;
|
|
995
|
-
}
|
|
996
|
-
#processBeginStreakPacket() {
|
|
997
|
-
const id = CommIn.unPackInt8U();
|
|
998
|
-
const ksType = CommIn.unPackInt8U();
|
|
999
|
-
const player = this.players[id];
|
|
1000
|
-
if (!player)
|
|
1001
|
-
return;
|
|
1002
|
-
switch (ksType) {
|
|
1003
|
-
case ShellStreak.HardBoiled:
|
|
1004
|
-
if (id === this.me.id)
|
|
1005
|
-
this.me.shieldHp = 100;
|
|
1006
|
-
player.streakRewards.push(ShellStreak.HardBoiled);
|
|
1007
|
-
break;
|
|
1008
|
-
case ShellStreak.EggBreaker:
|
|
1009
|
-
player.streakRewards.push(ShellStreak.EggBreaker);
|
|
1010
|
-
break;
|
|
1011
|
-
case ShellStreak.Restock: {
|
|
1012
|
-
player.grenades = 3;
|
|
1013
|
-
if (player.weapons[0] && player.weapons[0].ammo) {
|
|
1014
|
-
player.weapons[0].ammo.rounds = player.weapons[0].ammo.capacity;
|
|
1015
|
-
player.weapons[0].ammo.store = player.weapons[0].ammo.storeMax;
|
|
1016
|
-
}
|
|
1017
|
-
if (player.weapons[1] && player.weapons[1].ammo) {
|
|
1018
|
-
player.weapons[1].ammo.rounds = player.weapons[1].ammo.capacity;
|
|
1019
|
-
player.weapons[1].ammo.store = player.weapons[1].ammo.storeMax;
|
|
1020
|
-
}
|
|
1021
|
-
break;
|
|
1022
|
-
}
|
|
1023
|
-
case ShellStreak.OverHeal:
|
|
1024
|
-
player.hp = Math.min(200, player.hp + 100);
|
|
1025
|
-
player.streakRewards.push(ShellStreak.OverHeal);
|
|
1026
|
-
break;
|
|
1027
|
-
case ShellStreak.DoubleEggs:
|
|
1028
|
-
player.streakRewards.push(ShellStreak.DoubleEggs);
|
|
1029
|
-
break;
|
|
1030
|
-
case ShellStreak.MiniEgg:
|
|
1031
|
-
player.scale = 0.5;
|
|
1032
|
-
player.streakRewards.push(ShellStreak.MiniEgg);
|
|
1033
|
-
break;
|
|
1034
|
-
}
|
|
1035
|
-
this.emit("playerBeginStreak", player, ksType);
|
|
1036
|
-
}
|
|
1037
|
-
#processEndStreakPacket() {
|
|
1038
|
-
const id = CommIn.unPackInt8U();
|
|
1039
|
-
const ksType = CommIn.unPackInt8U();
|
|
1040
|
-
const player = this.players[id];
|
|
1041
|
-
if (!player)
|
|
1042
|
-
return;
|
|
1043
|
-
const streaks = [
|
|
1044
|
-
ShellStreak.EggBreaker,
|
|
1045
|
-
ShellStreak.OverHeal,
|
|
1046
|
-
ShellStreak.DoubleEggs,
|
|
1047
|
-
ShellStreak.MiniEgg
|
|
1048
|
-
];
|
|
1049
|
-
if (streaks.includes(ksType) && player.streakRewards.includes(ksType))
|
|
1050
|
-
player.streakRewards = player.streakRewards.filter((r) => r !== ksType);
|
|
1051
|
-
if (ksType === ShellStreak.MiniEgg)
|
|
1052
|
-
player.scale = 1;
|
|
1053
|
-
this.emit("playerEndStreak", player, ksType);
|
|
1054
|
-
}
|
|
1055
|
-
#processHitShieldPacket() {
|
|
1056
|
-
const shieldHealth = CommIn.unPackInt8U();
|
|
1057
|
-
const playerHealth = CommIn.unPackInt8U();
|
|
1058
|
-
const dx = CommIn.unPackFloat();
|
|
1059
|
-
const dz = CommIn.unPackFloat();
|
|
1060
|
-
if (!this.me)
|
|
1061
|
-
return;
|
|
1062
|
-
this.me.shieldHp = shieldHealth;
|
|
1063
|
-
this.me.hp = playerHealth;
|
|
1064
|
-
if (this.me.shieldHp <= 0) {
|
|
1065
|
-
this.me.streakRewards = this.me.streakRewards.filter((r) => r !== ShellStreak.HardBoiled);
|
|
1066
|
-
this.emit("selfShieldLost", this.me.hp, { dx, dz });
|
|
1067
|
-
} else
|
|
1068
|
-
this.emit("selfShieldHit", this.me.shieldHp, this.me.hp, { dx, dz });
|
|
1069
|
-
}
|
|
1070
|
-
#processGameOptionsPacket() {
|
|
1071
|
-
const oldOptions = { ...this.game.options };
|
|
1072
|
-
let gravity = CommIn.unPackInt8U();
|
|
1073
|
-
let damage = CommIn.unPackInt8U();
|
|
1074
|
-
let healthRegen = CommIn.unPackInt8U();
|
|
1075
|
-
if (gravity < 1 || gravity > 4) {
|
|
1076
|
-
gravity = 4;
|
|
1077
|
-
}
|
|
1078
|
-
if (damage < 0 || damage > 8) {
|
|
1079
|
-
damage = 4;
|
|
1080
|
-
}
|
|
1081
|
-
if (healthRegen > 16) {
|
|
1082
|
-
healthRegen = 4;
|
|
1083
|
-
}
|
|
1084
|
-
this.game.options.gravity = gravity / 4;
|
|
1085
|
-
this.game.options.damage = damage / 4;
|
|
1086
|
-
this.game.options.healthRegen = healthRegen / 4;
|
|
1087
|
-
const rawFlags = CommIn.unPackInt8U();
|
|
1088
|
-
Object.keys(CCGameOptionFlag).forEach((optionFlagName) => {
|
|
1089
|
-
const value = rawFlags & CCGameOptionFlag[optionFlagName] ? 1 : 0;
|
|
1090
|
-
this.game.options[optionFlagName] = value;
|
|
1091
|
-
});
|
|
1092
|
-
this.game.options.weaponsDisabled = Array.from({ length: 7 }, () => CommIn.unPackInt8U() === 1);
|
|
1093
|
-
this.game.options.mustUseSecondary = this.game.options.weaponsDisabled.every((v) => v);
|
|
1094
|
-
this.emit("gameOptionsChange", oldOptions, this.game.options);
|
|
1095
|
-
}
|
|
1096
|
-
#processGameActionPacket() {
|
|
1097
|
-
const action = CommIn.unPackInt8U();
|
|
1098
|
-
if (action === GameAction.Pause) {
|
|
1099
|
-
this.emit("gameForcePause");
|
|
1100
|
-
setTimeout(() => this.me.playing = false, 3000);
|
|
1101
|
-
}
|
|
1102
|
-
if (action === GameAction.Reset) {
|
|
1103
|
-
Object.values(this.players).forEach((player) => player.streak = 0);
|
|
1104
|
-
if (this.game.gameModeId !== GameMode.FFA)
|
|
1105
|
-
this.game.teamScore = [0, 0, 0];
|
|
1106
|
-
if (this.game.gameModeId === GameMode.Spatula) {
|
|
1107
|
-
this.game.spatula.controlledBy = 0;
|
|
1108
|
-
this.game.spatula.controlledByTeam = 0;
|
|
1109
|
-
this.game.spatula.coords = { x: 0, y: 0, z: 0 };
|
|
1110
|
-
}
|
|
1111
|
-
if (this.game.gameModeId === GameMode.KOTC) {
|
|
1112
|
-
this.game.stage = CoopState.Capturing;
|
|
1113
|
-
this.game.zoneNumber = 0;
|
|
1114
|
-
this.game.activeZone = null;
|
|
1115
|
-
this.game.capturing = 0;
|
|
1116
|
-
this.game.captureProgress = 0;
|
|
1117
|
-
this.game.numCapturing = 0;
|
|
1118
|
-
this.game.capturePercent = 0;
|
|
1119
|
-
}
|
|
1120
|
-
this.emit("gameReset");
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
#processPingPacket() {
|
|
1124
|
-
if (!this.intents.includes(this.Intents.PING))
|
|
1125
|
-
return;
|
|
1126
|
-
const oldPing = this.ping;
|
|
1127
|
-
this.ping = Date.now() - this.lastPingTime;
|
|
1128
|
-
this.emit("pingUpdate", oldPing, this.ping);
|
|
1129
|
-
setTimeout(() => {
|
|
1130
|
-
const out = new CommOut;
|
|
1131
|
-
out.packInt8(CommCode.ping);
|
|
1132
|
-
out.send(this.game.socket);
|
|
1133
|
-
this.lastPingTime = Date.now();
|
|
1134
|
-
}, 1000);
|
|
1135
|
-
}
|
|
1136
|
-
#processSwitchTeamPacket() {
|
|
1137
|
-
const id = CommIn.unPackInt8U();
|
|
1138
|
-
const toTeam = CommIn.unPackInt8U();
|
|
1139
|
-
const player = this.players[id];
|
|
1140
|
-
if (!player)
|
|
1141
|
-
return;
|
|
1142
|
-
const oldTeam = player.team;
|
|
1143
|
-
player.team = toTeam;
|
|
1144
|
-
player.streak = 0;
|
|
1145
|
-
this.emit("playerSwitchTeam", player, oldTeam, toTeam);
|
|
1146
|
-
}
|
|
1147
|
-
#processChangeCharacterPacket() {
|
|
1148
|
-
const id = CommIn.unPackInt8U();
|
|
1149
|
-
const weaponIndex = CommIn.unPackInt8U();
|
|
1150
|
-
const primaryWeaponIdx = CommIn.unPackInt16U();
|
|
1151
|
-
const secondaryWeaponIdx = CommIn.unPackInt16U();
|
|
1152
|
-
const shellColor = CommIn.unPackInt8U();
|
|
1153
|
-
const hatIdx = CommIn.unPackInt16U();
|
|
1154
|
-
const stampIdx = CommIn.unPackInt16U();
|
|
1155
|
-
const grenadeIdx = CommIn.unPackInt16U();
|
|
1156
|
-
const meleeIdx = CommIn.unPackInt16U();
|
|
1157
|
-
const stampPositionX = CommIn.unPackInt8();
|
|
1158
|
-
const stampPositionY = CommIn.unPackInt8();
|
|
1159
|
-
const findCosmetics = this.intents.includes(this.Intents.COSMETIC_DATA);
|
|
1160
|
-
const primaryWeaponItem = findCosmetics ? findItemById(primaryWeaponIdx) : primaryWeaponIdx;
|
|
1161
|
-
const secondaryWeaponItem = findCosmetics ? findItemById(secondaryWeaponIdx) : secondaryWeaponIdx;
|
|
1162
|
-
const hatItem = findCosmetics ? findItemById(hatIdx) : hatIdx;
|
|
1163
|
-
const stampItem = findCosmetics ? findItemById(stampIdx) : stampIdx;
|
|
1164
|
-
const grenadeItem = findCosmetics ? findItemById(grenadeIdx) : grenadeIdx;
|
|
1165
|
-
const meleeItem = findCosmetics ? findItemById(meleeIdx) : meleeIdx;
|
|
1166
|
-
const player = this.players[id];
|
|
1167
|
-
if (player) {
|
|
1168
|
-
const oldCharacter = { ...player.character };
|
|
1169
|
-
const oldWeaponIdx = player.selectedGun;
|
|
1170
|
-
player.character.eggColor = shellColor;
|
|
1171
|
-
player.character.primaryGun = primaryWeaponItem;
|
|
1172
|
-
player.character.secondaryGun = secondaryWeaponItem;
|
|
1173
|
-
player.character.stamp = stampItem;
|
|
1174
|
-
player.character.hat = hatItem;
|
|
1175
|
-
player.character.grenade = grenadeItem;
|
|
1176
|
-
player.character.melee = meleeItem;
|
|
1177
|
-
player.character.stampPos.x = stampPositionX;
|
|
1178
|
-
player.character.stampPos.y = stampPositionY;
|
|
1179
|
-
player.selectedGun = weaponIndex;
|
|
1180
|
-
player.weapons[0] = new GunList[weaponIndex];
|
|
1181
|
-
if (oldWeaponIdx !== player.selectedGun)
|
|
1182
|
-
this.emit("playerChangeGun", player, oldWeaponIdx, player.selectedGun);
|
|
1183
|
-
if (oldCharacter !== player.character)
|
|
1184
|
-
this.emit("playerChangeCharacter", player, oldCharacter, player.character);
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
#processUpdateBalancePacket() {
|
|
1188
|
-
const newBalance = CommIn.unPackInt32U();
|
|
1189
|
-
const oldBalance = this.account.eggBalance;
|
|
1190
|
-
this.account.eggBalance = newBalance;
|
|
1191
|
-
this.emit("balanceUpdate", oldBalance, newBalance);
|
|
1192
|
-
}
|
|
1193
|
-
#processRespawnDeniedPacket() {
|
|
1194
|
-
this.me.playing = false;
|
|
1195
|
-
this.emit("respawnDenied");
|
|
1196
|
-
}
|
|
1197
|
-
#processMeleePacket() {
|
|
1198
|
-
const id = CommIn.unPackInt8U();
|
|
1199
|
-
const player = this.players[id];
|
|
1200
|
-
if (player)
|
|
1201
|
-
this.emit("playerMelee", player);
|
|
1202
|
-
}
|
|
1203
|
-
#processReloadPacket() {
|
|
1204
|
-
const id = CommIn.unPackInt8U();
|
|
1205
|
-
const player = this.players[id];
|
|
1206
|
-
if (!player)
|
|
1207
|
-
return;
|
|
1208
|
-
const playerActiveWeapon = player.weapons[player.activeGun];
|
|
1209
|
-
if (playerActiveWeapon.ammo) {
|
|
1210
|
-
const newRounds = Math.min(Math.min(playerActiveWeapon.ammo.capacity, playerActiveWeapon.ammo.reload) - playerActiveWeapon.ammo.rounds, playerActiveWeapon.ammo.store);
|
|
1211
|
-
playerActiveWeapon.ammo.rounds += newRounds;
|
|
1212
|
-
playerActiveWeapon.ammo.store -= newRounds;
|
|
1213
|
-
}
|
|
1214
|
-
this.emit("playerReload", player, playerActiveWeapon);
|
|
835
|
+
emit(event, ...args) {
|
|
836
|
+
const dispatch = DispatchIndex[event];
|
|
837
|
+
if (dispatch)
|
|
838
|
+
this.dispatch(new dispatch(...args), true);
|
|
839
|
+
else
|
|
840
|
+
throw new Error(`no event found for "${event}"`);
|
|
1215
841
|
}
|
|
1216
842
|
updateGameOptions() {
|
|
1217
843
|
const out = new CommOut;
|
|
@@ -1221,193 +847,78 @@ export class Bot {
|
|
|
1221
847
|
out.packInt8(this.game.options.healthRegen * 4);
|
|
1222
848
|
const flags = (this.game.options.locked ? 1 : 0) | (this.game.options.noTeamChange ? 2 : 0) | (this.game.options.noTeamShuffle ? 4 : 0);
|
|
1223
849
|
out.packInt8(flags);
|
|
1224
|
-
this.game.options.weaponsDisabled.forEach((v) =>
|
|
1225
|
-
out.packInt8(v ? 1 : 0);
|
|
1226
|
-
});
|
|
850
|
+
this.game.options.weaponsDisabled.forEach((v) => out.packInt8(v ? 1 : 0));
|
|
1227
851
|
out.send(this.game.socket);
|
|
1228
852
|
}
|
|
1229
|
-
#processGameRequestOptionsPacket() {
|
|
1230
|
-
this.game.isPrivate = true;
|
|
1231
|
-
this.updateGameOptions();
|
|
1232
|
-
}
|
|
1233
|
-
#processExplodePacket() {
|
|
1234
|
-
const itemType = CommIn.unPackInt8U();
|
|
1235
|
-
let item = CommIn.unPackInt16U();
|
|
1236
|
-
const x = CommIn.unPackFloat();
|
|
1237
|
-
const y = CommIn.unPackFloat();
|
|
1238
|
-
const z = CommIn.unPackFloat();
|
|
1239
|
-
const damage = CommIn.unPackInt8U();
|
|
1240
|
-
const radius = CommIn.unPackFloat();
|
|
1241
|
-
if (this.intents.includes(this.Intents.COSMETIC_DATA))
|
|
1242
|
-
item = findItemById(item);
|
|
1243
|
-
if (itemType === ItemType.Grenade)
|
|
1244
|
-
this.emit("grenadeExplode", item, { x, y, z }, damage, radius);
|
|
1245
|
-
else
|
|
1246
|
-
this.emit("rocketHit", { x, y, z }, damage, radius);
|
|
1247
|
-
}
|
|
1248
|
-
#processThrowGrenadePacket() {
|
|
1249
|
-
const id = CommIn.unPackInt8U();
|
|
1250
|
-
const x = CommIn.unPackFloat();
|
|
1251
|
-
const y = CommIn.unPackFloat();
|
|
1252
|
-
const z = CommIn.unPackFloat();
|
|
1253
|
-
const dx = CommIn.unPackFloat();
|
|
1254
|
-
const dy = CommIn.unPackFloat();
|
|
1255
|
-
const dz = CommIn.unPackFloat();
|
|
1256
|
-
const player = this.players[id];
|
|
1257
|
-
if (player) {
|
|
1258
|
-
player.grenades--;
|
|
1259
|
-
this.emit("playerThrowGrenade", player, { x, y, z }, { x: dx, y: dy, z: dz });
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
#processChallengeCompletePacket() {
|
|
1263
|
-
const id = CommIn.unPackInt8U();
|
|
1264
|
-
const challengeId = CommIn.unPackInt8U();
|
|
1265
|
-
const player = this.players[id];
|
|
1266
|
-
if (!player)
|
|
1267
|
-
return;
|
|
1268
|
-
if (!this.intents.includes(this.Intents.CHALLENGES))
|
|
1269
|
-
return this.emit("challengeComplete", player, challengeId);
|
|
1270
|
-
const challenge = this.account.challenges.find((c) => c.id === challengeId);
|
|
1271
|
-
this.emit("challengeComplete", player, challenge);
|
|
1272
|
-
if (player.id === this.me.id)
|
|
1273
|
-
this.refreshChallenges();
|
|
1274
|
-
}
|
|
1275
|
-
#processSocketReadyPacket() {
|
|
1276
|
-
const out = new CommOut;
|
|
1277
|
-
out.packInt8(this.intents.includes(this.Intents.OBSERVE_GAME) ? CommCode.observeGame : CommCode.joinGame);
|
|
1278
|
-
out.packString(this.game.raw.uuid);
|
|
1279
|
-
out.packInt8(+this.intents.includes(this.Intents.VIP_HIDE_BADGE));
|
|
1280
|
-
out.packInt8(this.state.weaponIdx || this.account?.loadout?.classIdx || 0);
|
|
1281
|
-
out.packString(this.state.name);
|
|
1282
|
-
out.packInt32(this.account.session);
|
|
1283
|
-
out.packString(this.account.sessionId);
|
|
1284
|
-
out.packString(this.account.firebaseId);
|
|
1285
|
-
out.send(this.game.socket);
|
|
1286
|
-
}
|
|
1287
|
-
async#processGameJoinedPacket() {
|
|
1288
|
-
this.me.id = CommIn.unPackInt8U();
|
|
1289
|
-
this.me.team = CommIn.unPackInt8U();
|
|
1290
|
-
this.game.gameModeId = CommIn.unPackInt8U();
|
|
1291
|
-
this.game.gameMode = GameModeById[this.game.gameModeId];
|
|
1292
|
-
this.game.mapIdx = CommIn.unPackInt8U();
|
|
1293
|
-
this.game.map = Maps[this.game.mapIdx];
|
|
1294
|
-
this.game.playerLimit = CommIn.unPackInt8U();
|
|
1295
|
-
this.game.isGameOwner = CommIn.unPackInt8U() === 1;
|
|
1296
|
-
this.game.isPrivate = CommIn.unPackInt8U() === 1 || this.game.isGameOwner;
|
|
1297
|
-
CommIn.unPackInt8U();
|
|
1298
|
-
if (this.intents.includes(this.Intents.LOAD_MAP) || this.intents.includes(this.Intents.PATHFINDING)) {
|
|
1299
|
-
this.game.map.raw = await fetchMap(this.game.map.filename, this.game.map.hash);
|
|
1300
|
-
this.emit("mapLoad", this.game.map.raw);
|
|
1301
|
-
if (this.game.gameModeId === GameMode.KOTC) {
|
|
1302
|
-
const meshData = this.game.map.raw.data["DYNAMIC.capture-zone.none"];
|
|
1303
|
-
if (meshData) {
|
|
1304
|
-
this.game.map.zones = initKotcZones(meshData);
|
|
1305
|
-
if (!this.game.activeZone)
|
|
1306
|
-
this.game.activeZone = this.game.map.zones[this.game.zoneNumber - 1];
|
|
1307
|
-
} else
|
|
1308
|
-
delete this.game.map.zones;
|
|
1309
|
-
}
|
|
1310
|
-
if (this.intents.includes(this.Intents.PATHFINDING))
|
|
1311
|
-
this.pathing.nodeList = new NodeList(this.game.map.raw);
|
|
1312
|
-
}
|
|
1313
|
-
this.state.inGame = true;
|
|
1314
|
-
this.lastDeathTime = Date.now();
|
|
1315
|
-
const out = new CommOut;
|
|
1316
|
-
out.packInt8(CommCode.clientReady);
|
|
1317
|
-
out.send(this.game.socket);
|
|
1318
|
-
this.updateIntervalId = setInterval(() => this.update(), 100 / 3);
|
|
1319
|
-
if (this.intents.includes(this.Intents.PING)) {
|
|
1320
|
-
this.lastPingTime = Date.now();
|
|
1321
|
-
const out2 = new CommOut;
|
|
1322
|
-
out2.packInt8(CommCode.ping);
|
|
1323
|
-
out2.send(this.game.socket);
|
|
1324
|
-
}
|
|
1325
|
-
if (this.intents.includes(this.Intents.NO_AFK_KICK))
|
|
1326
|
-
this.afkKickInterval = setInterval(() => {
|
|
1327
|
-
if (this.state.inGame && !this.me.playing && Date.now() - this.lastDeathTime >= 15000) {
|
|
1328
|
-
const out3 = new CommOut;
|
|
1329
|
-
out3.packInt8(CommCode.keepAlive);
|
|
1330
|
-
out3.send(this.game.socket);
|
|
1331
|
-
}
|
|
1332
|
-
}, 15000);
|
|
1333
|
-
this.emit("gameReady");
|
|
1334
|
-
}
|
|
1335
|
-
#processPlayerInfoPacket() {
|
|
1336
|
-
const playerId = CommIn.unPackInt8U();
|
|
1337
|
-
const playerDBId = CommIn.unPackString(128);
|
|
1338
|
-
const playerIp = CommIn.unPackString(32);
|
|
1339
|
-
const player = this.players[playerId];
|
|
1340
|
-
if (!player)
|
|
1341
|
-
return;
|
|
1342
|
-
player.admin = {
|
|
1343
|
-
ip: playerIp,
|
|
1344
|
-
dbId: playerDBId
|
|
1345
|
-
};
|
|
1346
|
-
this.emit("playerInfo", player, playerIp, playerDBId);
|
|
1347
|
-
}
|
|
1348
853
|
packetHandlers = {
|
|
1349
|
-
[CommCode.syncThem]: (
|
|
1350
|
-
[CommCode.fire]: (
|
|
1351
|
-
[CommCode.hitThem]: (
|
|
1352
|
-
[CommCode.syncMe]: (
|
|
1353
|
-
[CommCode.hitMe]: (
|
|
1354
|
-
[CommCode.swapWeapon]: (
|
|
1355
|
-
[CommCode.collectItem]: (
|
|
1356
|
-
[CommCode.respawn]: (
|
|
1357
|
-
[CommCode.die]: (
|
|
1358
|
-
[CommCode.pause]: (
|
|
1359
|
-
[CommCode.chat]: (
|
|
1360
|
-
[CommCode.addPlayer]: (
|
|
1361
|
-
[CommCode.removePlayer]: (
|
|
1362
|
-
[CommCode.eventModifier]: (
|
|
1363
|
-
[CommCode.metaGameState]: (
|
|
1364
|
-
[CommCode.beginShellStreak]: (
|
|
1365
|
-
[CommCode.endShellStreak]: (
|
|
1366
|
-
[CommCode.hitMeHardBoiled]: (
|
|
1367
|
-
[CommCode.gameOptions]: (
|
|
1368
|
-
[CommCode.ping]: (
|
|
1369
|
-
[CommCode.switchTeam]: (
|
|
1370
|
-
[CommCode.changeCharacter]: (
|
|
1371
|
-
[CommCode.reload]: (
|
|
1372
|
-
[CommCode.explode]: (
|
|
1373
|
-
[CommCode.throwGrenade]: (
|
|
1374
|
-
[CommCode.spawnItem]: (
|
|
1375
|
-
[CommCode.melee]: (
|
|
1376
|
-
[CommCode.updateBalance]: (
|
|
1377
|
-
[CommCode.challengeCompleted]: (
|
|
1378
|
-
[CommCode.
|
|
1379
|
-
[CommCode.
|
|
1380
|
-
[CommCode.
|
|
1381
|
-
[CommCode.
|
|
1382
|
-
[CommCode.respawnDenied]: () =>
|
|
1383
|
-
|
|
854
|
+
[CommCode.syncThem]: processSyncThemPacket.bind(null, this),
|
|
855
|
+
[CommCode.fire]: processFirePacket.bind(null, this),
|
|
856
|
+
[CommCode.hitThem]: processHitThemPacket.bind(null, this),
|
|
857
|
+
[CommCode.syncMe]: processSyncMePacket.bind(null, this),
|
|
858
|
+
[CommCode.hitMe]: processHitMePacket.bind(null, this),
|
|
859
|
+
[CommCode.swapWeapon]: processSwapWeaponPacket.bind(null, this),
|
|
860
|
+
[CommCode.collectItem]: processCollectItemPacket.bind(null, this),
|
|
861
|
+
[CommCode.respawn]: processRespawnPacket.bind(null, this),
|
|
862
|
+
[CommCode.die]: processDiePacket.bind(null, this),
|
|
863
|
+
[CommCode.pause]: processPausePacket.bind(null, this),
|
|
864
|
+
[CommCode.chat]: processChatPacket.bind(null, this),
|
|
865
|
+
[CommCode.addPlayer]: processAddPlayerPacket.bind(null, this),
|
|
866
|
+
[CommCode.removePlayer]: processRemovePlayerPacket.bind(null, this),
|
|
867
|
+
[CommCode.eventModifier]: processEventModifierPacket.bind(null, this),
|
|
868
|
+
[CommCode.metaGameState]: processMetaGameStatePacket.bind(null, this),
|
|
869
|
+
[CommCode.beginShellStreak]: processBeginShellStreakPacket.bind(null, this),
|
|
870
|
+
[CommCode.endShellStreak]: processEndShellStreakPacket.bind(null, this),
|
|
871
|
+
[CommCode.hitMeHardBoiled]: processHitMeHardBoiledPacket.bind(null, this),
|
|
872
|
+
[CommCode.gameOptions]: processGameOptionsPacket.bind(null, this),
|
|
873
|
+
[CommCode.ping]: processPingPacket.bind(null, this),
|
|
874
|
+
[CommCode.switchTeam]: processSwitchTeamPacket.bind(null, this),
|
|
875
|
+
[CommCode.changeCharacter]: processChangeCharacterPacket.bind(null, this),
|
|
876
|
+
[CommCode.reload]: processReloadPacket.bind(null, this),
|
|
877
|
+
[CommCode.explode]: processExplodePacket.bind(null, this),
|
|
878
|
+
[CommCode.throwGrenade]: processThrowGrenadePacket.bind(null, this),
|
|
879
|
+
[CommCode.spawnItem]: processSpawnItemPacket.bind(null, this),
|
|
880
|
+
[CommCode.melee]: processMeleePacket.bind(null, this),
|
|
881
|
+
[CommCode.updateBalance]: processUpdateBalancePacket.bind(null, this),
|
|
882
|
+
[CommCode.challengeCompleted]: processChallengeCompletedPacket.bind(null, this),
|
|
883
|
+
[CommCode.gameAction]: processGameActionPacket.bind(null, this),
|
|
884
|
+
[CommCode.socketReady]: processSocketReadyPacket.bind(null, this),
|
|
885
|
+
[CommCode.gameJoined]: processGameJoinedPacket.bind(null, this),
|
|
886
|
+
[CommCode.playerInfo]: processPlayerInfoPacket.bind(null, this),
|
|
887
|
+
[CommCode.respawnDenied]: () => {
|
|
888
|
+
this.me.playing = false;
|
|
889
|
+
this.$emit("respawnDenied");
|
|
890
|
+
},
|
|
891
|
+
[CommCode.requestGameOptions]: () => {
|
|
892
|
+
this.game.isPrivate = true;
|
|
893
|
+
this.updateGameOptions();
|
|
894
|
+
},
|
|
1384
895
|
[CommCode.expireUpgrade]: () => {},
|
|
1385
896
|
[CommCode.clientReady]: () => {},
|
|
1386
897
|
[CommCode.musicInfo]: () => CommIn.unPackLongString()
|
|
1387
898
|
};
|
|
1388
899
|
processPacket(packet) {
|
|
900
|
+
if (this.hasQuit)
|
|
901
|
+
return;
|
|
1389
902
|
CommIn.init(packet);
|
|
1390
|
-
if (this.intents.includes(
|
|
1391
|
-
this
|
|
903
|
+
if (this.intents.includes(Intents.PACKET_HOOK))
|
|
904
|
+
this.$emit("packet", packet);
|
|
1392
905
|
let lastCommand = 0;
|
|
1393
906
|
let lastCode = 0;
|
|
1394
|
-
|
|
1395
|
-
while (CommIn.isMoreDataAvailable() && !abort) {
|
|
907
|
+
while (CommIn.isMoreDataAvailable()) {
|
|
1396
908
|
const cmd = CommIn.unPackInt8U();
|
|
1397
909
|
const handler = this.packetHandlers[cmd];
|
|
1398
910
|
if (handler)
|
|
1399
911
|
handler();
|
|
1400
912
|
else {
|
|
1401
|
-
console.error(`processPacket:
|
|
913
|
+
console.error(`processPacket: got but couldn't identify: ${Object.keys(CommCode).find((k) => CommCode[k] === cmd)} ${cmd}`);
|
|
1402
914
|
if (lastCommand)
|
|
1403
|
-
console.error(`processPacket:
|
|
1404
|
-
abort = true;
|
|
915
|
+
console.error(`processPacket: it may be a result of the ${lastCommand} command (${lastCode}).`);
|
|
1405
916
|
break;
|
|
1406
917
|
}
|
|
1407
918
|
lastCommand = Object.keys(CommCode).find((k) => CommCode[k] === cmd);
|
|
1408
919
|
lastCode = cmd;
|
|
1409
|
-
if (this.intents.includes(
|
|
1410
|
-
console.log(`[LOG_PACKETS]
|
|
920
|
+
if (this.intents.includes(Intents.LOG_PACKETS))
|
|
921
|
+
console.log(`[LOG_PACKETS] packet ${lastCommand}: ${lastCode}`);
|
|
1411
922
|
}
|
|
1412
923
|
}
|
|
1413
924
|
async checkChiknWinner() {
|
|
@@ -1416,19 +927,19 @@ export class Bot {
|
|
|
1416
927
|
id: this.account.id,
|
|
1417
928
|
sessionId: this.account.sessionId
|
|
1418
929
|
});
|
|
1419
|
-
if (
|
|
930
|
+
if (!response.ok)
|
|
1420
931
|
return response;
|
|
1421
932
|
this.account.cw.limit = response.limit;
|
|
1422
933
|
this.account.cw.atLimit = response.limit >= 4;
|
|
1423
934
|
this.account.cw.secondsUntilPlay = (this.account.cw.atLimit ? response.period : response.span) || 0;
|
|
1424
935
|
this.account.cw.canPlayAgain = Date.now() + this.account.cw.secondsUntilPlay * 1000;
|
|
1425
|
-
return this.account.cw;
|
|
936
|
+
return { ok: true, cw: this.account.cw };
|
|
1426
937
|
}
|
|
1427
938
|
async playChiknWinner(doPrematureCooldownCheck = true) {
|
|
1428
939
|
if (this.account.cw.atLimit || this.account.cw.limit > ChiknWinnerDailyLimit)
|
|
1429
|
-
return
|
|
940
|
+
return createError(ChicknWinnerError.HitDailyLimit);
|
|
1430
941
|
if (this.account.cw.canPlayAgain > Date.now() && doPrematureCooldownCheck)
|
|
1431
|
-
return
|
|
942
|
+
return createError(ChicknWinnerError.OnCooldown);
|
|
1432
943
|
const response = await this.api.queryServices({
|
|
1433
944
|
cmd: "incentivizedVideoReward",
|
|
1434
945
|
firebaseId: this.account.firebaseId,
|
|
@@ -1436,62 +947,73 @@ export class Bot {
|
|
|
1436
947
|
sessionId: this.account.sessionId,
|
|
1437
948
|
token: null
|
|
1438
949
|
});
|
|
1439
|
-
if (
|
|
950
|
+
if (!response.ok)
|
|
1440
951
|
return response;
|
|
1441
952
|
if (response.error) {
|
|
1442
953
|
if (response.error === "RATELIMITED" || response.error === "RATELMITED") {
|
|
1443
954
|
await this.checkChiknWinner();
|
|
1444
|
-
return
|
|
955
|
+
return createError(ChicknWinnerError.OnCooldown);
|
|
1445
956
|
} else if (response.error === "SESSION_EXPIRED") {
|
|
1446
|
-
this
|
|
1447
|
-
return
|
|
957
|
+
this.$emit("sessionExpired");
|
|
958
|
+
return createError(ChicknWinnerError.SessionExpired);
|
|
1448
959
|
}
|
|
1449
|
-
|
|
1450
|
-
return
|
|
960
|
+
this.errorLogger("unknown Chikn Winner response, report this on Github:", response);
|
|
961
|
+
return createError(ChicknWinnerError.InternalError);
|
|
1451
962
|
}
|
|
1452
963
|
if (response.reward) {
|
|
1453
964
|
this.account.eggBalance += response.reward.eggsGiven;
|
|
1454
965
|
response.reward.itemIds.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1455
966
|
await this.checkChiknWinner();
|
|
1456
|
-
return response.reward;
|
|
967
|
+
return { ok: true, ...response.reward };
|
|
1457
968
|
}
|
|
1458
|
-
|
|
1459
|
-
return
|
|
969
|
+
this.errorLogger("unknown Chikn Winner response, report this on Github:", response);
|
|
970
|
+
return createError(ChicknWinnerError.InternalError);
|
|
1460
971
|
}
|
|
1461
972
|
async resetChiknWinner() {
|
|
1462
973
|
if (this.account.eggBalance < 200)
|
|
1463
|
-
return
|
|
974
|
+
return createError(ChicknWinnerError.NotEnoughResetEggs);
|
|
1464
975
|
if (!this.account.cw.atLimit)
|
|
1465
|
-
return
|
|
976
|
+
return createError(ChicknWinnerError.NotAtDailyLimit);
|
|
1466
977
|
const response = await this.api.queryServices({
|
|
1467
978
|
cmd: "chwReset",
|
|
1468
979
|
sessionId: this.account.sessionId
|
|
1469
980
|
});
|
|
1470
|
-
if (
|
|
981
|
+
if (!response.ok)
|
|
1471
982
|
return response;
|
|
1472
983
|
if (response.result !== "SUCCESS") {
|
|
1473
|
-
|
|
1474
|
-
return
|
|
984
|
+
this.errorLogger("unknown Chikn Winner reset response, report this on Github:", response);
|
|
985
|
+
return createError(ChicknWinnerError.InternalError);
|
|
1475
986
|
}
|
|
1476
987
|
this.account.eggBalance -= 200;
|
|
1477
988
|
await this.checkChiknWinner();
|
|
1478
|
-
return this.account.cw;
|
|
989
|
+
return { ok: true, cw: this.account.cw };
|
|
1479
990
|
}
|
|
1480
991
|
canSee(target) {
|
|
1481
|
-
if (!this.intents.includes(
|
|
1482
|
-
|
|
992
|
+
if (!this.intents.includes(Intents.PATHFINDING))
|
|
993
|
+
throw new Error("canSee: you need enable the PATHFINDING intent");
|
|
1483
994
|
return this.pathing.nodeList.hasLineOfSight(this.me.position, target.position);
|
|
1484
995
|
}
|
|
996
|
+
getBestTarget() {
|
|
997
|
+
const options = Object.values(this.players).filter((player) => player?.playing).filter((player) => player.hp > 0).filter((player) => player.id !== this.me.id).filter((player) => this.me.team === 0 || player.team !== this.me.team);
|
|
998
|
+
const distancePlayers = options.map((player) => ({
|
|
999
|
+
player,
|
|
1000
|
+
distance: (player.position.x - this.me.position.x) ** 2 + 5 * (player.position.y - this.me.position.y) ** 2 + (player.position.z - this.me.position.z) ** 2
|
|
1001
|
+
})).sort((a, b) => a.distance - b.distance);
|
|
1002
|
+
if (distancePlayers.length)
|
|
1003
|
+
return distancePlayers[0].player;
|
|
1004
|
+
else
|
|
1005
|
+
return null;
|
|
1006
|
+
}
|
|
1485
1007
|
async refreshChallenges() {
|
|
1486
1008
|
const result = await this.api.queryServices({
|
|
1487
1009
|
cmd: "challengeGetDaily",
|
|
1488
1010
|
sessionId: this.account.sessionId,
|
|
1489
1011
|
playerId: this.account.id
|
|
1490
1012
|
});
|
|
1491
|
-
if (
|
|
1013
|
+
if (!result.ok)
|
|
1492
1014
|
return result;
|
|
1493
1015
|
this.#importChallenges(result);
|
|
1494
|
-
return this.account.challenges;
|
|
1016
|
+
return { ok: true, challenges: this.account.challenges };
|
|
1495
1017
|
}
|
|
1496
1018
|
async rerollChallenge(challengeId) {
|
|
1497
1019
|
const result = await this.api.queryServices({
|
|
@@ -1499,10 +1021,17 @@ export class Bot {
|
|
|
1499
1021
|
sessionId: this.account.sessionId,
|
|
1500
1022
|
slotId: challengeId
|
|
1501
1023
|
});
|
|
1502
|
-
if (
|
|
1024
|
+
if (!result.ok)
|
|
1503
1025
|
return result;
|
|
1504
|
-
|
|
1505
|
-
|
|
1026
|
+
if (result["0"]) {
|
|
1027
|
+
this.#importChallenges(Object.values(result));
|
|
1028
|
+
return { ok: true, challenges: this.account.challenges };
|
|
1029
|
+
}
|
|
1030
|
+
const isInEnum = Object.values(ChallengeRerollError).includes(result.error);
|
|
1031
|
+
if (isInEnum)
|
|
1032
|
+
return { ok: false, error: result.error };
|
|
1033
|
+
this.errorLogger("rerollChallenge: unknown error response", result);
|
|
1034
|
+
return { ok: false, error: ChallengeRerollError.InternalError };
|
|
1506
1035
|
}
|
|
1507
1036
|
async claimChallenge(challengeId) {
|
|
1508
1037
|
const result = await this.api.queryServices({
|
|
@@ -1510,15 +1039,19 @@ export class Bot {
|
|
|
1510
1039
|
sessionId: this.account.sessionId,
|
|
1511
1040
|
slotId: challengeId
|
|
1512
1041
|
});
|
|
1513
|
-
if (
|
|
1042
|
+
if (!result.ok)
|
|
1514
1043
|
return result;
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
eggReward: result.reward,
|
|
1520
|
-
|
|
1521
|
-
|
|
1044
|
+
if (result.reward) {
|
|
1045
|
+
this.#importChallenges(result.challenges);
|
|
1046
|
+
if (result.reward > 0)
|
|
1047
|
+
this.account.eggBalance += result.reward;
|
|
1048
|
+
return { ok: true, eggReward: result.reward, updatedChallenges: this.account.challenges };
|
|
1049
|
+
}
|
|
1050
|
+
const isInEnum = Object.values(ChallengeClaimError).includes(result.error);
|
|
1051
|
+
if (isInEnum)
|
|
1052
|
+
return { ok: false, error: result.error };
|
|
1053
|
+
this.errorLogger("claimChallenge: unknown error response", result);
|
|
1054
|
+
return { ok: false, error: ChallengeClaimError.InternalError };
|
|
1522
1055
|
}
|
|
1523
1056
|
async refreshBalance() {
|
|
1524
1057
|
const result = await this.api.queryServices({
|
|
@@ -1526,10 +1059,10 @@ export class Bot {
|
|
|
1526
1059
|
firebaseId: this.account.firebaseId,
|
|
1527
1060
|
sessionId: this.account.sessionId
|
|
1528
1061
|
});
|
|
1529
|
-
if (
|
|
1062
|
+
if (!result.ok)
|
|
1530
1063
|
return result;
|
|
1531
1064
|
this.account.eggBalance = result.currentBalance;
|
|
1532
|
-
return result.currentBalance;
|
|
1065
|
+
return { ok: true, currentBalance: result.currentBalance };
|
|
1533
1066
|
}
|
|
1534
1067
|
async redeemCode(code) {
|
|
1535
1068
|
const result = await this.api.queryServices({
|
|
@@ -1539,18 +1072,18 @@ export class Bot {
|
|
|
1539
1072
|
id: this.account.id,
|
|
1540
1073
|
code
|
|
1541
1074
|
});
|
|
1542
|
-
if (
|
|
1075
|
+
if (!result.ok)
|
|
1543
1076
|
return result;
|
|
1544
1077
|
if (result.result === "SUCCESS") {
|
|
1545
|
-
this.account.eggBalance
|
|
1078
|
+
this.account.eggBalance += result.eggs_given;
|
|
1546
1079
|
result.item_ids.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1547
|
-
return {
|
|
1548
|
-
result,
|
|
1549
|
-
eggsGiven: result.eggs_given,
|
|
1550
|
-
itemIds: result.item_ids
|
|
1551
|
-
};
|
|
1080
|
+
return { ok: true, eggsGiven: result.eggs_given, itemIds: result.item_ids };
|
|
1552
1081
|
}
|
|
1553
|
-
|
|
1082
|
+
const isInEnum = Object.values(RedeemCodeError).includes(result.result);
|
|
1083
|
+
if (isInEnum)
|
|
1084
|
+
return { ok: false, error: result.result };
|
|
1085
|
+
this.errorLogger("redeemCode: unknown error response", result);
|
|
1086
|
+
return { ok: false, error: RedeemCodeError.InternalError };
|
|
1554
1087
|
}
|
|
1555
1088
|
async claimURLReward(reward) {
|
|
1556
1089
|
const result = await this.api.queryServices({
|
|
@@ -1559,13 +1092,18 @@ export class Bot {
|
|
|
1559
1092
|
sessionId: this.account.sessionId,
|
|
1560
1093
|
reward
|
|
1561
1094
|
});
|
|
1562
|
-
if (
|
|
1095
|
+
if (!result.ok)
|
|
1563
1096
|
return result;
|
|
1564
1097
|
if (result.result === "SUCCESS") {
|
|
1565
1098
|
this.account.eggBalance += result.eggsGiven;
|
|
1566
1099
|
result.itemIds.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1100
|
+
return { ok: true, eggsGiven: result.eggsGiven, itemIds: result.itemIds };
|
|
1567
1101
|
}
|
|
1568
|
-
|
|
1102
|
+
const isInEnum = Object.values(ClaimURLError).includes(result.result);
|
|
1103
|
+
if (isInEnum)
|
|
1104
|
+
return { ok: false, error: result.result };
|
|
1105
|
+
this.errorLogger("claimURLReward: unknown error response", result);
|
|
1106
|
+
return { ok: false, error: ClaimURLError.InternalError };
|
|
1569
1107
|
}
|
|
1570
1108
|
async claimSocialReward(rewardTag) {
|
|
1571
1109
|
const result = await this.api.queryServices({
|
|
@@ -1574,13 +1112,18 @@ export class Bot {
|
|
|
1574
1112
|
sessionId: this.account.sessionId,
|
|
1575
1113
|
rewardTag
|
|
1576
1114
|
});
|
|
1577
|
-
if (
|
|
1115
|
+
if (!result.ok)
|
|
1578
1116
|
return result;
|
|
1579
1117
|
if (result.result === "SUCCESS") {
|
|
1580
1118
|
this.account.eggBalance += result.eggsGiven;
|
|
1581
1119
|
result.itemIds.forEach((id) => this.account.ownedItemIds.push(id));
|
|
1120
|
+
return { ok: true, eggsGiven: result.eggsGiven, itemIds: result.itemIds };
|
|
1582
1121
|
}
|
|
1583
|
-
|
|
1122
|
+
const isInEnum = Object.values(ClaimSocialError).includes(result.result);
|
|
1123
|
+
if (isInEnum)
|
|
1124
|
+
return { ok: false, error: result.result };
|
|
1125
|
+
this.errorLogger("claimSocialReward: unknown error response", result);
|
|
1126
|
+
return { ok: false, error: ClaimSocialError.InternalError };
|
|
1584
1127
|
}
|
|
1585
1128
|
async buyItem(itemId) {
|
|
1586
1129
|
const result = await this.api.queryServices({
|
|
@@ -1590,34 +1133,32 @@ export class Bot {
|
|
|
1590
1133
|
itemId,
|
|
1591
1134
|
save: true
|
|
1592
1135
|
});
|
|
1593
|
-
if (
|
|
1136
|
+
if (!result.ok)
|
|
1594
1137
|
return result;
|
|
1595
1138
|
if (result.result === "SUCCESS") {
|
|
1596
1139
|
this.account.eggBalance = result.currentBalance;
|
|
1597
1140
|
this.account.ownedItemIds.push(result.itemId);
|
|
1141
|
+
return { ok: true, itemId: result.itemId, currentBalance: result.currentBalance };
|
|
1598
1142
|
}
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
this.emit("error", error);
|
|
1605
|
-
else if (this.intents.includes(this.Intents.NO_EXIT_ON_ERROR))
|
|
1606
|
-
console.error(error);
|
|
1607
|
-
else
|
|
1608
|
-
throw new Error(error);
|
|
1143
|
+
const isInEnum = Object.values(BuyItemError).includes(result.result);
|
|
1144
|
+
if (isInEnum)
|
|
1145
|
+
return { ok: false, error: result.result };
|
|
1146
|
+
this.errorLogger("buyItem: unknown error response", result);
|
|
1147
|
+
return { ok: false, error: BuyItemError.InternalError };
|
|
1609
1148
|
}
|
|
1610
1149
|
leave(code = CloseCode.mainMenu) {
|
|
1611
1150
|
if (this.hasQuit)
|
|
1612
1151
|
return;
|
|
1152
|
+
this.state.inGame = false;
|
|
1613
1153
|
if (code > -1) {
|
|
1614
1154
|
this.game?.socket?.close(code);
|
|
1615
|
-
this
|
|
1616
|
-
this.emit("leave", code);
|
|
1155
|
+
this.$emit("leave", code);
|
|
1617
1156
|
}
|
|
1618
|
-
|
|
1157
|
+
if (this.updateIntervalId)
|
|
1158
|
+
clearInterval(this.updateIntervalId);
|
|
1159
|
+
if (this.pingTimeoutId)
|
|
1160
|
+
clearTimeout(this.pingTimeoutId);
|
|
1619
1161
|
this.#dispatches = [];
|
|
1620
|
-
this.state.inGame = false;
|
|
1621
1162
|
this.state.chatLines = 0;
|
|
1622
1163
|
this.state.reloading = false;
|
|
1623
1164
|
this.state.swappingGun = false;
|
|
@@ -1632,10 +1173,8 @@ export class Bot {
|
|
|
1632
1173
|
this.ping = 0;
|
|
1633
1174
|
this.lastPingTime = -1;
|
|
1634
1175
|
this.lastDeathTime = -1;
|
|
1635
|
-
this.lastUpdateTick = 0;
|
|
1636
1176
|
this.pathing = {
|
|
1637
1177
|
nodeList: null,
|
|
1638
|
-
followingPath: false,
|
|
1639
1178
|
activePath: null,
|
|
1640
1179
|
activeNode: null,
|
|
1641
1180
|
activeNodeIdx: 0
|
|
@@ -1643,37 +1182,45 @@ export class Bot {
|
|
|
1643
1182
|
}
|
|
1644
1183
|
logout() {
|
|
1645
1184
|
this.account = this.#initialAccount;
|
|
1646
|
-
if (this.intents.includes(
|
|
1185
|
+
if (this.intents.includes(Intents.RENEW_SESSION))
|
|
1647
1186
|
clearInterval(this.renewSessionInterval);
|
|
1648
1187
|
}
|
|
1649
|
-
quit(
|
|
1188
|
+
quit(cleanupLevel = CleanupLevel.Partial) {
|
|
1650
1189
|
if (this.hasQuit)
|
|
1651
1190
|
return;
|
|
1191
|
+
this.hasQuit = true;
|
|
1652
1192
|
this.leave();
|
|
1653
1193
|
if (this.matchmaker) {
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1194
|
+
try {
|
|
1195
|
+
this.matchmaker.close();
|
|
1196
|
+
} catch {}
|
|
1197
|
+
if (cleanupLevel >= CleanupLevel.Partial)
|
|
1198
|
+
this.matchmaker = null;
|
|
1657
1199
|
}
|
|
1658
|
-
if (
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1200
|
+
if (this.intents.includes(Intents.NO_AFK_KICK))
|
|
1201
|
+
clearInterval(this.afkKickInterval);
|
|
1202
|
+
if (this.intents.includes(Intents.RENEW_SESSION))
|
|
1203
|
+
clearInterval(this.renewSessionInterval);
|
|
1204
|
+
if (this.pingTimeoutId)
|
|
1205
|
+
clearTimeout(this.pingTimeoutId);
|
|
1206
|
+
if (cleanupLevel >= CleanupLevel.Partial) {
|
|
1207
|
+
this.api = null;
|
|
1208
|
+
this.packetHandlers = null;
|
|
1209
|
+
this.pathing = null;
|
|
1666
1210
|
this.#initialAccount = {};
|
|
1667
1211
|
this.#initialGame = {};
|
|
1668
1212
|
this.#hooks = {};
|
|
1669
1213
|
this.#globalHooks = [];
|
|
1670
1214
|
this.#dispatches = [];
|
|
1215
|
+
this.matchmakerListeners = [];
|
|
1216
|
+
if (cleanupLevel >= CleanupLevel.Full) {
|
|
1217
|
+
this.account = null;
|
|
1218
|
+
this.game = null;
|
|
1219
|
+
this.me = null;
|
|
1220
|
+
this.players = null;
|
|
1221
|
+
this.state = null;
|
|
1222
|
+
}
|
|
1671
1223
|
}
|
|
1672
|
-
if (this.intents.includes(this.Intents.NO_AFK_KICK))
|
|
1673
|
-
clearInterval(this.afkKickInterval);
|
|
1674
|
-
if (this.intents.includes(this.Intents.RENEW_SESSION))
|
|
1675
|
-
clearInterval(this.renewSessionInterval);
|
|
1676
|
-
this.hasQuit = true;
|
|
1677
1224
|
}
|
|
1678
1225
|
}
|
|
1679
1226
|
export default Bot;
|