gomoku/src/index.ts

99 lines
2.7 KiB
TypeScript

import { Elysia, t } from 'elysia';
import { staticPlugin } from '@elysiajs/static';
import { cookie } from '@elysiajs/cookie';
import { WebSocketHandler } from './game/WebSocketHandler';
import { GameInstance } from './game/GameInstance';
const wsHandler = new WebSocketHandler();
const app = new Elysia()
.use(
staticPlugin({
assets: './public',
prefix: '/',
}),
)
.use(cookie())
.ws('/ws', {
query: t.Object({
gameId: t.String(),
playerId: t.String(),
}),
open(ws) {
const { gameId, playerId } = ws.data.query;
if (!gameId || !playerId) {
console.error(
'WebSocket connection missing gameId or playerId in query params.',
);
ws.send('Error: missing gameId or playerId.');
ws.close();
return;
}
wsHandler.handleConnection(ws);
},
message(ws, message) {
wsHandler.handleMessage(ws, message);
},
close(ws) {
wsHandler.handleDisconnect(ws);
},
})
.get('/', async ({ query, cookie, request: _request }) => {
let playerId: string;
const existingPlayerId = cookie.playerId?.value;
if (existingPlayerId) {
playerId = existingPlayerId;
console.log(`Using existing playerId from cookie: ${playerId}`);
} else {
playerId = `player-${Math.random().toString(36).substring(2, 9)}`;
cookie.playerId.set({
value: playerId,
httpOnly: true,
path: '/',
maxAge: 30 * 24 * 60 * 60,
});
console.log(`Generated new playerId and set cookie: ${playerId}`);
}
const urlGameId = query.gameId as string | undefined;
let game: GameInstance;
if (urlGameId) {
let existingGame = wsHandler.getGame(urlGameId);
if (existingGame) {
game = existingGame;
console.log(`Found existing game: ${urlGameId}`);
} else {
game = wsHandler.createGame(urlGameId);
console.log(`Created new game with provided ID: ${urlGameId}`);
}
} else {
game = wsHandler.createGame();
console.log(`Created new game without specific ID: ${game.id}`);
}
game.addPlayer(playerId);
wsHandler.broadcastGameState(game.id);
const htmlTemplate = await Bun.file('./index.html').text();
let finalHtml = htmlTemplate
.replace(
'<meta name="gameId" content="" />',
`<meta name="gameId" content="${game.id}" />`,
)
.replace(
'<meta name="playerId" content="" />',
`<meta name="playerId" content="${playerId}" />`,
);
return new Response(finalHtml, {
headers: { 'Content-Type': 'text/html' },
status: 200,
});
});
app.listen(3000, () => {
console.log(
`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`,
);
});