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