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 4a4446ac..38d0039c 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 @@ -229,8 +229,7 @@ export class GameSession { this._forfeit(); } else { - // WIP: envoyer un truc à Nest ? Genre "match draw" - this.destroy(); + this._matchEnd(en.PlayerSide.noSide, true); } return true; } @@ -269,11 +268,16 @@ export class GameSession { gc.scoreLeft = 3; gc.scoreRight = 0; } - else + else if (winner === en.PlayerSide.right) { gc.scoreLeft = 0; gc.scoreRight = 3; } + else + { // TODO: match draw, verifier la getion coté Nest + gc.scoreLeft = 0; + gc.scoreRight = 0; + } } await fetch(c.addressBackEnd + "/game/gameserver/updategame", { diff --git a/srcs/requirements/game_server/game_back/src/shared_js/enums.ts b/srcs/requirements/game_server/game_back/src/shared_js/enums.ts index 6d54e139..d6555451 100644 --- a/srcs/requirements/game_server/game_back/src/shared_js/enums.ts +++ b/srcs/requirements/game_server/game_back/src/shared_js/enums.ts @@ -31,6 +31,7 @@ export enum InputEnum { } export enum PlayerSide { + noSide = 0, left = 1, right } 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 89200706..a4ece577 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte +++ b/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte @@ -13,25 +13,20 @@ let allUsers; //Game's stuff - let optionsAreNotSet = true; const options = new pong.InitOptions(); - - //Game's stuff client side only const gameAreaId = "game_area"; - //html boolean for pages - let showWaitPage = false; - let showInvitations = false; - let showGameOption = true; - let showError = false; + //boolean for html page let hiddenGame = true; - let showMatchEnded = false; + let optionsAreNotSet = true; + let showGameOptions = true; + let showInvitations = false; + let showError = false; + let errorMessage = ""; + let showWaitPage = false; - let isThereAnyInvitation = false; let invitations = []; - let waitingMessage = "Please wait..."; - let errorMessageWhenAttemptingToGetATicket = ""; let watchGameStateInterval; const watchGameStateIntervalRate = 142; @@ -48,6 +43,17 @@ pong.destroy(); }) + function resetPage() { + hiddenGame = true; + optionsAreNotSet = true; + showGameOptions = true; + showInvitations = false; + showError = false; + showWaitPage = false; + options.reset(user.username); + pong.destroy(); + }; + const initGame = async() => { optionsAreNotSet = false; @@ -63,31 +69,29 @@ gameOptions : matchOptions, isGameIsWithInvitation : options.isSomeoneIsInvited }) - }) + }); const responseFromServer = await responseWhenGrantToken; const responseInjson = await responseFromServer.json(); const token : string = responseInjson.token; showWaitPage = false; - console.log("status : " + responseFromServer.status) + console.log("status : " + responseFromServer.status); if (responseFromServer.status != 200) { - console.log(responseInjson) + console.log(responseInjson); console.log("On refuse le ticket"); - errorMessageWhenAttemptingToGetATicket = responseInjson.message; + errorMessage = responseInjson.message; showError = true; - options.reset(); - options.playerOneUsername = user.username; + options.reset(user.username); setTimeout(() => { - optionsAreNotSet = true + optionsAreNotSet = true; showError = false; - // showWaitPage = false // ??? + errorMessage = ""; }, 5000); } else if (token) { watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate); - // options.isInvitedPerson = false // ??? - pong.init(options, gameAreaId, token); + pong.init(matchOptions, options, gameAreaId, token); hiddenGame = false; } // TODO: Un "else" peut-être ? Si pas de token on fait un truc ? @@ -96,25 +100,25 @@ const initGameForInvitedPlayer = async(invitation : any) => { - optionsAreNotSet = false - showWaitPage = true - console.log("invitation : ") - console.log(invitation) + optionsAreNotSet = false; + showWaitPage = true; + console.log("invitation : "); + console.log(invitation); if (invitation.token) { watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate); options.playerOneUsername = invitation.playerOneUsername; options.playerTwoUsername = invitation.playerTwoUsername; options.isSomeoneIsInvited = true; - options.isInvitedPerson = true - pong.init(options, gameAreaId, invitation.token); - showWaitPage = false + options.isInvitedPerson = true; + pong.init(invitation.gameOptions, options, gameAreaId, invitation.token); + showWaitPage = false; hiddenGame = false; } } const watchGameState = () => { - console.log("watchGameState") + console.log("watchGameState"); if (gameState) { // trigger Svelte reactivity gameState.matchStarted = gameState.matchStarted; gameState.matchEnded = gameState.matchEnded; @@ -123,34 +127,24 @@ if (gameState.matchAborted || gameState.matchEnded) { clearInterval(watchGameStateInterval); - console.log("watchGameState, end") - showWaitPage = false - gameState.matchAborted ? - errorMessageWhenAttemptingToGetATicket = "The match has been aborted" - : errorMessageWhenAttemptingToGetATicket = "The match is finished !" - gameState.matchAborted ? showError = true : showMatchEnded = true; + console.log("watchGameState, end"); setTimeout(() => { resetPage(); - errorMessageWhenAttemptingToGetATicket = ""; - isThereAnyInvitation = false; - invitations = []; // ??? - console.log("watchGameState : setTimeout") + console.log("watchGameState : setTimeout"); }, 5000); } } - - const showOptions = () => { - showGameOption = true - showInvitations = false + const switchToGameOptions = () => { + showGameOptions = true; + showInvitations = false; } - const showInvitation = async() => { - showGameOption = false; + const fetchInvitations = async() => { + showGameOptions = false; showInvitations = true; invitations = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/invitations`) - .then(x => x.json()) - invitations.length !== 0 ? isThereAnyInvitation = true : isThereAnyInvitation = false + .then(x => x.json()); } const rejectInvitation = async(invitation) => { @@ -162,30 +156,23 @@ }) }) .then(x => x.json()) - .catch(error => console.log(error)) - showInvitation() + .catch(error => console.log(error)); + fetchInvitations(); } - const acceptInvitation = async(invitation : any) => { - const res = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/accept`, { + const acceptInvitation = async(invitation : any) => + { + const res = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/accept`, { method: "POST", headers: { 'Content-Type': 'application/json'}, body: JSON.stringify({ token : invitation.token }) - }) - .then(x => x.json()) - .catch(error => { - console.log(error) - }) - if (res.status === 200) - { - showInvitation() - initGameForInvitedPlayer(invitation) - } - //Au final c'est utile ! + }).catch(error => console.log(error)); - initGameForInvitedPlayer(invitation) // Luke: normal de initGameForInvitedPlayer() sur un "res.status" different de 200 ? + if (res && res.ok) { + initGameForInvitedPlayer(invitation); + } } function leaveMatch() { @@ -193,16 +180,6 @@ resetPage(); }; - function resetPage() { - hiddenGame = true; - optionsAreNotSet = true - showError = false; - showMatchEnded = false; - options.reset(); - options.playerOneUsername = user.username; - pong.destroy(); - }; -
@@ -210,53 +187,61 @@ Might become useless after CSS rework. -->
- {#if showMatchEnded === true} -
-

{errorMessageWhenAttemptingToGetATicket}

-
- {/if} - {#if showError === true} -
+ {#if showError} +
Error -

{errorMessageWhenAttemptingToGetATicket}

+

{errorMessage}

{/if} + {#if !hiddenGame} + {#if gameState.matchEnded} +
+

The match is finished !

+
+ {:else if gameState.matchAborted} +
+

The match has been aborted

+
+ {/if} + {/if} + + {#if !hiddenGame} - {#if !hiddenGame && gameState.matchStarted && !gameState.matchEnded} -
- + {#if gameState.matchStarted && !gameState.matchEnded} +
+
- {:else if !hiddenGame && !gameState.matchStarted} -
- + {:else if !gameState.matchStarted} +
+
{/if} {/if} - {#if showWaitPage === true} -
+ {#if showWaitPage} +
Connecting to the game... -

{waitingMessage}

+

Please wait...

{/if} - + {#if optionsAreNotSet} - {#if showGameOption === true} + {#if showGameOptions}
-
- -
+
+ +
game options
@@ -277,7 +262,7 @@
- {#if options.isSomeoneIsInvited === true} + {#if options.isSomeoneIsInvited} {/if}
- +
@@ -293,26 +278,23 @@ {/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} -
-
+
+ +
+ invitations + + {#if invitations.length !== 0} + {#each invitations as invitation} +
+ {invitation.playerOneUsername} has invited you to play a pong ! + + +
+ {/each} + {:else} +

Currently, no one asked to play with you.

+ {/if} +
{/if} {/if} @@ -352,22 +334,22 @@ canvas { width: 80%; } -#div_game { +.div_game { margin-top: 20px; text-align: center; font-family: "Bit5x3"; color: rgb(245, 245, 245); font-size: x-large; } -#div_game fieldset { +.div_game fieldset { max-width: 50vw; width: auto; margin: 0 auto; } -#div_game fieldset div { +.div_game fieldset div { padding: 10px; } -#pong_button { +.pong_button { font-family: "Bit5x3"; color: rgb(245, 245, 245); background-color: #333333; @@ -375,18 +357,4 @@ canvas { padding: 10px; } -#users_name { /* UNUSED */ - text-align: center; - font-family: "Bit5x3"; - color: rgb(245, 245, 245); - font-size: x-large; -} -#error_notification { /* UNUSED */ - text-align: center; - display: block; - font-family: "Bit5x3"; - color: rgb(143, 19, 19); - font-size: x-large; -} - diff --git a/srcs/requirements/svelte/api_front/src/pages/game/GameSpectator.svelte b/srcs/requirements/svelte/api_front/src/pages/game/GameSpectator.svelte index 5365ff0e..8f72ab6e 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/GameSpectator.svelte +++ b/srcs/requirements/svelte/api_front/src/pages/game/GameSpectator.svelte @@ -20,8 +20,9 @@ //html boolean for pages let hiddenGame = true; - let hiddenMatchList = false; + let watchGameStateInterval; + const watchGameStateIntervalRate = 142; onMount( async() => { user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`) @@ -31,34 +32,55 @@ const responseForMatchList = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/match/all`) const jsonForMatchList = await responseForMatchList.json(); matchList = jsonForMatchList; - if (matchList.length <= 0) { - hiddenMatchList = true; - } }) onDestroy( async() => { + clearInterval(watchGameStateInterval); pongSpectator.destroy(); }) - async function initGameSpectator(gameSessionId: string, matchOptions: pongSpectator.MatchOptions) { + async function initGameSpectator(gameSessionId: string, matchOptions: pongSpectator.MatchOptions) + { + watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate); pongSpectator.init(matchOptions, sound, gameAreaId, gameSessionId); hiddenGame = false; }; + const watchGameState = () => { + console.log("watchGameState") + if (gameState) { // trigger Svelte reactivity + gameState.matchStarted = gameState.matchStarted; + gameState.matchEnded = gameState.matchEnded; + gameState.matchAborted = gameState.matchAborted; + } + if (gameState.matchAborted || gameState.matchEnded) + { + clearInterval(watchGameStateInterval); + console.log("watchGameState, end") + setTimeout(() => { + resetPage(); + console.log("watchGameState : setTimeout") + }, 5000); + } + } + function leaveMatch() { + clearInterval(watchGameStateInterval); resetPage(); }; async function resetPage() { hiddenGame = true; pongSpectator.destroy(); + fetchMatchList(); + }; + + async function fetchMatchList() { matchList = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/game/match/all`) .then( x => x.json() ); - if (matchList.length <= 0) { - hiddenMatchList = true; - } }; + @@ -67,38 +89,50 @@ Might become useless after CSS rework. -->
+ {#if !hiddenGame} + {#if gameState.matchEnded} +
+

The match is finished !

+
+ {/if} + {/if} + - {#if hiddenGame} -
-
-
- {#if hiddenMatchList} - no match available - {:else} - options -
-

sound :

- - - - -
- - {#each matchList as match} - initGameSpectator(match.gameServerIdOfTheMatch, match.gameOptions)} /> - {/each} - - {/if} -
+ {#if !hiddenGame} + {#if !gameState.matchEnded} +
+
+ {/if} + {/if} -
- {:else} -
- + + + {#if hiddenGame} +
+
+ options + +
+

sound :

+ + + + +
+
+ {#if matchList.length !== 0} + + {#each matchList as match} + initGameSpectator(match.gameServerIdOfTheMatch, match.gameOptions)} /> + {/each} + + {:else} +

no match ongoing

+ {/if}
{/if} @@ -133,26 +167,26 @@ canvas { width: 80%; } -#div_game { +.div_game { margin-top: 20px; text-align: center; font-family: "Bit5x3"; color: rgb(245, 245, 245); font-size: x-large; } -#div_game fieldset { +.div_game fieldset { max-width: 50vw; width: auto; margin: 0 auto; } -#div_game fieldset div { +.div_game fieldset div { padding: 10px; } #match_list { font-family: 'Courier New', Courier, monospace; font-size: large; } -#pong_button { +.pong_button { font-family: "Bit5x3"; color: rgb(245, 245, 245); background-color: #333333; diff --git a/srcs/requirements/svelte/api_front/src/pages/game/client/class/InitOptions.ts b/srcs/requirements/svelte/api_front/src/pages/game/client/class/InitOptions.ts index d09c0597..16c8f73c 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/client/class/InitOptions.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/client/class/InitOptions.ts @@ -7,13 +7,13 @@ export class InitOptions { isInvitedPerson = false; playerOneUsername = ""; playerTwoUsername = ""; - reset() { + reset(playerOneUsername: string) { this.sound = "off"; this.multi_balls = false; this.moving_walls = false; this.isSomeoneIsInvited = false; this.isInvitedPerson = false; - this.playerOneUsername = ""; + this.playerOneUsername = playerOneUsername; this.playerTwoUsername = ""; } } diff --git a/srcs/requirements/svelte/api_front/src/pages/game/client/pong.ts b/srcs/requirements/svelte/api_front/src/pages/game/client/pong.ts index 7667a322..2dc874b7 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/client/pong.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/client/pong.ts @@ -1,5 +1,6 @@ import * as c from "./constants.js" +import type * as en from "../shared_js/enums.js" import { handleInput } from "./handleInput.js"; import { gameLoop } from "./gameLoop.js" import { drawLoop } from "./draw.js"; @@ -10,16 +11,14 @@ export { InitOptions } from "./class/InitOptions.js"; import { initBase, destroyBase, computeMatchOptions } from "./init.js"; export { computeMatchOptions } from "./init.js"; -/* TODO: A way to delay the init of variables, but still use "const" not "let" ? */ import { pong, gc } from "./global.js" import { setStartFunction } from "./global.js" let abortControllerKeydown: AbortController; let abortControllerKeyup: AbortController; -export function init(options: InitOptions, gameAreaId: string, token: string) +export function init(matchOptions: en.MatchOptions, options: InitOptions, gameAreaId: string, token: string) { - const matchOptions = computeMatchOptions(options); initBase(matchOptions, options.sound, gameAreaId); setStartFunction(start); @@ -72,7 +71,6 @@ function start_after_countdown() ); resume(); - gameState.matchStarted = true; } function resume() 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 99c17dd9..4c590539 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 @@ -101,6 +101,7 @@ function preMatchListener(this: WebSocket, event: MessageEvent) msg.matchmakingComplete(); break; case en.EventTypes.matchStart: + gameState.matchStarted = true; socket.removeEventListener("message", preMatchListener); socket.addEventListener("message", inGameListener); startFunction(); @@ -244,6 +245,7 @@ export function preMatchListenerSpectator(this: WebSocket, event: MessageEvent) const data: ev.ServerEvent = JSON.parse(event.data); if (data.type === en.EventTypes.matchStart) { + gameState.matchStarted = true; socket.removeEventListener("message", preMatchListenerSpectator); socket.addEventListener("message", inGameListenerSpectator); socket.send(JSON.stringify( new ev.ClientEvent(en.EventTypes.clientSpectatorReady) )); @@ -324,10 +326,5 @@ function matchEndSpectator(data: ev.EventMatchEnd) console.log("matchEndSpectator"); gameState.matchEnded = true; socket.close(); - // WIP - /* msg.win(); - if (data.forfeit) { - msg.forfeit(clientInfo.side); - } */ } diff --git a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/enums.ts b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/enums.ts index 6d54e139..d6555451 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/shared_js/enums.ts +++ b/srcs/requirements/svelte/api_front/src/pages/game/shared_js/enums.ts @@ -31,6 +31,7 @@ export enum InputEnum { } export enum PlayerSide { + noSide = 0, left = 1, right }