diff --git a/common/events.ts b/common/events.ts new file mode 100644 index 0000000..bed0435 --- /dev/null +++ b/common/events.ts @@ -0,0 +1,37 @@ +// Events received by the server +enum ClientEventNames { + CreateRoom = "createRoom", + JoinRoom = "joinRoom", + PlayersUpdate = "playersUpdate", + ExtractNumber = "extractNumber", + ChooseCartella = "chooseCartella", + UnchooseCartella = "unchooseCartella", + StartGame = "startGame", + ChoseAllCartelle = "choseAllCartelle", + PleaseGiveMeCartelle = "pleaseGiveMeCartelle", + GiveAllCartelle = "giveAllCartelle", + Ready = "ready" +} + +// Events sent by the server +enum ServerEventNames { + CreateRoom = "createRoom", + HostClosed = "hostClosed", + JoinRoomError = "joinRoomError", + PlayersUpdate = "playersUpdate", + JoinRoom = "joinRoom", + ExtractedNumber = "extractedNumber", + Progress = "progress", + EndGame = "endGame", + ChosenCartella = "chosenCartella", + UnchosenCartella = "unchosenCartella", + EveryoneChose = "everyoneChose", + StartGameError = "startGameError", + StartingGame = "startingGame", + GaveMeCartelle = "gaveMeCartelle", +} + +export { + ServerEventNames, + ClientEventNames +}; \ No newline at end of file diff --git a/server/types.ts b/common/types.ts similarity index 95% rename from server/types.ts rename to common/types.ts index a459a5b..041f415 100644 --- a/server/types.ts +++ b/common/types.ts @@ -11,10 +11,12 @@ export interface Player { hasTabellone: boolean; cartelle: number[]; choseAllCartelle: boolean; + ready: boolean; } export interface StrippedPlayer { username: string; id: SocketID; + ready: boolean; } export enum TombolaAction { NONE, @@ -39,4 +41,4 @@ export interface Room { export enum RoomJoinError { NoSuchRoom, GameHasStarted -} \ No newline at end of file +}; \ No newline at end of file diff --git a/package.json b/package.json index 33f79e9..89198f6 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "start": "craco start", "build": "craco build", "test": "craco test", - "server": "tsc --build server/tsconfig.json && node build_server" + "server": "tsc --build server/tsconfig.json && node build_server/server" }, "eslintConfig": { "extends": [ diff --git a/server/index.ts b/server/index.ts index 8d1d51a..7785f3b 100644 --- a/server/index.ts +++ b/server/index.ts @@ -6,33 +6,34 @@ import http from 'http'; import socketio from 'socket.io'; import randomstring from "randomstring"; // import routes from './routes'; -import { chooseCartella, choseAllCartelle, createRoom, extractNumber, joinRoom, pleaseGiveMeCartelle, startGame, unchooseCartella, updatePlayers } from './routines/rooms'; +import { chooseCartella, choseAllCartelle, createRoom, extractNumber, joinRoom, pleaseGiveMeCartelle, ready, startGame, unchooseCartella, updatePlayers } from './routines/rooms'; import cartelle from './cartelle'; import { stripIndents } from "common-tags"; import ip from "ip"; +import { ClientEventNames } from "../common/events"; import { config } from "dotenv"; import { join } from 'path'; config({ - path: join(__dirname, "..", ".env") + path: join(__dirname, "..", "..", ".env") }); const app = express(); app.use(express.json()); app.use(express.urlencoded()); -app.use(express.static(path.join(__dirname, '..', 'build'))); +app.use(express.static(path.join(__dirname, '..', '..', 'build'))); // app.use(routes); // 404 route -app.get("*", (req, res) => res.sendFile(path.join(__dirname, '..', 'build', 'index.html'))); +app.get("*", (req, res) => res.sendFile(path.join(__dirname, '..', '..', 'build', 'index.html'))); const server = http.createServer(app); const io = new socketio.Server(server, { cors: { - origin: "http://localhost:8080", + origin: process.env.DOMAIN, methods: ["GET", "POST"] } }); @@ -50,10 +51,11 @@ io.on("connection", (socket: socketio.Socket) => { socket.on("unchooseCartella", unchooseCartella.bind(null, socket, ID)); socket.on("startGame", startGame.bind(null, socket, ID)); socket.on("choseAllCartelle", choseAllCartelle.bind(null, socket, ID)); - socket.on("pleaseGiveMeCartelle", pleaseGiveMeCartelle.bind(null, socket, ID)); - socket.on("giveAllCartelle", () => { - socket.emit("giveAllCartelle", cartelle); + socket.on(ClientEventNames.PleaseGiveMeCartelle, pleaseGiveMeCartelle.bind(null, socket, ID)); + socket.on(ClientEventNames.GiveAllCartelle, () => { + socket.emit(ClientEventNames.GiveAllCartelle, cartelle); }); + socket.on(ClientEventNames.Ready, ready.bind(null, socket, ID)); }) const PORT = process.env.PORT || 8080; diff --git a/server/routines/rooms.ts b/server/routines/rooms.ts index 94d0500..2a8a051 100644 --- a/server/routines/rooms.ts +++ b/server/routines/rooms.ts @@ -1,7 +1,8 @@ import { Socket } from "socket.io"; import randomstring from "randomstring"; -import { PracticalTombolaAction, Room, RoomJoinError, SocketID, SocketWrapper, TombolaAction } from "../types"; +import { PracticalTombolaAction, Room, RoomJoinError, SocketID, SocketWrapper, StrippedPlayer, TombolaAction } from "../../common/types"; import cartelle from "../cartelle"; +import { ServerEventNames } from "../../common/events"; const rooms = new Map(); const flatbellone = [...Array(90).keys()].map(n => n + 1); @@ -29,6 +30,7 @@ export function createRoom(socket: Socket, id: SocketID, username: string) { hasTabellone: false, cartelle: [], choseAllCartelle: false, + ready: true, } ], gameStarted: false, @@ -71,7 +73,8 @@ export function joinRoom(socket: Socket, id: SocketID, username: string, roomID: username, hasTabellone: false, cartelle: [], - choseAllCartelle: false + choseAllCartelle: false, + ready: false, }); room.players.forEach(player => { @@ -100,10 +103,12 @@ export function joinRoom(socket: Socket, id: SocketID, username: string, roomID: export function updatePlayers(socket: Socket, id: SocketID, roomID: string) { if (!rooms.has(roomID)) return socket.emit("playersUpdate", []); - socket.emit("playersUpdate", rooms.get(roomID)!.players.map(player => { + const room = rooms.get(roomID)!; + socket.emit("playersUpdate", room.players.map((player): StrippedPlayer => { return { id: player.socketData.id, - name: player.username + username: player.username, + ready: player.ready } })); } @@ -136,7 +141,8 @@ export function extractNumber(socket: Socket, id: SocketID) { room.winners[previousOne(room.nextProgress) as PracticalTombolaAction] = progressing.map(({ player }) => { return { username: player.username, - id: player.socketData.id + id: player.socketData.id, + ready: player.ready } }); } @@ -259,6 +265,26 @@ export function pleaseGiveMeCartelle(socket: Socket, id: SocketID) { socket.emit("gaveMeCartelle", room.players.find(player => player.socketData.id == id)?.cartelle ?? [0]); } +export function ready(socket: Socket, id: SocketID) { + const roomID = roomIDForID(id) ?? ""; + const room = rooms.get(roomID); + if (!room) + return; + + const i = room.players.findIndex(p => p.socketData.id === id); + room.players[i].ready = !room.players[i].ready; + + everySocket(id).forEach(socket => { + socket.emit(ServerEventNames.PlayersUpdate, room.players.map((p): StrippedPlayer => { + return { + id: p.socketData.id, + username: p.username, + ready: p.ready + } + })) + }); +} + function roomIDForID(id: SocketID): string | undefined { return [...rooms.entries()].find(([k, v]) => { return v.players.map(s => s.socketData.id).includes(id); diff --git a/src/pages/waiting-for-players.tsx b/src/pages/waiting-for-players.tsx index f90ae1d..a39f04e 100644 --- a/src/pages/waiting-for-players.tsx +++ b/src/pages/waiting-for-players.tsx @@ -3,6 +3,7 @@ import React from "react"; import Heading from "../components/Heading"; import { useHistory } from "react-router-dom"; import Modal from "../components/Modal"; +import { StrippedPlayer } from "../../common/types"; interface WaitingForPlayersProps { socket: Socket; @@ -10,13 +11,9 @@ interface WaitingForPlayersProps { gameKey: string; host: boolean; } -interface Player { - id: string; - name: string; -} export const WaitingForPlayers: React.FunctionComponent = ({ socket, socketID, gameKey, host }) => { - const [players, setPlayers] = React.useState([]); + const [players, setPlayers] = React.useState([]); const [open, setOpen] = React.useState(false); const history = useHistory(); @@ -27,7 +24,7 @@ export const WaitingForPlayers: React.FunctionComponent // Request a player update console.log(gameKey); socket.emit("playersUpdate", gameKey); - socket.on("playersUpdate", (players: Player[]) => setPlayers(players)); + socket.on("playersUpdate", (players: StrippedPlayer[]) => setPlayers(players)); socket.on("startingGame", (givesTabellone: boolean) => { history.push(givesTabellone ? "/tabellone" : "/choose-cartelle"); }); @@ -43,7 +40,7 @@ export const WaitingForPlayers: React.FunctionComponent {host && (
@@ -53,14 +50,17 @@ export const WaitingForPlayers: React.FunctionComponent
    {players.map(p => { - return
  1. {p.name} {p.id === socketID && <>(Tu!)}
  2. + return
  3. {p.username} {p.id === socketID && <>(Tu!)}
  4. })}
- {host && ( -
+
+ {host && ( -
- )} + )} + +