bonktools 2.3.0 → 3.1.0
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/bonk_fullchain.pem +37 -0
- package/examples/host-bot.js +63 -0
- package/examples/simple-bot.js +127 -0
- package/old/bonkbot.js +1266 -0
- package/old/examplebot.js +64 -0
- package/package.json +6 -8
- package/scripts/download-cert.js +52 -0
- package/src/bot.js +1498 -0
- package/src/packet.js +374 -0
- package/src/utils/constants.js +153 -0
- package/src/utils/errors.js +137 -0
- package/src/utils/logger.js +109 -0
- package/src/utils/validation.js +130 -0
package/src/packet.js
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Packet parser for BonkBot
|
|
3
|
+
*/
|
|
4
|
+
const {
|
|
5
|
+
SERVER_MESSAGE_TYPES,
|
|
6
|
+
CLIENT_MESSAGE_TYPES,
|
|
7
|
+
} = require("./utils/constants");
|
|
8
|
+
const {
|
|
9
|
+
createLogger
|
|
10
|
+
} = require("./utils/logger");
|
|
11
|
+
// Create logger
|
|
12
|
+
const logger = createLogger("PacketParser");
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Parse a packet array into a normalized object
|
|
16
|
+
* @param {Array} packet - Packet array from socket
|
|
17
|
+
* @returns {Object} Normalized packet object
|
|
18
|
+
*/
|
|
19
|
+
function parsePacket(packet) {
|
|
20
|
+
if (!Array.isArray(packet) || packet.length < 1) {
|
|
21
|
+
return {
|
|
22
|
+
type: "unknown",
|
|
23
|
+
raw: packet
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const messageType = packet[0];
|
|
28
|
+
|
|
29
|
+
// Handle server-to-client packets (incoming)
|
|
30
|
+
switch (messageType) {
|
|
31
|
+
case SERVER_MESSAGE_TYPES.PLAYER_PINGS:
|
|
32
|
+
return {
|
|
33
|
+
type: "PLAYER_PINGS",
|
|
34
|
+
pings: packet[1],
|
|
35
|
+
pingId: packet[2],
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
case SERVER_MESSAGE_TYPES.ROOM_ADDRESS:
|
|
39
|
+
return {
|
|
40
|
+
type: "ROOM_ADDRESS",
|
|
41
|
+
address: packet[1],
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
case SERVER_MESSAGE_TYPES.JOIN_ROOM:
|
|
45
|
+
return {
|
|
46
|
+
type: "JOIN_ROOM",
|
|
47
|
+
myid: packet[1],
|
|
48
|
+
hostid: packet[2],
|
|
49
|
+
playerdata: packet[3],
|
|
50
|
+
timestamp: packet[4],
|
|
51
|
+
teamslocked: packet[5],
|
|
52
|
+
roomid: packet[6],
|
|
53
|
+
roombypass: packet[7],
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
case SERVER_MESSAGE_TYPES.PLAYER_JOIN:
|
|
57
|
+
const isGuest = packet[4] === true;
|
|
58
|
+
return {
|
|
59
|
+
type: "PLAYER_JOIN",
|
|
60
|
+
id: packet[1],
|
|
61
|
+
peerID: packet[2],
|
|
62
|
+
username: packet[3],
|
|
63
|
+
guest: isGuest,
|
|
64
|
+
level: isGuest ? "0" : packet[5],
|
|
65
|
+
team: packet[6] || 1, // Default to FFA if not provided
|
|
66
|
+
avatar: packet[packet.length - 1], // Avatar is always the last item
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
case SERVER_MESSAGE_TYPES.PLAYER_LEAVE:
|
|
70
|
+
return {
|
|
71
|
+
type: "PLAYER_LEAVE",
|
|
72
|
+
id: packet[1],
|
|
73
|
+
tick: packet[2],
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
case SERVER_MESSAGE_TYPES.HOST_LEAVE:
|
|
77
|
+
if (packet[2] === -1) {
|
|
78
|
+
return {
|
|
79
|
+
type: "HOST_LEAVE",
|
|
80
|
+
gameclose: true,
|
|
81
|
+
oldid: packet[1],
|
|
82
|
+
};
|
|
83
|
+
} else {
|
|
84
|
+
return {
|
|
85
|
+
type: "HOST_LEAVE",
|
|
86
|
+
gameclose: false,
|
|
87
|
+
oldid: packet[1],
|
|
88
|
+
newid: packet[2],
|
|
89
|
+
timestamp: packet[3],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
case SERVER_MESSAGE_TYPES.PLAYER_INPUT:
|
|
94
|
+
let invalid = false
|
|
95
|
+
if (
|
|
96
|
+
!packet[2] ||
|
|
97
|
+
!packet[2].hasOwnProperty("f") ||
|
|
98
|
+
!packet[2].hasOwnProperty("c") ||
|
|
99
|
+
!packet[2].hasOwnProperty("i")
|
|
100
|
+
) {
|
|
101
|
+
invalid = true
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
type: "PLAYER_INPUT",
|
|
106
|
+
id: packet[1],
|
|
107
|
+
input: packet[2].i,
|
|
108
|
+
frame: packet[2].f,
|
|
109
|
+
sequence: packet[2].c,
|
|
110
|
+
invalid: invalid,
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
case SERVER_MESSAGE_TYPES.READY_CHANGE:
|
|
114
|
+
return {
|
|
115
|
+
type: "READY_CHANGE",
|
|
116
|
+
id: packet[1],
|
|
117
|
+
ready: packet[2],
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
case SERVER_MESSAGE_TYPES.GAME_END:
|
|
121
|
+
return {
|
|
122
|
+
type: "GAME_END"
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
case SERVER_MESSAGE_TYPES.GAME_START:
|
|
126
|
+
return {
|
|
127
|
+
type: "GAME_START",
|
|
128
|
+
timestamp: packet[1],
|
|
129
|
+
mapData: packet[2],
|
|
130
|
+
state: packet[3],
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
case SERVER_MESSAGE_TYPES.STATUS_MESSAGE:
|
|
134
|
+
return {
|
|
135
|
+
type: "STATUS_MESSAGE",
|
|
136
|
+
status: packet[1],
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
case SERVER_MESSAGE_TYPES.TEAM_CHANGE:
|
|
140
|
+
return {
|
|
141
|
+
type: "TEAM_CHANGE",
|
|
142
|
+
id: packet[1],
|
|
143
|
+
team: packet[2],
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
case SERVER_MESSAGE_TYPES.TEAMLOCK_TOGGLE:
|
|
147
|
+
return {
|
|
148
|
+
type: "TEAMLOCK_TOGGLE",
|
|
149
|
+
locked: packet[1],
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
case SERVER_MESSAGE_TYPES.CHAT_MESSAGE:
|
|
153
|
+
return {
|
|
154
|
+
type: "CHAT_MESSAGE",
|
|
155
|
+
id: packet[1],
|
|
156
|
+
message: packet[2],
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
case SERVER_MESSAGE_TYPES.INITIAL_DATA:
|
|
160
|
+
return {
|
|
161
|
+
type: "INITIAL_DATA",
|
|
162
|
+
...packet[1],
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
case SERVER_MESSAGE_TYPES.TIMESYNC:
|
|
166
|
+
return {
|
|
167
|
+
type: "TIMESYNC",
|
|
168
|
+
time: packet[1].result,
|
|
169
|
+
id: packet[1].id,
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
case SERVER_MESSAGE_TYPES.PLAYER_KICK:
|
|
173
|
+
return {
|
|
174
|
+
type: "PLAYER_KICK",
|
|
175
|
+
id: packet[1],
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
case SERVER_MESSAGE_TYPES.MAP_REORDER:
|
|
179
|
+
return {
|
|
180
|
+
type: "MAP_REORDER",
|
|
181
|
+
start: packet[1],
|
|
182
|
+
end: packet[2],
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
case SERVER_MESSAGE_TYPES.GAMEMODE_CHANGE:
|
|
186
|
+
return {
|
|
187
|
+
type: "GAMEMODE_CHANGE",
|
|
188
|
+
engine: packet[1],
|
|
189
|
+
mode: packet[2],
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
case SERVER_MESSAGE_TYPES.CHANGE_ROUNDS:
|
|
193
|
+
return {
|
|
194
|
+
type: "CHANGE_ROUNDS",
|
|
195
|
+
rounds: packet[1],
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
case SERVER_MESSAGE_TYPES.MAP_SWITCH:
|
|
199
|
+
return {
|
|
200
|
+
type: "MAP_SWITCH",
|
|
201
|
+
mapdata: packet[1],
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
case SERVER_MESSAGE_TYPES.TYPING:
|
|
205
|
+
return {
|
|
206
|
+
type: "TYPING",
|
|
207
|
+
id: packet[1],
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
case SERVER_MESSAGE_TYPES.AFK_WARNING:
|
|
211
|
+
return {
|
|
212
|
+
type: "AFK_WARNING",
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
case SERVER_MESSAGE_TYPES.MAP_SUGGEST:
|
|
216
|
+
return {
|
|
217
|
+
type: "MAP_SUGGEST",
|
|
218
|
+
mapdata: packet[1],
|
|
219
|
+
id: packet[2],
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
case SERVER_MESSAGE_TYPES.MAP_SUGGEST:
|
|
223
|
+
return {
|
|
224
|
+
type: "MAP_SUGGEST",
|
|
225
|
+
maptitle: packet[1],
|
|
226
|
+
mapauthor: packet[2],
|
|
227
|
+
id: packet[3],
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
case SERVER_MESSAGE_TYPES.BALANCE_SET:
|
|
231
|
+
return {
|
|
232
|
+
type: "BALANCE_SET",
|
|
233
|
+
id: packet[1],
|
|
234
|
+
balance: packet[2],
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
case SERVER_MESSAGE_TYPES.DEBUG_WINNER:
|
|
238
|
+
return {
|
|
239
|
+
type: "DEBUG_WINNER",
|
|
240
|
+
id: packet[1],
|
|
241
|
+
data: packet[2],
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
case SERVER_MESSAGE_TYPES.SAVE_REPLAY:
|
|
245
|
+
return {
|
|
246
|
+
type: "SAVE_REPLAY",
|
|
247
|
+
id: packet[1],
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
case SERVER_MESSAGE_TYPES.HOST_TRANSFER:
|
|
251
|
+
return {
|
|
252
|
+
type: "HOST_TRANSFER",
|
|
253
|
+
oldHost: packet[1].oldHost || packet[1],
|
|
254
|
+
newHost: packet[1].newHost || packet[2],
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
case SERVER_MESSAGE_TYPES.FRIEND_REQUEST:
|
|
258
|
+
return {
|
|
259
|
+
type: "FRIEND_REQUEST",
|
|
260
|
+
id: packet[1],
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
case SERVER_MESSAGE_TYPES.COUNTDOWN:
|
|
264
|
+
return {
|
|
265
|
+
type: "COUNTDOWN",
|
|
266
|
+
countdown: packet[1],
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
case SERVER_MESSAGE_TYPES.ABORT_COUNTDOWN:
|
|
270
|
+
return {
|
|
271
|
+
type: "ABORT_COUNTDOWN",
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
case SERVER_MESSAGE_TYPES.PLAYER_LEVEL_UP:
|
|
275
|
+
return {
|
|
276
|
+
type: "PLAYER_LEVEL_UP",
|
|
277
|
+
sid: packet[1].sid,
|
|
278
|
+
level: packet[1].lv,
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
case SERVER_MESSAGE_TYPES.LOCAL_GAINED_XP:
|
|
282
|
+
const xpData = packet[1];
|
|
283
|
+
if (xpData.newLevel) {
|
|
284
|
+
return {
|
|
285
|
+
type: "LOCAL_GAINED_XP",
|
|
286
|
+
xp: xpData.newXP,
|
|
287
|
+
level: xpData.newLevel,
|
|
288
|
+
token: xpData.newToken,
|
|
289
|
+
};
|
|
290
|
+
} else {
|
|
291
|
+
return {
|
|
292
|
+
type: "LOCAL_GAINED_XP",
|
|
293
|
+
xp: xpData.newXP,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
case SERVER_MESSAGE_TYPES.STATE:
|
|
298
|
+
return parseStatePacket(packet[1]);
|
|
299
|
+
|
|
300
|
+
case SERVER_MESSAGE_TYPES.ROOM_SHARE_LINK:
|
|
301
|
+
return {
|
|
302
|
+
type: "ROOM_SHARE_LINK",
|
|
303
|
+
roomId: packet[1],
|
|
304
|
+
roomBypass: packet[2],
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
case SERVER_MESSAGE_TYPES.PLAYER_TABBED:
|
|
308
|
+
return {
|
|
309
|
+
type: "PLAYER_TABBED",
|
|
310
|
+
id: packet[1],
|
|
311
|
+
tabbed: packet[2],
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
case SERVER_MESSAGE_TYPES.CURATE_RESULT:
|
|
315
|
+
return {
|
|
316
|
+
type: "CURATE_RESULT",
|
|
317
|
+
success: packet[1],
|
|
318
|
+
message: packet[2],
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
case SERVER_MESSAGE_TYPES.ROOM_NAME_UPDATE:
|
|
322
|
+
return {
|
|
323
|
+
type: "ROOM_NAME_UPDATE",
|
|
324
|
+
name: packet[1],
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
case SERVER_MESSAGE_TYPES.ROOM_PASSWORD_UPDATE:
|
|
328
|
+
return {
|
|
329
|
+
type: "ROOM_PASSWORD_UPDATE",
|
|
330
|
+
passwordSet: packet[1] === 1,
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
default:
|
|
334
|
+
logger.debug("Unknown message type", {
|
|
335
|
+
type: messageType,
|
|
336
|
+
packet
|
|
337
|
+
});
|
|
338
|
+
return {
|
|
339
|
+
type: "unknown",
|
|
340
|
+
messageType,
|
|
341
|
+
data: packet.slice(1),
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Parse a state packet into a normalized object
|
|
348
|
+
* @param {Object} data - State packet data
|
|
349
|
+
* @returns {Object} Normalized state packet
|
|
350
|
+
*/
|
|
351
|
+
function parseStatePacket(data) {
|
|
352
|
+
return {
|
|
353
|
+
type: "STATE",
|
|
354
|
+
gt: data.gt,
|
|
355
|
+
rounds: data.wl,
|
|
356
|
+
quickplay: data.q,
|
|
357
|
+
teamsLocked: data.tl,
|
|
358
|
+
teams: data.tea,
|
|
359
|
+
engine: data.ga,
|
|
360
|
+
mode: data.mo,
|
|
361
|
+
balance: data.bal,
|
|
362
|
+
inputs: data.inputs,
|
|
363
|
+
framecount: data.fc,
|
|
364
|
+
stateID: data.stateID,
|
|
365
|
+
admin: data.admin,
|
|
366
|
+
map: data.gs ? data.gs.map : null,
|
|
367
|
+
state: data.state,
|
|
368
|
+
random: data.random,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
module.exports = {
|
|
373
|
+
parsePacket
|
|
374
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants used throughout the BonkBot library
|
|
3
|
+
*/
|
|
4
|
+
// Default skin for bots
|
|
5
|
+
const DEFAULT_AVATAR = {
|
|
6
|
+
layers: [],
|
|
7
|
+
bc: 16774557,
|
|
8
|
+
};
|
|
9
|
+
// Default server
|
|
10
|
+
const DEFAULT_SERVER = "b2ny1";
|
|
11
|
+
// Socket message types - Server to Client (Incoming)
|
|
12
|
+
const SERVER_MESSAGE_TYPES = {
|
|
13
|
+
PLAYER_PINGS: 1,
|
|
14
|
+
ROOM_ADDRESS: 2,
|
|
15
|
+
JOIN_ROOM: 3,
|
|
16
|
+
PLAYER_JOIN: 4,
|
|
17
|
+
PLAYER_LEAVE: 5,
|
|
18
|
+
HOST_LEAVE: 6,
|
|
19
|
+
PLAYER_INPUT: 7,
|
|
20
|
+
READY_CHANGE: 8,
|
|
21
|
+
GAME_END: 13,
|
|
22
|
+
GAME_START: 15,
|
|
23
|
+
STATUS_MESSAGE: 16,
|
|
24
|
+
TEAM_CHANGE: 18,
|
|
25
|
+
TEAMLOCK_TOGGLE: 19,
|
|
26
|
+
CHAT_MESSAGE: 20,
|
|
27
|
+
INITIAL_DATA: 21,
|
|
28
|
+
TIMESYNC: 23,
|
|
29
|
+
PLAYER_KICK: 24,
|
|
30
|
+
MAP_REORDER: 25,
|
|
31
|
+
GAMEMODE_CHANGE: 26,
|
|
32
|
+
CHANGE_ROUNDS: 27,
|
|
33
|
+
MAP_SWITCH: 29,
|
|
34
|
+
TYPING: 30,
|
|
35
|
+
AFK_WARNING: 32,
|
|
36
|
+
MAP_SUGGEST: 33,
|
|
37
|
+
MAP_SUGGEST: 34,
|
|
38
|
+
BALANCE_SET: 36,
|
|
39
|
+
DEBUG_WINNER: 38,
|
|
40
|
+
SAVE_REPLAY: 40,
|
|
41
|
+
HOST_TRANSFER: 41,
|
|
42
|
+
FRIEND_REQUEST: 42,
|
|
43
|
+
COUNTDOWN: 43,
|
|
44
|
+
ABORT_COUNTDOWN: 44,
|
|
45
|
+
PLAYER_LEVEL_UP: 45,
|
|
46
|
+
LOCAL_GAINED_XP: 46,
|
|
47
|
+
STATE: 48,
|
|
48
|
+
ROOM_SHARE_LINK: 49,
|
|
49
|
+
PLAYER_TABBED: 52,
|
|
50
|
+
CURATE_RESULT: 57,
|
|
51
|
+
ROOM_NAME_UPDATE: 58,
|
|
52
|
+
ROOM_PASSWORD_UPDATE: 59,
|
|
53
|
+
};
|
|
54
|
+
// Socket message types - Client to Server (Outgoing)
|
|
55
|
+
const CLIENT_MESSAGE_TYPES = {
|
|
56
|
+
PING_RESPONSE: 1,
|
|
57
|
+
TEST_PING: 2,
|
|
58
|
+
GET_DEBUG: 3,
|
|
59
|
+
SEND_INPUTS: 4,
|
|
60
|
+
TRIGGER_START: 5,
|
|
61
|
+
CHANGE_OWN_TEAM: 6,
|
|
62
|
+
TEAM_LOCK: 7,
|
|
63
|
+
SILENCE_PLAYER: 8,
|
|
64
|
+
KICK_BAN_PLAYER: 9,
|
|
65
|
+
CHAT_MESSAGE: 10,
|
|
66
|
+
INFORM_IN_LOBBY: 11,
|
|
67
|
+
CREATE_ROOM: 12,
|
|
68
|
+
JOIN_ROOM: 13,
|
|
69
|
+
RETURN_TO_LOBBY: 14,
|
|
70
|
+
SET_READY: 16,
|
|
71
|
+
ALL_READY_RESET: 17,
|
|
72
|
+
TIMESYNC: 18,
|
|
73
|
+
SEND_MAP_REORDER: 19,
|
|
74
|
+
SEND_MODE: 20,
|
|
75
|
+
SEND_ROUNDS: 21,
|
|
76
|
+
SEND_MAP_DELETE: 22,
|
|
77
|
+
SEND_MAP_ADD: 23,
|
|
78
|
+
SEND_TYPING: 24,
|
|
79
|
+
CHANGE_OTHER_TEAM: 26,
|
|
80
|
+
SEND_MAP_SUGGEST: 27,
|
|
81
|
+
SEND_BALANCE: 29,
|
|
82
|
+
VERSION_CHECK: 30,
|
|
83
|
+
SEND_DEBUG_WINNER: 31,
|
|
84
|
+
SEND_TEAM_SETTINGS: 32,
|
|
85
|
+
SEND_ARM_RECORD: 33,
|
|
86
|
+
SEND_HOST_CHANGE: 34,
|
|
87
|
+
SEND_FRIENDED: 35,
|
|
88
|
+
SEND_START_COUNTDOWN: 36,
|
|
89
|
+
SEND_ABORT_COUNTDOWN: 37,
|
|
90
|
+
SEND_REQUEST_XP: 38,
|
|
91
|
+
SEND_MAP_VOTE: 39,
|
|
92
|
+
INFORM_IN_GAME: 40,
|
|
93
|
+
GET_PRE_VOTE: 41,
|
|
94
|
+
TABBED: 44,
|
|
95
|
+
DESYNC_TEST: 45,
|
|
96
|
+
SEND_DESYNC_RESPONSE: 46,
|
|
97
|
+
SEND_NO_HOST_SWAP: 50,
|
|
98
|
+
SEND_CURATE: 51,
|
|
99
|
+
};
|
|
100
|
+
// For backward compatibility, keep the old MESSAGE_TYPES object
|
|
101
|
+
// but use the server message types as the default
|
|
102
|
+
const MESSAGE_TYPES = {
|
|
103
|
+
...SERVER_MESSAGE_TYPES,
|
|
104
|
+
...CLIENT_MESSAGE_TYPES,
|
|
105
|
+
};
|
|
106
|
+
// Team mappings
|
|
107
|
+
const TEAM_NAMES = {
|
|
108
|
+
0: "spectator",
|
|
109
|
+
1: "ffa",
|
|
110
|
+
2: "red",
|
|
111
|
+
3: "blue",
|
|
112
|
+
4: "green",
|
|
113
|
+
5: "yellow",
|
|
114
|
+
};
|
|
115
|
+
// Gamemode names
|
|
116
|
+
const GAMEMODE_NAMES = {
|
|
117
|
+
"b": "classic",
|
|
118
|
+
"ar": "arrows",
|
|
119
|
+
"ard": "death arrrows",
|
|
120
|
+
"sp": "grapple",
|
|
121
|
+
"v": "vtol",
|
|
122
|
+
"f": "football"
|
|
123
|
+
}
|
|
124
|
+
// Engine names
|
|
125
|
+
const ENGINE_NAMES = {
|
|
126
|
+
"b": "bonk",
|
|
127
|
+
"f": "football"
|
|
128
|
+
}
|
|
129
|
+
// API endpoints
|
|
130
|
+
const API = {
|
|
131
|
+
LOGIN: "https://bonk2.io/scripts/login_legacy.php",
|
|
132
|
+
GET_ROOMS: "https://bonk2.io/scripts/getrooms.php",
|
|
133
|
+
GET_ROOM_ADDRESS: "https://bonk2.io/scripts/getroomaddress.php",
|
|
134
|
+
AUTOJOIN: "https://bonk2.io/scripts/autojoin.php"
|
|
135
|
+
};
|
|
136
|
+
// Socket connection settings
|
|
137
|
+
const SOCKET = {
|
|
138
|
+
KEEP_ALIVE_INTERVAL: 5000,
|
|
139
|
+
CONNECTION_TIMEOUT: 10000,
|
|
140
|
+
};
|
|
141
|
+
// Export all constants
|
|
142
|
+
module.exports = {
|
|
143
|
+
DEFAULT_AVATAR,
|
|
144
|
+
DEFAULT_SERVER,
|
|
145
|
+
MESSAGE_TYPES,
|
|
146
|
+
GAMEMODE_NAMES,
|
|
147
|
+
ENGINE_NAMES,
|
|
148
|
+
SERVER_MESSAGE_TYPES,
|
|
149
|
+
CLIENT_MESSAGE_TYPES,
|
|
150
|
+
TEAM_NAMES,
|
|
151
|
+
API,
|
|
152
|
+
SOCKET,
|
|
153
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for BonkBot
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Base error class for BonkBot errors
|
|
7
|
+
*/
|
|
8
|
+
class BonkBotError extends Error {
|
|
9
|
+
/**
|
|
10
|
+
* Create a new BonkBotError
|
|
11
|
+
* @param {string} message - Error message
|
|
12
|
+
* @param {Object} [options] - Additional error options
|
|
13
|
+
*/
|
|
14
|
+
constructor(message, options = {}) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = this.constructor.name;
|
|
17
|
+
this.code = options.code || "UNKNOWN_ERROR";
|
|
18
|
+
this.details = options.details || {};
|
|
19
|
+
|
|
20
|
+
// Capture stack trace
|
|
21
|
+
if (Error.captureStackTrace) {
|
|
22
|
+
Error.captureStackTrace(this, this.constructor);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Error thrown when there's a connection issue
|
|
29
|
+
*/
|
|
30
|
+
class ConnectionError extends BonkBotError {
|
|
31
|
+
/**
|
|
32
|
+
* Create a new ConnectionError
|
|
33
|
+
* @param {string} message - Error message
|
|
34
|
+
* @param {Object} [options] - Additional error options
|
|
35
|
+
*/
|
|
36
|
+
constructor(message, options = {}) {
|
|
37
|
+
super(message, {
|
|
38
|
+
code: options.code || "CONNECTION_ERROR",
|
|
39
|
+
details: options.details,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Error thrown when there's an authentication issue
|
|
46
|
+
*/
|
|
47
|
+
class AuthenticationError extends BonkBotError {
|
|
48
|
+
/**
|
|
49
|
+
* Create a new AuthenticationError
|
|
50
|
+
* @param {string} message - Error message
|
|
51
|
+
* @param {Object} [options] - Additional error options
|
|
52
|
+
*/
|
|
53
|
+
constructor(message, options = {}) {
|
|
54
|
+
super(message, {
|
|
55
|
+
code: options.code || "AUTHENTICATION_ERROR",
|
|
56
|
+
details: options.details,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Error thrown when there's an issue with room operations
|
|
63
|
+
*/
|
|
64
|
+
class RoomError extends BonkBotError {
|
|
65
|
+
/**
|
|
66
|
+
* Create a new RoomError
|
|
67
|
+
* @param {string} message - Error message
|
|
68
|
+
* @param {Object} [options] - Additional error options
|
|
69
|
+
*/
|
|
70
|
+
constructor(message, options = {}) {
|
|
71
|
+
super(message, {
|
|
72
|
+
code: options.code || "ROOM_ERROR",
|
|
73
|
+
details: options.details,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Error thrown when there's an issue with the game state
|
|
80
|
+
*/
|
|
81
|
+
class GameStateError extends BonkBotError {
|
|
82
|
+
/**
|
|
83
|
+
* Create a new GameStateError
|
|
84
|
+
* @param {string} message - Error message
|
|
85
|
+
* @param {Object} [options] - Additional error options
|
|
86
|
+
*/
|
|
87
|
+
constructor(message, options = {}) {
|
|
88
|
+
super(message, {
|
|
89
|
+
code: options.code || "GAME_STATE_ERROR",
|
|
90
|
+
details: options.details,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Error thrown when there's a validation issue
|
|
97
|
+
*/
|
|
98
|
+
class ValidationError extends BonkBotError {
|
|
99
|
+
/**
|
|
100
|
+
* Create a new ValidationError
|
|
101
|
+
* @param {string} message - Error message
|
|
102
|
+
* @param {Object} [options] - Additional error options
|
|
103
|
+
*/
|
|
104
|
+
constructor(message, options = {}) {
|
|
105
|
+
super(message, {
|
|
106
|
+
code: options.code || "VALIDATION_ERROR",
|
|
107
|
+
details: options.details,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Error thrown when a rate limit is hit
|
|
114
|
+
*/
|
|
115
|
+
class RateLimitError extends BonkBotError {
|
|
116
|
+
/**
|
|
117
|
+
* Create a new RateLimitError
|
|
118
|
+
* @param {string} message - Error message
|
|
119
|
+
* @param {Object} [options] - Additional error options
|
|
120
|
+
*/
|
|
121
|
+
constructor(message, options = {}) {
|
|
122
|
+
super(message, {
|
|
123
|
+
code: options.code || "RATE_LIMIT_ERROR",
|
|
124
|
+
details: options.details,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = {
|
|
130
|
+
BonkBotError,
|
|
131
|
+
ConnectionError,
|
|
132
|
+
AuthenticationError,
|
|
133
|
+
RoomError,
|
|
134
|
+
GameStateError,
|
|
135
|
+
ValidationError,
|
|
136
|
+
RateLimitError,
|
|
137
|
+
};
|