diff --git a/srcs/requirements/nestjs/api_back/src/common/constants/constants.ts b/srcs/requirements/nestjs/api_back/src/common/constants/constants.ts index b10583b0..bd208814 100644 --- a/srcs/requirements/nestjs/api_back/src/common/constants/constants.ts +++ b/srcs/requirements/nestjs/api_back/src/common/constants/constants.ts @@ -8,6 +8,12 @@ const MIME_TYPES = { 'image/png': 'png' }; +export enum STATUS { + CONNECTED = 'Connected', + DISCONNECTED = 'Disconnected', + IN_GAME = 'In Game', + IN_POOL = 'In Pool', +} export const storageForAvatar = { storage: diskStorage({ diff --git a/srcs/requirements/nestjs/api_back/src/game/game.service.ts b/srcs/requirements/nestjs/api_back/src/game/game.service.ts index 562ab843..9d7c28d9 100644 --- a/srcs/requirements/nestjs/api_back/src/game/game.service.ts +++ b/srcs/requirements/nestjs/api_back/src/game/game.service.ts @@ -12,6 +12,7 @@ import { UsersService } from 'src/users/users.service'; import { CreateGameDto } from './dto/createGame.dto'; import { UpdateGameDto } from './dto/updateGame.dto'; import { FriendshipService } from 'src/friendship/friendship.service'; +import { STATUS } from 'src/common/constants/constants'; @Injectable() export class GameService { @@ -55,11 +56,25 @@ export class GameService { return encryptedTextToReturn } + async deleteToken(user : User){ + const tokenGame = await this.tokenGameRepository.createQueryBuilder('tokengame') + .where('tokengame.playerTwoUsername = :playerTwoUsername', {playerTwoUsername : user.username}) + .orWhere('tokengame.playerOneUsername = :playerOneUsername', {playerOneUsername : user.username}) + .getMany(); + if (tokenGame) + return this.tokenGameRepository.remove(tokenGame); + } + + async generateToken(user : User, grantTicketDto : GrantTicketDto) { console.log(user.status); - if (user.status === "In Game" || user.status === "In Pool") - return new HttpException("You can't play two games", HttpStatus.FORBIDDEN); + if (user.status === STATUS.IN_POOL || user.status === STATUS.IN_GAME) + { + await this.deleteToken(user); + user.status = STATUS.CONNECTED; + this.userRepository.save(user); + } if (grantTicketDto.isGameIsWithInvitation === true) { const secondUser : Partial = await this.userService.findOneByUsername(user.id.toString(), grantTicketDto.playerTwoUsername) @@ -112,6 +127,8 @@ export class GameService { const userTwo : User = await this.userRepository.createQueryBuilder('user') .where("user.username = :username", {username : tokenGame.playerTwoUsername}) .getOne(); + this.deleteToken(userOne) + this.deleteToken(userTwo) this.userService.updateStatus(userTwo.id, "In Game") } return true; @@ -133,6 +150,7 @@ export class GameService { .where("user.username = :username", {username : tokenGame.playerOneUsername}) .getOne(); this.userService.updateStatus(user.id, "In Game") + this.deleteToken(user) return true; } } @@ -249,7 +267,7 @@ export class GameService { game.isMatchIsFinished = true; game.playerOneUsernameResult = updateGameDto.playerOneUsernameResult game.playerTwoUsernameResult = updateGameDto.playerTwoUsernameResult - this.userRepository.save(game); + this.gameRepository.save(game); const playerOne = await this.userRepository.findOneBy({username : game.playerOneUsername}) const playerTwo = await this.userRepository.findOneBy({username : game.playerTwoUsername}) if (!playerOne || !playerTwo) 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 b3ffc753..88b6d176 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte +++ b/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte @@ -26,13 +26,14 @@ let showGameOption = true; let showError = false; let hiddenGame = true; + let showMatchEnded = false; let isThereAnyInvitation = false; let invitations = []; let waitingMessage = "Please wait..." let errorMessageWhenAttemptingToGetATicket = ""; - + let idOfIntevalCheckTerminationOfTheMatch; onMount( async() => { user = await fetch('http://transcendance:8080/api/v2/user') @@ -43,16 +44,30 @@ }) onDestroy( async() => { + options.playerOneUsername = user.username; + showError = false; + showMatchEnded = false; + optionsAreNotSet = true + options.playerTwoUsername = ""; + options.isSomeoneIsInvited = false; + options.isInvitedPerson = false; + options.moving_walls = false; + options.multi_balls = false; + errorMessageWhenAttemptingToGetATicket = ""; + hiddenGame = true; + isThereAnyInvitation = false; + invitations = []; pong.destroy(); + clearInterval(idOfIntevalCheckTerminationOfTheMatch); }) const initGame = async() => { optionsAreNotSet = false; showWaitPage = true; - + idOfIntevalCheckTerminationOfTheMatch = setInterval(matchTermitation, 1000); const matchOptions = pong.computeMatchOptions(options); - + const responseWhenGrantToken = fetch("http://transcendance:8080/api/v2/game/ticket", { method : "POST", headers : {'Content-Type': 'application/json'}, @@ -67,15 +82,24 @@ const responseInjson = await responseFromServer.json(); const token : string = responseInjson.token; showWaitPage = false; - if (!responseFromServer.ok) + if (!responseFromServer.ok || (responseFromServer.status != 200 && responseFromServer.status != 201)) { + console.log(responseInjson) + console.log("On refuse le ticket"); + clearInterval(idOfIntevalCheckTerminationOfTheMatch); errorMessageWhenAttemptingToGetATicket = responseInjson.message; showError = true; + options.playerTwoUsername = ""; + options.playerOneUsername = user.username; + options.isSomeoneIsInvited = false; + options.isInvitedPerson = false; + options.moving_walls = false; + options.multi_balls = false; setTimeout(() => { showError = false; showWaitPage = false optionsAreNotSet = true - options.playerTwoUsername = ""; + }, 5000); } else if (token) @@ -89,6 +113,7 @@ // Pour Cherif: renommer en un truc du genre "initGameForInvitedPlayer" ? const initGameForPrivateParty = async(invitation : any) => { + idOfIntevalCheckTerminationOfTheMatch = setInterval(matchTermitation, 1000); optionsAreNotSet = false showWaitPage = true console.log("invitation : ") @@ -105,6 +130,38 @@ } } + const matchTermitation = () => { + console.log("Ping matchTermitation") + if (matchAbort || matchEnded) + { + clearInterval(idOfIntevalCheckTerminationOfTheMatch); + console.log("matchTermitation was called") + showWaitPage = false + matchAbort ? errorMessageWhenAttemptingToGetATicket = "The match has been aborted" : errorMessageWhenAttemptingToGetATicket = "The match is finished !" + matchAbort ? showError = true : showMatchEnded = true; + hiddenGame = true; + setTimeout(() => { + showError = false; + showMatchEnded = false; + optionsAreNotSet = true + options.playerTwoUsername = ""; + options.playerOneUsername = user.username; + options.isSomeoneIsInvited = false; + options.isInvitedPerson = false; + options.moving_walls = false; + options.multi_balls = false; + errorMessageWhenAttemptingToGetATicket = ""; + options.playerTwoUsername = ""; + hiddenGame = true; + isThereAnyInvitation = false; + invitations = []; + pong.destroy(); + console.log("matchTermitation : setTimeout") + }, 5000); + } + } + + const showOptions = () => { showGameOption = true showInvitations = false @@ -132,7 +189,7 @@ } const acceptInvitation = async(invitation : any) => { - await fetch("http://transcendance:8080/api/v2/game/accept",{ + const res = await fetch("http://transcendance:8080/api/v2/game/accept",{ method: "POST", headers: { 'Content-Type': 'application/json'}, body: JSON.stringify({ @@ -142,9 +199,14 @@ .then(x => x.json()) .catch(error => { console.log(error) - }) - showInvitation() // maybe useless + if (res.status === 200) + { + showInvitation() + initGameForPrivateParty(invitation) + } + //Au final c'est utile ! + initGameForPrivateParty(invitation) } @@ -168,6 +230,12 @@ {/if} + {#if showMatchEnded === true} +
+

{errorMessageWhenAttemptingToGetATicket}

+
+ {/if} + {#if showWaitPage === true}
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 fefb64d1..6f33f98d 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,9 @@ function preMatchListener(this: WebSocket, event: MessageEvent) matchAbort = true; socket.removeEventListener("message", preMatchListener); msg.matchAbort(); + setTimeout(() => { + matchAbort = false; + }, 1000); break; } } @@ -212,6 +215,9 @@ function matchEnd(data: ev.EventMatchEnd) else { msg.lose(); } + setTimeout(() => { + matchEnded = false; + }, 1000); } /* Spectator */ @@ -320,3 +326,4 @@ function matchEndSpectator(data: ev.EventMatchEnd) msg.forfeit(clientInfo.side); } */ } +