diff --git a/.gitignore b/.gitignore index a50d08a..f79d6ed 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ package-lock.json **/*.bun dist/ +target/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..c62094e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +repos: + - repo: local + hooks: + - id: just-format + name: just format + language: system + entry: bash -c "just format" diff --git a/justfile b/justfile index 65a2f12..601b4af 100644 --- a/justfile +++ b/justfile @@ -1,40 +1,24 @@ -# justfile for Elysia project - -# Install dependencies install: bun install -# Run the development server dev: bun run --watch src/index.ts -# Build the project build: - bun build src/client-entry.ts --outfile dist/bundle.js --define "process.env.WS_URL='ws://localhost:3000/ws'" + bun build --compile --minify --target bun --outfile ./target/gomoku ./src/index.ts + +deploy: build + rsync -avz target/gomoku sepiatonesxyz:~/gomoku -# Run tests test: bun test check: bunx tsc --noEmit --skipLibCheck -# Lint the project -lint: - # Add your lint command here, for example: - # bun run lint - echo "Linting not configured yet" - -# Clean the project clean: rm -rf node_modules rm -rf dist -# Format the code format: bun run prettier . --write - -# Bump version -bump-version: - # Add your version bump command here - echo "Version bump not configured yet" diff --git a/index.html b/public/index.html similarity index 100% rename from index.html rename to public/index.html diff --git a/src/index.ts b/src/index.ts index 9417ee2..b3239f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -49,6 +49,7 @@ const app = new Elysia() } let gameId = query.gameId as string | undefined; + let gameIdInitialized = false; if (gameId) { if (!wsHandler.hasGame(gameId)) { wsHandler.createGame(gameId); @@ -56,12 +57,20 @@ const app = new Elysia() } } else { gameId = wsHandler.createGame(); + gameIdInitialized = true; console.log(`Created new game without specific ID: ${gameId}`); } + if (gameIdInitialized) { + return new Response(null, { + status: 302, + headers: { Location: `/?gameId=${gameId}` }, + }); + } + const displayName = wsHandler.getPlayerName(playerId); - const htmlTemplate = await Bun.file('./index.html').text(); + const htmlTemplate = await Bun.file('./public/index.html').text(); let finalHtml = htmlTemplate .replace( '', @@ -82,8 +91,8 @@ const app = new Elysia() }); }); -app.listen(3000, () => { - console.log( - `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`, - ); +const port = Number(process.env.PORT || 3000); + +app.listen(port, () => { + console.log(`🦊 Elysia is running at ${app.server?.hostname}:${port}`); }); diff --git a/src/web-socket-handler.tsx b/src/web-socket-handler.tsx index 431264a..cf8e705 100644 --- a/src/web-socket-handler.tsx +++ b/src/web-socket-handler.tsx @@ -54,15 +54,25 @@ class GameServer { public handleConnection(ws: WS) { const { playerId } = ws.data.query; - const playerName = this.webSocketHandler.getPlayerName(playerId); // Retrieve name or use ID - const conn = new PlayerConnection(playerId, playerName, ws); - this.connections.set(playerId, conn); - console.log(`Created connection with player ${conn.id} in game ${this.id}`); + if (this.connections.has(playerId)) { + const existingConn = this.connections.get(playerId)!; + existingConn.ws = ws; // Update with new WebSocket + console.log( + `Updated connection for player ${playerId} in game ${this.id}, replacing old WS.`, + ); + } else { + const playerName = this.webSocketHandler.getPlayerName(playerId); // Retrieve name or use ID + const conn = new PlayerConnection(playerId, playerName, ws); + this.connections.set(playerId, conn); + console.log( + `Created new connection with player ${conn.id} in game ${this.id}`, + ); - if (!this.blackPlayerId) { - this.blackPlayerId = conn.id; - } else if (!this.whitePlayerId) { - this.whitePlayerId = conn.id; + if (!this.blackPlayerId) { + this.blackPlayerId = conn.id; + } else if (!this.whitePlayerId) { + this.whitePlayerId = conn.id; + } } if (this.whitePlayerId && this.blackPlayerId) { this.gomoku.status = 'playing'; @@ -76,6 +86,7 @@ class GameServer { public handleDisconnect(ws: WS) { const { playerId } = ws.data.query; this.connections.delete(playerId); + this.broadcastTitle(); } public broadcastBoard() { @@ -734,7 +745,7 @@ export class WebSocketHandler { game.handleDisconnect(ws); console.log(`${playerId} disconnected from game ${gameId}`); - if (game.connections.entries.length == 0) { + if (game.connections.size == 0) { this.games.delete(gameId); console.log(`Game ${gameId} has been deleted (empty).`); }