@phalanx-engine/server 0.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.
Files changed (54) hide show
  1. package/README.md +507 -0
  2. package/dist/Phalanx.d.ts +85 -0
  3. package/dist/Phalanx.d.ts.map +1 -0
  4. package/dist/Phalanx.js +600 -0
  5. package/dist/Phalanx.js.map +1 -0
  6. package/dist/config/defaults.d.ts +10 -0
  7. package/dist/config/defaults.d.ts.map +1 -0
  8. package/dist/config/defaults.js +51 -0
  9. package/dist/config/defaults.js.map +1 -0
  10. package/dist/config/validation.d.ts +15 -0
  11. package/dist/config/validation.d.ts.map +1 -0
  12. package/dist/config/validation.js +74 -0
  13. package/dist/config/validation.js.map +1 -0
  14. package/dist/index.d.ts +12 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +14 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/services/GameRoom.d.ts +359 -0
  19. package/dist/services/GameRoom.d.ts.map +1 -0
  20. package/dist/services/GameRoom.js +1272 -0
  21. package/dist/services/GameRoom.js.map +1 -0
  22. package/dist/services/MatchmakingService.d.ts +102 -0
  23. package/dist/services/MatchmakingService.d.ts.map +1 -0
  24. package/dist/services/MatchmakingService.js +286 -0
  25. package/dist/services/MatchmakingService.js.map +1 -0
  26. package/dist/services/OAuthExchangeService.d.ts +49 -0
  27. package/dist/services/OAuthExchangeService.d.ts.map +1 -0
  28. package/dist/services/OAuthExchangeService.js +96 -0
  29. package/dist/services/OAuthExchangeService.js.map +1 -0
  30. package/dist/services/PrivateRoomService.d.ts +136 -0
  31. package/dist/services/PrivateRoomService.d.ts.map +1 -0
  32. package/dist/services/PrivateRoomService.js +395 -0
  33. package/dist/services/PrivateRoomService.js.map +1 -0
  34. package/dist/services/TokenValidator.d.ts +60 -0
  35. package/dist/services/TokenValidator.d.ts.map +1 -0
  36. package/dist/services/TokenValidator.js +213 -0
  37. package/dist/services/TokenValidator.js.map +1 -0
  38. package/dist/types/index.d.ts +390 -0
  39. package/dist/types/index.d.ts.map +1 -0
  40. package/dist/types/index.js +6 -0
  41. package/dist/types/index.js.map +1 -0
  42. package/dist/utils/DeterministicRandom.d.ts +88 -0
  43. package/dist/utils/DeterministicRandom.d.ts.map +1 -0
  44. package/dist/utils/DeterministicRandom.js +140 -0
  45. package/dist/utils/DeterministicRandom.js.map +1 -0
  46. package/dist/utils/FixedMath.d.ts +22 -0
  47. package/dist/utils/FixedMath.d.ts.map +1 -0
  48. package/dist/utils/FixedMath.js +26 -0
  49. package/dist/utils/FixedMath.js.map +1 -0
  50. package/dist/utils/index.d.ts +7 -0
  51. package/dist/utils/index.d.ts.map +1 -0
  52. package/dist/utils/index.js +6 -0
  53. package/dist/utils/index.js.map +1 -0
  54. package/package.json +62 -0
