diff --git a/memo.txt b/memo.txt new file mode 100644 index 00000000..b9730741 --- /dev/null +++ b/memo.txt @@ -0,0 +1,47 @@ +DONE : + + +TODO : + routes gameServer -> Nest : + - validation + - creation de partie + - fin de partie + - mode spectateur + - quelques routes cote serveur + - une interface cote front (liste des matchs en cours) + - etat du client (en ligne, en jeu, ...) + - le chat + +-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- +"Bonus" : + - HTTPS + - mettre le site en ligne +-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- +BUG : + - Bug de son étonnant dans le front, ça pop une fois de temps en temps : + Uncaught (in promise) DOMException: The element has no supported sources. +-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- + +- Comment fonctionne .env ? Comment faire pour ne pas le push sur le depot ? + +- certains status 200 pourrait peut-être être du 204 ? + (exemple dans TwoFactorAuthentication.svelte) + +A la place de : +``` + if (response.status === 401) { + // Wrong + } + if (response.status === 200) { + // Ok + } +``` +On pourrait mettre : +``` + if (!response.ok) { + // Wrong + } + else { + // Ok + } +``` diff --git a/srcs/requirements/game_server/game_back/src/server/class/Client.ts b/srcs/requirements/game_server/game_back/src/server/class/Client.ts index c6e4defa..864472ec 100644 --- a/srcs/requirements/game_server/game_back/src/server/class/Client.ts +++ b/srcs/requirements/game_server/game_back/src/server/class/Client.ts @@ -17,6 +17,8 @@ export class Client { } export class ClientPlayer extends Client { + token: string; + username: string; matchOptions: en.MatchOptions = 0; inputBuffer: ev.EventInput = new ev.EventInput(); lastInputId: number = 0; diff --git a/srcs/requirements/game_server/game_back/src/server/class/GameSession.ts b/srcs/requirements/game_server/game_back/src/server/class/GameSession.ts index 55879135..78e645f5 100644 --- a/srcs/requirements/game_server/game_back/src/server/class/GameSession.ts +++ b/srcs/requirements/game_server/game_back/src/server/class/GameSession.ts @@ -24,15 +24,18 @@ export class GameSession { spectatorsUpdateInterval: NodeJS.Timer | number = 0; components: GameComponentsServer; matchOptions: en.MatchOptions; + isPrivateMatch: boolean; // WIP: could be used to separate leaderboards for example. matchEnded: boolean = false; + lastStateSnapshot: ev.EventGameUpdate; actual_time: number; last_time: number; delta_time: number; - constructor(id: string, matchOptions: en.MatchOptions) { + constructor(id: string, matchOptions: en.MatchOptions, isPrivateMatch: boolean = false) { this.id = id; this.matchOptions = matchOptions; + this.isPrivateMatch = isPrivateMatch; this.components = new GameComponentsServer(this.matchOptions); } start() { @@ -51,6 +54,7 @@ export class GameSession { }); s.actual_time = Date.now(); + s.lastStateSnapshot = s._gameStateSnapshot(); s.gameLoopInterval = setInterval(s._gameLoop, c.serverGameLoopIntervalMS, s); s.playersUpdateInterval = setInterval(s._playersUpdate, c.playersUpdateIntervalMS, s); s.spectatorsUpdateInterval = setInterval(s._spectatorsUpdate, c.spectatorsUpdateIntervalMS, s); @@ -139,16 +143,16 @@ export class GameSession { }); } private _playersUpdate(s: GameSession) { - const gameState: ev.EventGameUpdate = s._gameStateSnapshot(); + s.lastStateSnapshot = s._gameStateSnapshot(); s.playersMap.forEach( (client) => { - gameState.lastInputId = client.lastInputId; - client.socket.send(JSON.stringify(gameState)); + s.lastStateSnapshot.lastInputId = client.lastInputId; + client.socket.send(JSON.stringify(s.lastStateSnapshot)); }); } private _spectatorsUpdate(s: GameSession) { - const gameState = s._gameStateSnapshot(); + s.lastStateSnapshot.lastInputId = 0; s.spectatorsMap.forEach( (client) => { - client.socket.send(JSON.stringify(gameState)); + client.socket.send(JSON.stringify(s.lastStateSnapshot)); }); } private _gameStateSnapshot() : ev.EventGameUpdate { @@ -182,7 +186,12 @@ export class GameSession { { if (Math.abs(gc.scoreLeft - gc.scoreRight) >= 2) { - s._matchEnd(s); + if (gc.scoreLeft > gc.scoreRight) { + s._matchEnd(en.PlayerSide.left); + } + else { + s._matchEnd(en.PlayerSide.right); + } return; } } @@ -197,45 +206,53 @@ export class GameSession { this.matchEnded = true; if (this.playersMap.size != 0) { + console.log("Forfeit Ending"); const gc = this.components; const luckyWinner: ClientPlayer = this.playersMap.values().next().value; - let eventEnd: ev.EventMatchEnd; if (luckyWinner.racket === gc.playerLeft) { - eventEnd = new ev.EventMatchEnd(en.PlayerSide.left, true); - console.log("Player Left WIN (by forfeit)"); + this._matchEnd(en.PlayerSide.left, true); } else { - eventEnd = new ev.EventMatchEnd(en.PlayerSide.right, true); - console.log("Player Right WIN (by forfeit)"); + this._matchEnd(en.PlayerSide.right, true); } - luckyWinner.socket.send(JSON.stringify(eventEnd)); - this.spectatorsMap.forEach( (client) => { - client.socket.send(JSON.stringify(eventEnd)); - }); } return true; } return false; } - private _matchEnd(s: GameSession) { - s.matchEnded = true; - const gc = s.components; - + private async _matchEnd(winner: en.PlayerSide, forfeit_flag: boolean = false) + { + this.matchEnded = true; let eventEnd: ev.EventMatchEnd; - if (gc.scoreLeft > gc.scoreRight) { - eventEnd = new ev.EventMatchEnd(en.PlayerSide.left); + eventEnd = new ev.EventMatchEnd(winner, forfeit_flag); + this.playersMap.forEach( (client) => { + client.socket.send(JSON.stringify(eventEnd)); + }); + this.spectatorsMap.forEach( (client) => { + client.socket.send(JSON.stringify(eventEnd)); + }); + + /* // WIP nest , send match result + const gc = this.components; + await fetch(c.addressBackEnd + "/game/matchEnd", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: this.id, + scoreLeft: gc.scoreLeft, + scoreRight: gc.scoreRight, + }) + }); */ + + // logs + if (winner === en.PlayerSide.left) { console.log("Player Left WIN"); } else { - eventEnd = new ev.EventMatchEnd(en.PlayerSide.right); console.log("Player Right WIN"); } - - s.playersMap.forEach( (client) => { - client.socket.send(JSON.stringify(eventEnd)); - }); - s.spectatorsMap.forEach( (client) => { - client.socket.send(JSON.stringify(eventEnd)); - }); } } diff --git a/srcs/requirements/game_server/game_back/src/server/constants.ts b/srcs/requirements/game_server/game_back/src/server/constants.ts index b7efffd3..3ab0ce0b 100644 --- a/srcs/requirements/game_server/game_back/src/server/constants.ts +++ b/srcs/requirements/game_server/game_back/src/server/constants.ts @@ -8,3 +8,5 @@ export const fixedDeltaTime = serverGameLoopIntervalMS/1000; // second // 33.333ms == 1000/30 export const playersUpdateIntervalMS = 1000/30; // millisecond export const spectatorsUpdateIntervalMS = 1000/30; // millisecond + +export const addressBackEnd = "http://backend_dev:3000"; diff --git a/srcs/requirements/game_server/game_back/src/server/wsServer.ts b/srcs/requirements/game_server/game_back/src/server/wsServer.ts index c11015f2..0001b002 100644 --- a/srcs/requirements/game_server/game_back/src/server/wsServer.ts +++ b/srcs/requirements/game_server/game_back/src/server/wsServer.ts @@ -10,16 +10,17 @@ import { v4 as uuidv4 } from 'uuid'; import * as en from "../shared_js/enums.js" import * as ev from "../shared_js/class/Event.js" +import * as c from "./constants.js" import { Client, ClientPlayer, ClientSpectator } from "./class/Client.js" import { GameSession } from "./class/GameSession.js" import { shortId } from "./utils.js"; import { gameSessionIdPLACEHOLDER } from "./constants.js"; -// pas indispensable d'avoir un autre port si le WebSocket est relié à un serveur http préexistant ? const wsPort = 8042; export const wsServer = new WebSocketServer({host: "0.0.0.0", port: wsPort, path: "/pong"}); const clientsMap: Map = new Map; // socket.id/Client -const matchmakingPlayersMap: Map = new Map; // socket.id/ClientPlayer (duplicates with clientsMap) +const matchmakingMap: Map = new Map; // socket.id/ClientPlayer (duplicates with clientsMap) +const privateMatchmakingMap: Map = new Map; // socket.id/ClientPlayer (duplicates with clientsMap) const gameSessionsMap: Map = new Map; // GameSession.id(url)/GameSession wsServer.on("connection", connectionListener); @@ -54,7 +55,7 @@ function connectionListener(socket: WebSocket, request: IncomingMessage) } -function clientAnnounceListener(this: WebSocket, data: string) +async function clientAnnounceListener(this: WebSocket, data: string) { try { const msg : ev.ClientAnnounce = JSON.parse(data); @@ -65,11 +66,46 @@ function clientAnnounceListener(this: WebSocket, data: string) if (msg.role === en.ClientRole.player) { const announce: ev.ClientAnnouncePlayer = msg; + + // WIP nest, fetch token validation + const body = { + playerOneUsername: announce.username, + playerTwoUsername: "", + gameOptions: announce.matchOptions, + isGameIsWithInvitation: announce.privateMatch, + token: announce.token, + }; + if (announce.privateMatch) { + body.playerTwoUsername = announce.playerTwoUsername; + } + const response = await fetch(c.addressBackEnd + "/game/validateToken", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(body) + }); + if (!response.ok) + { + // send message to client ? or just gtfo ? + clientTerminate(clientsMap.get(this.id)); + return; + } + const player = clientsMap.get(this.id) as ClientPlayer; player.matchOptions = announce.matchOptions; - this.send(JSON.stringify( new ev.EventAssignId(this.id) )); + player.token = announce.token; + player.username = announce.username; + + this.send(JSON.stringify( new ev.EventAssignId(this.id) )); // unused this.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchmakingInProgress) )); - matchmaking(player); + if (announce.privateMatch) { + privateMatchmaking(player); + } + else { + publicMatchmaking(player); + } } else if (msg.role === en.ClientRole.spectator) { @@ -77,6 +113,7 @@ function clientAnnounceListener(this: WebSocket, data: string) const gameSession = gameSessionsMap.get(announce.gameSessionId); if (!gameSession) { // WIP: send "invalid game session" + clientTerminate(clientsMap.get(this.id)); return; } const spectator = clientsMap.get(this.id) as ClientSpectator; @@ -97,15 +134,15 @@ function clientAnnounceListener(this: WebSocket, data: string) } -function matchmaking(player: ClientPlayer) +function publicMatchmaking(player: ClientPlayer) { const minPlayersNumber = 2; const maxPlayersNumber = 2; + matchmakingMap.set(player.id, player); const matchOptions = player.matchOptions; - matchmakingPlayersMap.set(player.id, player); const compatiblePlayers: ClientPlayer[] = []; - for (const [id, client] of matchmakingPlayersMap) + for (const [id, client] of matchmakingMap) { if (client.matchOptions === matchOptions) { @@ -116,17 +153,52 @@ function matchmaking(player: ClientPlayer) } } - if (compatiblePlayers.length < minPlayersNumber) { - return; + if (compatiblePlayers.length >= minPlayersNumber) { + compatiblePlayers.forEach((client) => { + matchmakingMap.delete(client.id); + }); + createGameSession(compatiblePlayers, matchOptions); + } +} + + +function privateMatchmaking(player: ClientPlayer) +{ + const minPlayersNumber = 2; + const maxPlayersNumber = 2; + privateMatchmakingMap.set(player.id, player); + const matchOptions = player.matchOptions; + + const token = player.token; + const compatiblePlayers: ClientPlayer[] = []; + for (const [id, client] of privateMatchmakingMap) + { + if (client.token === token) + { + compatiblePlayers.push(client); + if (compatiblePlayers.length === maxPlayersNumber) { + break; + } + } } + if (compatiblePlayers.length >= minPlayersNumber) { + compatiblePlayers.forEach((client) => { + privateMatchmakingMap.delete(client.id); + }); + createGameSession(compatiblePlayers, matchOptions); + } +} + + +function createGameSession(playersArr: ClientPlayer[], matchOptions: en.MatchOptions) +{ // const id = gameSessionIdPLACEHOLDER; // Force ID, TESTING SPECTATOR const id = uuidv4(); const gameSession = new GameSession(id, matchOptions); gameSessionsMap.set(id, gameSession); - compatiblePlayers.forEach((client) => { - matchmakingPlayersMap.delete(client.id); + playersArr.forEach((client) => { client.gameSession = gameSession; gameSession.playersMap.set(client.id, client); gameSession.unreadyPlayersMap.set(client.id, client); @@ -134,15 +206,15 @@ function matchmaking(player: ClientPlayer) // WIP: Not pretty, hardcoded two players. // Could be done in gameSession maybe ? - compatiblePlayers[0].racket = gameSession.components.playerRight; - compatiblePlayers[1].racket = gameSession.components.playerLeft; + playersArr[0].racket = gameSession.components.playerRight; + playersArr[1].racket = gameSession.components.playerLeft; - compatiblePlayers.forEach((client) => { + playersArr.forEach((client) => { client.socket.once("message", playerReadyConfirmationListener); }); - compatiblePlayers[0].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) )); - compatiblePlayers[1].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) )); + playersArr[0].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.right) )); + playersArr[1].socket.send(JSON.stringify( new ev.EventMatchmakingComplete(en.PlayerSide.left) )); setTimeout(function abortMatch() { if (gameSession.unreadyPlayersMap.size !== 0) @@ -158,7 +230,7 @@ function matchmaking(player: ClientPlayer) } -function playerReadyConfirmationListener(this: WebSocket, data: string) +async function playerReadyConfirmationListener(this: WebSocket, data: string) { try { const msg : ev.ClientEvent = JSON.parse(data); @@ -167,7 +239,34 @@ function playerReadyConfirmationListener(this: WebSocket, data: string) const client = clientsMap.get(this.id); const gameSession = client.gameSession; gameSession.unreadyPlayersMap.delete(this.id); - if (gameSession.unreadyPlayersMap.size === 0) { + if (gameSession.unreadyPlayersMap.size === 0) + { + // WIP nest , send gameSession.id + const gameSessionPlayersIterator = gameSession.playersMap.values(); + const response = await fetch(c.addressBackEnd + "/game/newGameSession", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: gameSession.id, + gameOptions: gameSession.matchOptions, + playerOneUsername: (gameSessionPlayersIterator.next().value).username, + playerTwoUsername: (gameSessionPlayersIterator.next().value).username, + }) + }); + if (!response.ok) + { + gameSessionsMap.delete(gameSession.id); + gameSession.playersMap.forEach((client) => { + client.socket.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchAbort) )); + client.gameSession = null; + clientTerminate(client); + }); + return; + } + gameSession.playersMap.forEach( (client) => { client.socket.send(JSON.stringify( new ev.ServerEvent(en.EventTypes.matchStart) )); }); @@ -227,7 +326,8 @@ const pingInterval = setInterval( () => { } console.log("gameSessionMap size: " + gameSessionsMap.size); console.log("clientsMap size: " + clientsMap.size); - console.log("matchmakingPlayersMap size: " + matchmakingPlayersMap.size); + console.log("matchmakingMap size: " + matchmakingMap.size); + console.log("privateMatchmakingMap size: " + privateMatchmakingMap.size); console.log(""); }, 4200); @@ -247,8 +347,11 @@ function clientTerminate(client: Client) } } clientsMap.delete(client.id); - if (matchmakingPlayersMap.has(client.id)) { - matchmakingPlayersMap.delete(client.id); + if (matchmakingMap.has(client.id)) { + matchmakingMap.delete(client.id); + } + else if (privateMatchmakingMap.has(client.id)) { + privateMatchmakingMap.delete(client.id); } } diff --git a/srcs/requirements/game_server/game_back/src/shared_js/class/Event.ts b/srcs/requirements/game_server/game_back/src/shared_js/class/Event.ts index 992827e4..d1f8b671 100644 --- a/srcs/requirements/game_server/game_back/src/shared_js/class/Event.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/class/Event.ts @@ -89,12 +89,21 @@ export class ClientAnnounce extends ClientEvent { } export class ClientAnnouncePlayer extends ClientAnnounce { - clientId: string; + clientId: string; // unused matchOptions: en.MatchOptions; - constructor(matchOptions: en.MatchOptions, clientId: string = "") { + token: string; + username: string; + privateMatch: boolean; + playerTwoUsername?: string; + constructor(matchOptions: en.MatchOptions, token: string, username: string, privateMatch: boolean = false, playerTwoUsername?: string) { super(en.ClientRole.player); - this.clientId = clientId; this.matchOptions = matchOptions; + this.token = token; + this.username = username; + this.privateMatch = privateMatch; + if (playerTwoUsername) { + this.playerTwoUsername = playerTwoUsername; + } } } diff --git a/srcs/requirements/game_server/game_back/src/shared_js/class/Rectangle.ts b/srcs/requirements/game_server/game_back/src/shared_js/class/Rectangle.ts index bbbb30e5..d258c553 100644 --- a/srcs/requirements/game_server/game_back/src/shared_js/class/Rectangle.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/class/Rectangle.ts @@ -1,6 +1,6 @@ import { Vector, VectorInteger } from "./Vector.js"; -import { Component, Moving } from "./interface.js"; +import type { Component, Moving } from "./interface.js"; import * as c from "../constants.js" export class Rectangle implements Component { diff --git a/srcs/requirements/game_server/game_back/src/shared_js/class/interface.ts b/srcs/requirements/game_server/game_back/src/shared_js/class/interface.ts index 544d54a8..0f484da3 100644 --- a/srcs/requirements/game_server/game_back/src/shared_js/class/interface.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/class/interface.ts @@ -1,5 +1,5 @@ -import { Vector, VectorInteger } from "./Vector.js"; +import type { Vector, VectorInteger } from "./Vector.js"; export interface Component { pos: VectorInteger; diff --git a/srcs/requirements/game_server/game_back/src/shared_js/utils.ts b/srcs/requirements/game_server/game_back/src/shared_js/utils.ts index 6cba06d2..dd3d40d0 100644 --- a/srcs/requirements/game_server/game_back/src/shared_js/utils.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/utils.ts @@ -1,5 +1,5 @@ -import { MovingRectangle } from "./class/Rectangle.js"; +import type { MovingRectangle } from "./class/Rectangle.js"; export function random(min: number = 0, max: number = 1) { return Math.random() * (max - min) + min; diff --git a/srcs/requirements/game_server/game_back/src/shared_js/wallsMovement.ts b/srcs/requirements/game_server/game_back/src/shared_js/wallsMovement.ts index 0f6dbe58..b2c2b581 100644 --- a/srcs/requirements/game_server/game_back/src/shared_js/wallsMovement.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/wallsMovement.ts @@ -1,7 +1,7 @@ import * as c from "./constants.js"; -import { MovingRectangle } from "../shared_js/class/Rectangle.js"; -import { GameComponents } from "./class/GameComponents.js"; +import type { MovingRectangle } from "../shared_js/class/Rectangle.js"; +import type { GameComponents } from "./class/GameComponents.js"; export function wallsMovements(delta: number, gc: GameComponents) { diff --git a/srcs/requirements/svelte/api_front/public/favicon.ico b/srcs/requirements/svelte/api_front/public/favicon.ico new file mode 100644 index 00000000..b7e7e5ca Binary files /dev/null and b/srcs/requirements/svelte/api_front/public/favicon.ico differ diff --git a/srcs/requirements/svelte/api_front/public/favicon.png b/srcs/requirements/svelte/api_front/public/favicon.png deleted file mode 100644 index 7e6f5eb5..00000000 Binary files a/srcs/requirements/svelte/api_front/public/favicon.png and /dev/null differ diff --git a/srcs/requirements/svelte/api_front/public/index.html b/srcs/requirements/svelte/api_front/public/index.html index 2e6a0f20..786ea3ad 100644 --- a/srcs/requirements/svelte/api_front/public/index.html +++ b/srcs/requirements/svelte/api_front/public/index.html @@ -6,7 +6,7 @@ Potato Pong - + diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/0.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/0.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/0.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/0.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/1.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/1.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/1.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/1.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/10.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/10.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/10.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/10.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/11.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/11.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/11.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/11.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/12.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/12.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/12.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/12.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/13.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/13.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/13.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/13.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/14.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/14.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/14.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/14.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/15.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/15.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/15.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/15.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/16.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/16.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/16.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/16.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/17.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/17.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/17.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/17.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/18.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/18.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/18.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/18.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/19.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/19.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/19.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/19.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/2.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/2.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/2.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/2.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/20.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/20.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/20.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/20.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/21.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/21.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/21.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/21.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/22.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/22.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/22.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/22.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/23.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/23.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/23.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/23.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/24.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/24.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/24.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/24.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/25.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/25.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/25.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/25.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/26.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/26.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/26.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/26.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/27.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/27.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/27.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/27.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/28.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/28.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/28.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/28.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/29.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/29.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/29.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/29.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/3.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/3.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/3.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/3.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/30.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/30.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/30.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/30.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/31.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/31.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/31.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/31.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/32.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/32.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/32.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/32.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/4.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/4.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/4.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/4.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/5.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/5.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/5.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/5.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/6.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/6.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/6.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/6.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/7.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/7.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/7.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/7.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/8.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/8.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/8.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/8.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/pong/9.ogg b/srcs/requirements/svelte/api_front/public/sound/pong/9.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/pong/9.ogg rename to srcs/requirements/svelte/api_front/public/sound/pong/9.ogg diff --git a/srcs/requirements/svelte/api_front/public/sounds/roblox-oof.ogg b/srcs/requirements/svelte/api_front/public/sound/roblox-oof.ogg similarity index 100% rename from srcs/requirements/svelte/api_front/public/sounds/roblox-oof.ogg rename to srcs/requirements/svelte/api_front/public/sound/roblox-oof.ogg diff --git a/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte b/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte index 78ab66df..224be713 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte +++ b/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte @@ -34,11 +34,10 @@ let token = ""; //Game's stuff gameserver side - let sound = false; + let sound = "on"; // possible de faire un boolean avec svelte et radio buttons ? let multi_balls = false; let moving_walls = false; - let matchOption : enumeration.MatchOptions = enumeration.MatchOptions.noOption; - + let matchOptions : enumeration.MatchOptions = enumeration.MatchOptions.noOption; //html boolean for pages let showWaitPage = false; let showInvitations = false; @@ -61,71 +60,17 @@ }) const init = async() => { - optionsAreNotSet = false - showWaitPage = true - console.log("Player two username " + playerTwoUsername) if (multi_balls === true) matchOption |= enumeration.MatchOptions.multiBalls if (moving_walls === true ) matchOption |= enumeration.MatchOptions.movingWalls - const res = await fetch("http://transcendance:8080/api/v2/game/ticket", { - method : "POST", - headers : {'Content-Type': 'application/json'}, - body : JSON.stringify({ - playerOneUsername : user.username, - playerTwoUsername : playerTwoUsername, - gameOptions : matchOption, - isGameIsWithInvitation : invite_someone - }) - }) - .then(x => x.json()) - .catch(error => { - console.log(error) - }) - if (res.status === 403 || res.status === 404 || res.status === 500) - { - errorMessageWhenAttemptingToGetATicket = res.message; - showError = true; - setTimeout(() => { - showError = false; - showWaitPage = false - optionsAreNotSet = true - playerTwoUsername = ""; - matchOption = 0; - token = "" - }, 5000) - return ; - } - else if (res.status === 200) - { - initAudio(sound) - initMatchOptions(matchOption) - initPong(new GameArea()) - initGc(new GameComponentsClient(matchOption, pong.ctx)) - initStartFunction(start) - initWebSocket(matchOption) - } - // const fetch = await fetch("http://transcendance:8080/api/v2/game/gameServer/validate", { - // method : "POST", - // headers : {'Content-Type': 'application/json'}, - // body : JSON.stringify({ - // playerOneUsername : user.username, - // playerTwoUsername : playerTwoUsername, - // gameOptions : matchOption, - // isGameIsWithInvitation : invite_someone, - // token : token - // }) - // }) - // .then(x => x.json()) - // .catch(error => { - // console.log(error) - // }) - // if (res.status !== 200) - // { - // showError = true; - // errorMessageWhenAttemptingToGetATicket = "Your session is not valid. Please try again." - // return ; - // } + initAudio(sound) + initMatchOptions(matchOption) + optionsAreNotSet = false + initPong(new GameArea()) + initGc(new GameComponentsClient(matchOption, pong.ctx)) + initStartFunction(start) + initWebSocket(matchOption) } function start() : void { @@ -188,83 +133,35 @@
.
- {#if showError === true} -
-
- Error -

{errorMessageWhenAttemptingToGetATicket}

- -
-
- {/if} - - {#if showWaitPage === true} -
-
- Connecting to the game... -

{waitingMessage}

-
-
- {/if} - {#if optionsAreNotSet} - {#if showGameOption === true} -
-
- -
- game options -
- - -
-
- - -
-
- - -
-
- - -
- {#if invite_someone === true} - - {/if} -
- -
-
-
-
- {/if} - {#if showInvitations} -
- -
- Current invitation(s) - {#if isThereAnyInvitation} - {#each invitations as invitation } -
- {invitation.playerOneUsername} has invited you to play a pong ! - - -
- {/each} - {/if} - {#if isThereAnyInvitation ===false} -

Currently, no one asked to play with you.

- - {/if} -
-
- {/if} +
+
+
+ game options +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+

--- keys ---

+

move up: 'w' or 'up arrow'

+

move down: 's' OR 'down arrow'

+

grid on/off: 'g'

+
{/if}
@@ -276,29 +173,26 @@ @font-face { font-family: "Bit5x3"; - src: url("/fonts/Bit5x3.woff2") format("woff2"),local("Bit5x3"), url("/fonts/Bit5x3.woff") format("woff"); + src: + url("/fonts/Bit5x3.woff2") format("woff2"), + local("Bit5x3"), + url("/fonts/Bit5x3.woff") format("woff"); font-weight: normal; font-style: normal; font-display: swap; } -#preload_font { - font-family: "Bit5x3"; - opacity:0; - height:0; - width:0; - display:inline-block; -} body { margin: 0; background-color: #222425; } #canvas_container { + margin-top: 20px; text-align: center; /* border: dashed rgb(245, 245, 245) 5px; */ /* max-height: 80vh; */ /* overflow: hidden; */ } -#div_game { +#div_game_options { text-align: center; font-family: "Bit5x3"; color: rgb(245, 245, 245); diff --git a/srcs/requirements/svelte/api_front/src/pages/game/client/class/GameComponentsClient.ts b/srcs/requirements/svelte/api_front/src/pages/game/client/class/GameComponentsClient.ts index 9fa0a2a3..63797971 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/client/class/GameComponentsClient.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/client/class/GameComponentsClient.ts @@ -5,7 +5,7 @@ import { Vector, VectorInteger } from "../../shared_js/class/Vector.js"; import { TextElem, TextNumericValue } from "./Text.js"; import { RectangleClient, MovingRectangleClient, RacketClient, BallClient, Line } from "./RectangleClient.js"; import { GameComponents } from "../../shared_js/class/GameComponents.js"; -import { MovingRectangle } from "../../shared_js/class/Rectangle.js"; +import type { MovingRectangle } from "../../shared_js/class/Rectangle.js"; class GameComponentsExtensionForClient extends GameComponents { wallTop: RectangleClient | MovingRectangleClient; diff --git a/srcs/requirements/svelte/api_front/src/pages/game/client/class/InputHistory.ts b/srcs/requirements/svelte/api_front/src/pages/game/client/class/InputHistory.ts index 952693af..f8a7fe4f 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/client/class/InputHistory.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/client/class/InputHistory.ts @@ -1,6 +1,6 @@ -import * as en from "../../shared_js/enums.js" -import * as ev from "../../shared_js/class/Event.js" +import type * as en from "../../shared_js/enums.js" +import type * as ev from "../../shared_js/class/Event.js" export class InputHistory { input: en.InputEnum; diff --git a/srcs/requirements/svelte/api_front/src/pages/game/client/class/RectangleClient.ts b/srcs/requirements/svelte/api_front/src/pages/game/client/class/RectangleClient.ts index 1cc1c4f5..e671fb3f 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/client/class/RectangleClient.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/client/class/RectangleClient.ts @@ -1,6 +1,6 @@ import { Vector, VectorInteger } from "../../shared_js/class/Vector.js"; -import { Component, GraphicComponent, Moving } from "../../shared_js/class/interface.js"; +import type { GraphicComponent } from "../../shared_js/class/interface.js"; import { Rectangle, MovingRectangle, Racket, Ball } from "../../shared_js/class/Rectangle.js"; import { soundPongArr } from "../audio.js" import { random } from "../utils.js"; @@ -81,7 +81,9 @@ export class BallClient extends Ball implements GraphicComponent { } bounce(collider?: Rectangle) { this._bounceAlgo(collider); - soundPongArr[ Math.floor(random(0, soundPongArr.length)) ].play(); + let i = Math.floor(random(0, soundPongArr.length)); + soundPongArr[ i ].play(); + console.log(`sound_i=${i}`); // debug log } } diff --git a/srcs/requirements/svelte/api_front/src/pages/game/client/class/Text.ts b/srcs/requirements/svelte/api_front/src/pages/game/client/class/Text.ts index 11f00ab9..ccdfdc0c 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/client/class/Text.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/client/class/Text.ts @@ -1,6 +1,6 @@ import { Vector, VectorInteger } from "../../shared_js/class/Vector.js"; -import { Component } from "../../shared_js/class/interface.js"; +import type { Component } from "../../shared_js/class/interface.js"; // conflict with Text export class TextElem implements Component { diff --git a/srcs/requirements/svelte/api_front/src/pages/game/client/gameLoop.ts b/srcs/requirements/svelte/api_front/src/pages/game/client/gameLoop.ts index 784841c3..2ba91739 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/client/gameLoop.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/client/gameLoop.ts @@ -3,8 +3,8 @@ import * as c from "./constants.js"; import * as en from "../shared_js/enums.js" import { gc, matchOptions, clientInfo, clientInfoSpectator} from "./global.js"; import { wallsMovements } from "../shared_js/wallsMovement.js"; -import { RacketClient } from "./class/RectangleClient.js"; -import { VectorInteger } from "../shared_js/class/Vector.js"; +import type { RacketClient } from "./class/RectangleClient.js"; +import type { VectorInteger } from "../shared_js/class/Vector.js"; let actual_time: number = Date.now(); let last_time: number; diff --git a/srcs/requirements/svelte/api_front/src/pages/game/client/ws.ts b/srcs/requirements/svelte/api_front/src/pages/game/client/ws.ts index b02ebaec..dc9a88fd 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/client/ws.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/client/ws.ts @@ -30,11 +30,17 @@ export let socket: WebSocket; /* TODO: A way to still use "const" not "let" ? */ export const clientInfo = new ClientInfo(); export const clientInfoSpectator = new ClientInfoSpectator(); // WIP, could refactor this -export function initWebSocket(options: en.MatchOptions) + +export function initWebSocket(options: en.MatchOptions, token: string, username: string, privateMatch = false, playerTwoUsername?: string) { socket = new WebSocket(wsUrl, "json"); socket.addEventListener("open", (event) => { - socket.send(JSON.stringify( new ev.ClientAnnouncePlayer(options, clientInfo.id) )); + if (privateMatch) { + socket.send(JSON.stringify( new ev.ClientAnnouncePlayer(options, token, username, privateMatch, playerTwoUsername) )); + } + else { + socket.send(JSON.stringify( new ev.ClientAnnouncePlayer(options, token, username) )); + } }); // socket.addEventListener("message", logListener); // for testing purpose socket.addEventListener("message", preMatchListener); diff --git a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/Event.ts b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/Event.ts index 992827e4..d1f8b671 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/Event.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/Event.ts @@ -89,12 +89,21 @@ export class ClientAnnounce extends ClientEvent { } export class ClientAnnouncePlayer extends ClientAnnounce { - clientId: string; + clientId: string; // unused matchOptions: en.MatchOptions; - constructor(matchOptions: en.MatchOptions, clientId: string = "") { + token: string; + username: string; + privateMatch: boolean; + playerTwoUsername?: string; + constructor(matchOptions: en.MatchOptions, token: string, username: string, privateMatch: boolean = false, playerTwoUsername?: string) { super(en.ClientRole.player); - this.clientId = clientId; this.matchOptions = matchOptions; + this.token = token; + this.username = username; + this.privateMatch = privateMatch; + if (playerTwoUsername) { + this.playerTwoUsername = playerTwoUsername; + } } } diff --git a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/Rectangle.ts b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/Rectangle.ts index bbbb30e5..d258c553 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/Rectangle.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/Rectangle.ts @@ -1,6 +1,6 @@ import { Vector, VectorInteger } from "./Vector.js"; -import { Component, Moving } from "./interface.js"; +import type { Component, Moving } from "./interface.js"; import * as c from "../constants.js" export class Rectangle implements Component { diff --git a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/interface.ts b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/interface.ts index 544d54a8..0f484da3 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/interface.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/class/interface.ts @@ -1,5 +1,5 @@ -import { Vector, VectorInteger } from "./Vector.js"; +import type { Vector, VectorInteger } from "./Vector.js"; export interface Component { pos: VectorInteger; diff --git a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/utils.ts b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/utils.ts index 6cba06d2..dd3d40d0 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/utils.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/utils.ts @@ -1,5 +1,5 @@ -import { MovingRectangle } from "./class/Rectangle.js"; +import type { MovingRectangle } from "./class/Rectangle.js"; export function random(min: number = 0, max: number = 1) { return Math.random() * (max - min) + min; diff --git a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/wallsMovement.ts b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/wallsMovement.ts index 0f6dbe58..b2c2b581 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/wallsMovement.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/wallsMovement.ts @@ -1,7 +1,7 @@ import * as c from "./constants.js"; -import { MovingRectangle } from "../shared_js/class/Rectangle.js"; -import { GameComponents } from "./class/GameComponents.js"; +import type { MovingRectangle } from "../shared_js/class/Rectangle.js"; +import type { GameComponents } from "./class/GameComponents.js"; export function wallsMovements(delta: number, gc: GameComponents) {