99 lines
2.7 KiB
TypeScript
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}`,
|
|
);
|
|
});
|