@@ -0,0 +1,600 @@
1
+ import { EventEmitter } from 'events';
2
+ import { Server as SocketIOServer } from 'socket.io';
3
+ import { createServer as createHttpServer, } from 'http';
4
+ import { createServer as createHttpsServer, } from 'https';
5
+ import { readFileSync } from 'fs';
6
+ import { validateConfig } from './config/validation.js';
7
+ import { MatchmakingService } from './services/MatchmakingService.js';
8
+ import { PrivateRoomService } from './services/PrivateRoomService.js';
9
+ import { TokenValidatorService } from './services/TokenValidator.js';
10
+ import { OAuthExchangeService, } from './services/OAuthExchangeService.js';
11
+ /**
12
+ * Phalanx Engine
13
+ * A game-agnostic deterministic lockstep multiplayer engine
14
+ */
15
+ export class Phalanx extends EventEmitter {
16
+ config;
17
+ httpServer = null;
18
+ io = null;
19
+ matchmaking = null;
20
+ privateRooms = null;
21
+ tokenValidator = null;
22
+ oauthExchange = null;
23
+ isRunning = false;
24
+ constructor(config) {
25
+ super();
26
+ this.config = validateConfig(config);
27
+ }
28
+ /**
29
+ * Create HTTP or HTTPS server based on TLS configuration
30
+ */
31
+ createServer() {
32
+ const requestHandler = async (req, res) => {
33
+ // Handle CORS preflight
34
+ if (req.method === 'OPTIONS') {
35
+ this.setCorsHeaders(res, req);
36
+ res.writeHead(204);
37
+ res.end();
38
+ return;
39
+ }
40
+ // Delegate to consumer-provided handler first (e.g. bot webhook)
41
+ if (this.config.extraRequestHandler) {
42
+ try {
43
+ const consumed = await this.config.extraRequestHandler(req, res);
44
+ if (consumed)
45
+ return;
46
+ }
47
+ catch (err) {
48
+ console.error('[Phalanx] extraRequestHandler threw an error:', err);
49
+ if (!res.headersSent) {
50
+ res.writeHead(500, { 'Content-Type': 'application/json' });
51
+ res.end(JSON.stringify({ error: 'Internal server error' }));
52
+ }
53
+ return;
54
+ }
55
+ }
56
+ // Health check endpoint
57
+ if (req.url === '/' || req.url === '/health') {
58
+ this.setCorsHeaders(res, req);
59
+ res.writeHead(200, { 'Content-Type': 'application/json' });
60
+ res.end(JSON.stringify({
61
+ status: 'ok',
62
+ timestamp: new Date().toISOString(),
63
+ tls: !!this.config.tls?.enabled,
64
+ }));
65
+ return;
66
+ }
67
+ // OAuth token exchange endpoint
68
+ if (req.url === '/auth/token' && req.method === 'POST') {
69
+ await this.handleTokenExchange(req, res);
70
+ return;
71
+ }
72
+ // 404 for other routes
73
+ this.setCorsHeaders(res, req);
74
+ res.writeHead(404, { 'Content-Type': 'application/json' });
75
+ res.end(JSON.stringify({ error: 'Not found' }));
76
+ };
77
+ if (this.config.tls?.enabled) {
78
+ try {
79
+ const tlsOptions = {
80
+ key: readFileSync(this.config.tls.keyPath),
81
+ cert: readFileSync(this.config.tls.certPath),
82
+ ca: this.config.tls.caPath
83
+ ? readFileSync(this.config.tls.caPath)
84
+ : undefined,
85
+ };
86
+ console.log('[Phalanx] Starting with TLS enabled (WSS)');
87
+ return createHttpsServer(tlsOptions, (req, res) => void requestHandler(req, res));
88
+ }
89
+ catch (error) {
90
+ const message = error instanceof Error ? error.message : 'Unknown error';
91
+ throw new Error(`Failed to load TLS certificates: ${message}`);
92
+ }
93
+ }
94
+ console.log('[Phalanx] Starting without TLS (development mode)');
95
+ return createHttpServer((req, res) => void requestHandler(req, res));
96
+ }
97
+ /**
98
+ * Set CORS headers on response
99
+ */
100
+ setCorsHeaders(res, req) {
101
+ const configuredOrigins = Array.isArray(this.config.cors.origin)
102
+ ? this.config.cors.origin
103
+ : [this.config.cors.origin];
104
+ // Get the request Origin header
105
+ const requestOrigin = req?.headers.origin;
106
+ // Check if the request origin is in our allowed list
107
+ let allowedOrigin;
108
+ if (requestOrigin && configuredOrigins.includes(requestOrigin)) {
109
+ allowedOrigin = requestOrigin;
110
+ }
111
+ else if (configuredOrigins.includes('*')) {
112
+ allowedOrigin = '*';
113
+ }
114
+ else {
115
+ // Default to first configured origin (for preflight without Origin header)
116
+ allowedOrigin = configuredOrigins[0] || '*';
117
+ }
118
+ res.setHeader('Access-Control-Allow-Origin', allowedOrigin);
119
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
120
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
121
+ if (this.config.cors.credentials) {
122
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
123
+ }
124
+ }
125
+ /**
126
+ * Handle OAuth token exchange request
127
+ */
128
+ async handleTokenExchange(req, res) {
129
+ this.setCorsHeaders(res, req);
130
+ if (!this.oauthExchange) {
131
+ res.writeHead(503, { 'Content-Type': 'application/json' });
132
+ res.end(JSON.stringify({
133
+ success: false,
134
+ error: 'OAuth not configured',
135
+ errorCode: 'not_configured'
136
+ }));
137
+ return;
138
+ }
139
+ try {
140
+ // Read request body
141
+ const body = await this.readRequestBody(req);
142
+ const request = JSON.parse(body);
143
+ // Validate required fields
144
+ if (!request.code || !request.codeVerifier || !request.redirectUri || !request.provider) {
145
+ res.writeHead(400, { 'Content-Type': 'application/json' });
146
+ res.end(JSON.stringify({
147
+ success: false,
148
+ error: 'Missing required fields: code, codeVerifier, redirectUri, provider',
149
+ errorCode: 'invalid_request'
150
+ }));
151
+ return;
152
+ }
153
+ // Exchange the code for tokens
154
+ const result = await this.oauthExchange.exchangeCode(request);
155
+ res.writeHead(result.success ? 200 : 400, { 'Content-Type': 'application/json' });
156
+ res.end(JSON.stringify(result));
157
+ }
158
+ catch (error) {
159
+ console.error('[Phalanx] Token exchange error:', error);
160
+ res.writeHead(500, { 'Content-Type': 'application/json' });
161
+ res.end(JSON.stringify({
162
+ success: false,
163
+ error: 'Internal server error',
164
+ errorCode: 'server_error'
165
+ }));
166
+ }
167
+ }
168
+ /**
169
+ * Read the full request body as a string
170
+ */
171
+ readRequestBody(req) {
172
+ return new Promise((resolve, reject) => {
173
+ let body = '';
174
+ req.on('data', (chunk) => {
175
+ body += chunk.toString();
176
+ // Limit body size to 1MB
177
+ if (body.length > 1024 * 1024) {
178
+ reject(new Error('Request body too large'));
179
+ }
180
+ });
181
+ req.on('end', () => resolve(body));
182
+ req.on('error', reject);
183
+ });
184
+ }
185
+ /**
186
+ * Start the Phalanx server
187
+ */
188
+ async start() {
189
+ if (this.isRunning) {
190
+ throw new Error('Phalanx server is already running');
191
+ }
192
+ // Create HTTP/HTTPS server with health check endpoint
193
+ this.httpServer = this.createServer();
194
+ // Create Socket.IO server
195
+ this.io = new SocketIOServer(this.httpServer, {
196
+ cors: this.config.cors,
197
+ });
198
+ // Setup authentication if enabled
199
+ if (this.config.auth?.enabled) {
200
+ this.tokenValidator = new TokenValidatorService(this.config.auth);
201
+ this.oauthExchange = new OAuthExchangeService(this.config.auth);
202
+ this.setupAuthMiddleware();
203
+ console.log('[Phalanx] Authentication enabled');
204
+ if (this.config.auth.google?.clientSecret) {
205
+ console.log('[Phalanx] OAuth token exchange endpoint available at /auth/token');
206
+ }
207
+ }
208
+ else {
209
+ console.log('[Phalanx] Authentication disabled (development mode)');
210
+ }
211
+ // Create matchmaking service
212
+ this.matchmaking = new MatchmakingService(this.io, this.config, (event, ...args) => this.emit(event, ...args));
213
+ // Create private room service
214
+ this.privateRooms = new PrivateRoomService(this.io, this.config, (event, ...args) => this.emit(event, ...args), (gameType) => this.matchmaking.resolveGameTypeConfig(gameType), (playerId) => this.matchmaking.isInAnyQueue(playerId));
215
+ // Wire up match-ended event to prune finished matches from both services
216
+ this.on('match-ended', ((matchId) => {
217
+ this.matchmaking?.removeMatch(matchId);
218
+ this.privateRooms?.removeMatch(matchId);
219
+ }));
220
+ // Setup socket handlers
221
+ this.setupSocketHandlers();
222
+ // Start matchmaking
223
+ this.matchmaking.start();
224
+ // Start listening
225
+ return new Promise((resolve, reject) => {
226
+ this.httpServer.listen(this.config.port, () => {
227
+ this.isRunning = true;
228
+ resolve();
229
+ });
230
+ this.httpServer.on('error', (err) => {
231
+ reject(err);
232
+ });
233
+ });
234
+ }
235
+ /**
236
+ * Create or reuse a private room for a host that will connect later.
237
+ * Intended for trusted server-side integrations such as Telegram bot
238
+ * commands; browser clients should continue using the Socket.IO flow.
239
+ */
240
+ createPrivateRoomForHost(params) {
241
+ if (!this.privateRooms) {
242
+ throw new Error('Private room service is not running');
243
+ }
244
+ return this.privateRooms.createRoomForDisconnectedHost(params.playerId, params.username ?? params.playerId, params.gameType);
245
+ }
246
+ /**
247
+ * Stop the Phalanx server
248
+ */
249
+ async stop() {
250
+ if (!this.isRunning) {
251
+ return;
252
+ }
253
+ this.isRunning = false;
254
+ // Stop matchmaking first
255
+ if (this.matchmaking) {
256
+ this.matchmaking.stop();
257
+ this.matchmaking = null;
258
+ }
259
+ // Stop private rooms
260
+ if (this.privateRooms) {
261
+ this.privateRooms.stop();
262
+ this.privateRooms = null;
263
+ }
264
+ // Disconnect all sockets first
265
+ if (this.io) {
266
+ this.io.disconnectSockets(true);
267
+ }
268
+ // Close HTTP server (this also closes Socket.IO)
269
+ if (this.httpServer) {
270
+ await new Promise((resolve) => {
271
+ this.httpServer.close(() => resolve());
272
+ });
273
+ this.httpServer = null;
274
+ }
275
+ this.io = null;
276
+ }
277
+ /**
278
+ * Setup authentication middleware for Socket.IO connections.
279
+ * Validates tokens before allowing connections.
280
+ */
281
+ setupAuthMiddleware() {
282
+ if (!this.io || !this.tokenValidator)
283
+ return;
284
+ this.io.use(async (socket, next) => {
285
+ const token = socket.handshake.auth?.token;
286
+ // Check if token is provided
287
+ if (!token) {
288
+ // Allow anonymous if configured
289
+ if (this.config.auth?.allowAnonymous) {
290
+ console.log(`[Phalanx] Anonymous connection allowed: ${socket.id}`);
291
+ socket.data.authenticated = false;
292
+ return next();
293
+ }
294
+ console.log(`[Phalanx] Connection rejected - no token: ${socket.id}`);
295
+ return next(new Error('Authentication required'));
296
+ }
297
+ // Validate the token
298
+ const result = await this.tokenValidator.validate(token);
299
+ if (!result.valid) {
300
+ console.log(`[Phalanx] Connection rejected - invalid token: ${socket.id} - ${result.error}`);
301
+ return next(new Error(result.error || 'Invalid token'));
302
+ }
303
+ // Store authenticated user info on socket
304
+ socket.data.authenticated = true;
305
+ socket.data.userId = result.userId;
306
+ socket.data.username = result.username;
307
+ console.log(`[Phalanx] Authenticated connection: ${socket.id} - User: ${result.userId}`);
308
+ next();
309
+ });
310
+ }
311
+ /**
312
+ * Setup socket event handlers
313
+ */
314
+ setupSocketHandlers() {
315
+ if (!this.io)
316
+ return;
317
+ this.io.on('connection', (socket) => {
318
+ let playerId = null;
319
+ // Track activity on ANY message from client (LOCKSTEP-5)
320
+ // This replaces tick-ack - any message = player is alive
321
+ socket.onAny(() => {
322
+ if (playerId && socket.data.matchId) {
323
+ const gameRoom = this.findMatch(socket.data.matchId);
324
+ if (gameRoom) {
325
+ gameRoom.updatePlayerActivity(playerId);
326
+ }
327
+ }
328
+ });
329
+ // Handle join queue (MATCH-1)
330
+ socket.on('queue-join', (data) => {
331
+ playerId = data.playerId;
332
+ const username = data.username ?? data.playerId;
333
+ this.matchmaking.joinQueue(playerId, username, socket, data.gameType);
334
+ });
335
+ // Handle leave queue (MATCH-2)
336
+ socket.on('queue-leave', () => {
337
+ if (playerId) {
338
+ this.matchmaking.leaveQueue(playerId, socket);
339
+ }
340
+ });
341
+ // Handle room-create (private match)
342
+ socket.on('room-create', (data) => {
343
+ playerId = data.playerId;
344
+ const username = data.username ?? data.playerId;
345
+ this.privateRooms.createRoom(playerId, username, socket, data.gameType);
346
+ });
347
+ // Handle room-join (private match)
348
+ socket.on('room-join', (data) => {
349
+ playerId = data.playerId;
350
+ const username = data.username ?? data.playerId;
351
+ this.privateRooms.joinRoom(playerId, username, socket, data.code);
352
+ });
353
+ // Handle room-cancel (private match)
354
+ socket.on('room-cancel', () => {
355
+ if (playerId) {
356
+ this.privateRooms.cancelRoom(playerId, socket);
357
+ }
358
+ });
359
+ // Handle room-recover (private match)
360
+ // Called when a host reconnects after a transient socket disconnect
361
+ // (e.g. mobile browser killing the WebSocket when the user switches
362
+ // to a messenger to share the invite link) and wants to reclaim
363
+ // their still-alive room. `code` is required to prove the caller
364
+ // is actually the host who created the room — in an anonymous
365
+ // socket environment, `playerId` alone is not an authentication
366
+ // token. If it's missing we reject with the same `Room expired`
367
+ // error the service itself uses, so clients can't distinguish
368
+ // "wrong code" from "missing code" from "no such room".
369
+ socket.on('room-recover', (payload) => {
370
+ // The payload is untrusted — a client can emit literally
371
+ // anything (including `null`, a primitive, or a missing
372
+ // argument, which Socket.IO will surface as `undefined`).
373
+ // Guard the top-level shape before dereferencing any field
374
+ // so a malformed message can't crash the connection
375
+ // handler, and validate each field before touching state
376
+ // on this connection. A failed recover must not mutate the
377
+ // captured `playerId` — otherwise a later handler like
378
+ // `room-cancel` would act on a playerId the socket was
379
+ // never authenticated to own.
380
+ if (!payload || typeof payload !== 'object') {
381
+ socket.emit('room-error', { message: 'Room expired' });
382
+ return;
383
+ }
384
+ const data = payload;
385
+ if (typeof data.code !== 'string' || data.code.length === 0) {
386
+ socket.emit('room-error', { message: 'Room expired' });
387
+ return;
388
+ }
389
+ if (typeof data.playerId !== 'string' || data.playerId.length === 0) {
390
+ socket.emit('room-error', { message: 'Room expired' });
391
+ return;
392
+ }
393
+ const recovered = this.privateRooms.recoverRoom(data.playerId, socket, data.code);
394
+ if (recovered) {
395
+ playerId = data.playerId;
396
+ }
397
+ });
398
+ // Handle player command
399
+ socket.on('player-command', (command) => {
400
+ if (!playerId)
401
+ return;
402
+ // Find the match this player is in (check both matchmaking and private rooms)
403
+ const matchId = socket.data.matchId;
404
+ const gameRoom = matchId ? this.findMatch(matchId) : undefined;
405
+ if (gameRoom) {
406
+ const accepted = gameRoom.handleCommand(playerId, command);
407
+ socket.emit('command-ack', {
408
+ tick: command.tick,
409
+ accepted,
410
+ });
411
+ return;
412
+ }
413
+ socket.emit('command-ack', { tick: command.tick, accepted: false });
414
+ });
415
+ // Handle submit-commands (LOCKSTEP-2): batch command submission for a specific tick
416
+ // Clients can submit empty arrays if they have no commands for this tick
417
+ socket.on('submit-commands', (data) => {
418
+ if (!playerId)
419
+ return;
420
+ const { tick, commands } = data;
421
+ // Validate input
422
+ if (!Number.isFinite(tick) || !Array.isArray(commands)) {
423
+ socket.emit('submit-commands-ack', {
424
+ tick,
425
+ accepted: false,
426
+ reason: 'Invalid data',
427
+ });
428
+ return;
429
+ }
430
+ // Find the match this player is in via socket.data
431
+ const matchId = socket.data.matchId;
432
+ if (!matchId) {
433
+ socket.emit('submit-commands-ack', {
434
+ tick,
435
+ accepted: false,
436
+ reason: 'Not in a match',
437
+ });
438
+ return;
439
+ }
440
+ const gameRoom = this.findMatch(matchId);
441
+ if (!gameRoom) {
442
+ socket.emit('submit-commands-ack', {
443
+ tick,
444
+ accepted: false,
445
+ reason: 'Match not found',
446
+ });
447
+ return;
448
+ }
449
+ // Validate each command (NET-1)
450
+ const validCommands = [];
451
+ for (const cmd of commands) {
452
+ // Validate required fields
453
+ if (typeof cmd.type !== 'string' || cmd.data === undefined) {
454
+ socket.emit('command-rejected', {
455
+ reason: 'Missing required fields (type, data)',
456
+ tick,
457
+ type: cmd.type,
458
+ });
459
+ continue;
460
+ }
461
+ // Enrich command with playerId and tick, preserve sequence if present
462
+ const enrichedCommand = {
463
+ type: cmd.type,
464
+ data: cmd.data,
465
+ playerId: playerId,
466
+ tick,
467
+ ...(cmd.sequence !== undefined && { sequence: cmd.sequence }),
468
+ };
469
+ validCommands.push(enrichedCommand);
470
+ }
471
+ const result = gameRoom.receivePlayerCommands(playerId, tick, validCommands);
472
+ socket.emit('submit-commands-ack', {
473
+ tick,
474
+ accepted: result.accepted,
475
+ ...(result.invalidCommands && {
476
+ rejectedCount: result.invalidCommands.length,
477
+ }),
478
+ });
479
+ });
480
+ // Handle state-hash for desync detection (2.1.3)
481
+ socket.on('state-hash', (data) => {
482
+ if (!playerId)
483
+ return;
484
+ const { tick, hash } = data;
485
+ // Validate input
486
+ if (typeof tick !== 'number' || typeof hash !== 'string') {
487
+ return;
488
+ }
489
+ const matchId = socket.data.matchId;
490
+ if (!matchId)
491
+ return;
492
+ const gameRoom = this.findMatch(matchId);
493
+ if (gameRoom) {
494
+ gameRoom.receiveStateHash(playerId, tick, hash);
495
+ }
496
+ });
497
+ // Note: tick-ack is no longer needed - we use socket.onAny() to track activity
498
+ // Any message from client (including Socket.IO ping) = player is alive
499
+ // Handle pause request
500
+ socket.on('pause-game', () => {
501
+ if (!playerId)
502
+ return;
503
+ const matchId = socket.data.matchId;
504
+ if (!matchId)
505
+ return;
506
+ const gameRoom = this.findMatch(matchId);
507
+ if (gameRoom) {
508
+ gameRoom.pause(playerId);
509
+ }
510
+ });
511
+ // Handle resume request
512
+ socket.on('resume-game', () => {
513
+ if (!playerId)
514
+ return;
515
+ const matchId = socket.data.matchId;
516
+ if (!matchId)
517
+ return;
518
+ const gameRoom = this.findMatch(matchId);
519
+ if (gameRoom) {
520
+ gameRoom.resume(playerId);
521
+ }
522
+ });
523
+ // Handle client-ready (ready handshake after asset loading)
524
+ socket.on('client-ready', () => {
525
+ if (!playerId)
526
+ return;
527
+ const matchId = socket.data.matchId;
528
+ if (!matchId)
529
+ return;
530
+ const gameRoom = this.findMatch(matchId);
531
+ if (gameRoom) {
532
+ gameRoom.handlePlayerReady(playerId);
533
+ }
534
+ });
535
+ // Handle reconnection
536
+ socket.on('reconnect-match', (data) => {
537
+ playerId = data.playerId;
538
+ const gameRoom = this.findMatch(data.matchId);
539
+ if (gameRoom) {
540
+ const success = gameRoom.handleReconnect(playerId, socket.id);
541
+ socket.emit('reconnect-status', { success });
542
+ }
543
+ else {
544
+ socket.emit('reconnect-status', {
545
+ success: false,
546
+ reason: 'Match not found',
547
+ });
548
+ }
549
+ });
550
+ // Handle disconnect
551
+ socket.on('disconnect', () => {
552
+ if (this.matchmaking) {
553
+ this.matchmaking.handleDisconnect(socket.id);
554
+ }
555
+ if (this.privateRooms) {
556
+ this.privateRooms.handleDisconnect(socket.id);
557
+ }
558
+ });
559
+ });
560
+ }
561
+ /**
562
+ * Find a GameRoom by matchId across both matchmaking and private room services.
563
+ */
564
+ findMatch(matchId) {
565
+ return this.matchmaking?.getMatch(matchId) ?? this.privateRooms?.getMatch(matchId);
566
+ }
567
+ /**
568
+ * Register an event handler
569
+ */
570
+ on(event, handler) {
571
+ return super.on(event, handler);
572
+ }
573
+ /**
574
+ * Remove an event handler
575
+ */
576
+ off(event, handler) {
577
+ return super.off(event, handler);
578
+ }
579
+ /**
580
+ * Get all active matches (from both matchmaking and private rooms)
581
+ */
582
+ getActiveMatches() {
583
+ const matchmakingMatches = this.matchmaking?.getActiveMatches() ?? [];
584
+ const privateMatches = this.privateRooms?.getActiveMatches().map((m) => m.getMatchInfo()) ?? [];
585
+ return [...matchmakingMatches, ...privateMatches];
586
+ }
587
+ /**
588
+ * Get current matchmaking queue size
589
+ */
590
+ getQueueSize() {
591
+ return this.matchmaking?.getQueueSize() ?? 0;
592
+ }
593
+ /**
594
+ * Get the current configuration
595
+ */
596
+ getConfig() {
597
+ return { ...this.config };
598
+ }
599
+ }
600
+ //# sourceMappingURL=Phalanx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Phalanx.js","sourceRoot":"","sources":["../src/Phalanx.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { PhalanxConfig, GameModePreset, CustomGameMode } from '../types/index.js';
2
+ /**
3
+ * Game mode presets configuration
4
+ */
5
+ export declare const GAME_MODES: Record<GameModePreset, CustomGameMode>;
6
+ /**
7
+ * Default configuration values
8
+ */
9
+ export declare const DEFAULT_CONFIG: PhalanxConfig;
10
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACf,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,cAAc,EAAE,cAAc,CAM7D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,aA4C5B,CAAC"}