diff --git a/app/page.tsx b/app/page.tsx index 48f279a..5d90935 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,13 +1,17 @@ 'use client'; import { useRouter } from 'next/navigation'; -import generateID from '@/tools/simpleID'; +import { socket } from '@/socket'; +import { GameUpdate } from '@/types'; export default function Home() { const router = useRouter(); const handleCreateGame = () => { - const id = generateID(); - router.push(`/${id}`); + socket.emit('start'); + + socket.on('new-game', (game: GameUpdate) => { + router.push(`/${game.dmID}`); + }); }; return ( diff --git a/lib/GameStore.ts b/lib/GameStore.ts index ab9e101..e1db643 100644 --- a/lib/GameStore.ts +++ b/lib/GameStore.ts @@ -1,33 +1,56 @@ -import Deck from './TarokkaDeck'; - -import { GameState, GameUpdate, TarokkaGameCard } from '../types'; +import Deck from '@/lib/TarokkaDeck'; +import generateID from '@/tools/simpleID'; +import { GameState, GameUpdate } from '@/types'; const deck = new Deck(); export default class GameStore { - private games: Map; + private dms: Map; + private spectators: Map; constructor() { - this.games = new Map(); + this.dms = new Map(); + this.spectators = new Map(); } - createGame(id: string): GameState { - if (this.games.has(id)) throw new Error(`Game ${id} already exists`); + createGameIDs() { + const dmID = generateID(); + const spectatorID = generateID(); + + if ( + this.dms.has(dmID) || + this.dms.has(spectatorID) || + this.spectators.has(dmID) || + this.spectators.has(spectatorID) + ) { + return this.createGameIDs(); + } + + return { + dmID, + spectatorID, + }; + } + + createGame(): GameState { + const { dmID, spectatorID } = this.createGameIDs(); const newGame: GameState = { - id, + dmID, + spectatorID, players: new Set(), cards: deck.getHand(), lastUpdated: Date.now(), }; - this.games.set(id, newGame); + this.dms.set(dmID, newGame); + this.spectators.set(spectatorID, newGame); return newGame; } joinGame(gameID: string, playerID: string): GameUpdate { - const game = this.games.get(gameID) || this.createGame(gameID); + const game = this.getGame(gameID) || this.createGame(); game.players.add(playerID); game.lastUpdated = Date.now(); @@ -57,7 +80,7 @@ export default class GameStore { } getGame(gameID: string): GameState { - const game = this.games.get(gameID); + const game = this.dms.get(gameID) || this.spectators.get(gameID); if (!game) throw new Error(`Game ${gameID} not found`); @@ -65,12 +88,13 @@ export default class GameStore { } gameUpdate(game: GameState): GameUpdate { - const { id, cards } = game; + const { dmID, spectatorID, cards } = game; - return { id, cards }; + return { dmID, spectatorID, cards }; } deleteGame(gameID: string): void { - this.games.delete(gameID); + this.dms.delete(gameID); + this.spectators.delete(gameID); } } diff --git a/server.ts b/server.ts index dc54bf1..0b35b08 100644 --- a/server.ts +++ b/server.ts @@ -2,8 +2,8 @@ import next from 'next'; import { createServer } from 'http'; import { Server as SocketIOServer, type Socket } from 'socket.io'; -import GameStore from './lib/GameStore'; -import type { ClientUpdate } from './types'; +import GameStore from '@/lib/GameStore'; +import type { ClientUpdate } from '@/types'; const dev = process.env.NODE_ENV !== 'production'; const hostname = '0.0.0.0'; @@ -22,6 +22,14 @@ app.prepare().then(() => { io.on('connection', (socket: Socket) => { console.log(`Client connected: ${socket.id}`); + socket.on('start', () => { + const gameUpdate = gameStore.createGame(); + + console.log(`Socket ${socket.id} started game ${gameUpdate.dmID}`); + + socket.emit('new-game', gameUpdate); + }); + socket.on('join', (gameID) => { socket.join(gameID); const gameUpdate = gameStore.joinGame(gameID, socket.id); diff --git a/types/index.ts b/types/index.ts index 008da02..2d41c75 100644 --- a/types/index.ts +++ b/types/index.ts @@ -63,14 +63,16 @@ export type TarokkaCard = TarokkaBase | TarokkaHigh | TarokkaLow; export type TarokkaGameCard = TarokkaGameBase | TarokkaGameHigh | TarokkaGameLow; export interface GameState { - id: string; + dmID: string; + spectatorID: string; players: Set; cards: TarokkaGameCard[]; lastUpdated: number; } export interface GameUpdate { - id: string; + dmID: string; + spectatorID: string; cards: TarokkaGameCard[]; }