diff --git a/Makefile b/Makefile index dba718e5..5b7050eb 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ DOCKERCOMPOSEPATH=./srcs/docker-compose.yml +all : up + #dev allow hot reload. up: @bash ./make_env.sh @@ -11,8 +13,6 @@ start: docker compose -f ${DOCKERCOMPOSEPATH} start docker logs --follow nestjs -all : up - re: down up down: diff --git a/srcs/docker-compose.yml b/srcs/docker-compose.yml index 3d6fa9c2..eadd2da2 100644 --- a/srcs/docker-compose.yml +++ b/srcs/docker-compose.yml @@ -26,7 +26,7 @@ services: volumes: - ./requirements/nestjs/api_back/src:/usr/app/src - ./requirements/nestjs/api_back/test:/usr/app/test/ - - nestjs_photos_volume:/usr/app/src/uploads/avatars + - nestjs_photos_volume:/usr/app/uploads/avatars restart: unless-stopped depends_on: - postgresql 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 864472ec..67076fd3 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 @@ -6,6 +6,7 @@ import * as ev from "../../shared_js/class/Event.js" import * as en from "../../shared_js/enums.js" export class Client { + role: en.ClientRole; socket: WebSocket; id: string; // same as "socket.id" isAlive: boolean = true; @@ -23,9 +24,8 @@ export class ClientPlayer extends Client { inputBuffer: ev.EventInput = new ev.EventInput(); lastInputId: number = 0; racket: Racket; - constructor(socket: WebSocket, id: string, racket: Racket) { + constructor(socket: WebSocket, id: string) { super(socket, id); - this.racket = racket; } } 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 35923df1..8af02ec6 100644 --- a/srcs/requirements/game_server/game_back/src/server/wsServer.ts +++ b/srcs/requirements/game_server/game_back/src/server/wsServer.ts @@ -76,6 +76,8 @@ async function clientAnnounceListener(this: WebSocket, data: string) if (msg.role === en.ClientRole.player) { const announce: ev.ClientAnnouncePlayer = msg; + const player = clientsMap.get(this.id) as ClientPlayer; + player.role = msg.role; const body = { playerOneUsername: announce.username, @@ -106,8 +108,6 @@ async function clientAnnounceListener(this: WebSocket, data: string) clientTerminate(clientsMap.get(this.id)); return; } - - const player = clientsMap.get(this.id) as ClientPlayer; player.matchOptions = announce.matchOptions; player.token = announce.token; player.username = announce.username; @@ -126,13 +126,15 @@ async function clientAnnounceListener(this: WebSocket, data: string) else if (msg.role === en.ClientRole.spectator) { const announce: ev.ClientAnnounceSpectator = msg; + const spectator = clientsMap.get(this.id) as ClientSpectator; + spectator.role = msg.role; + const gameSession = gameSessionsMap.get(announce.gameSessionId); if (!gameSession) { this.send(JSON.stringify( new ev.EventError("invalid gameSessionId") )); clientTerminate(clientsMap.get(this.id)); return; } - const spectator = clientsMap.get(this.id) as ClientSpectator; spectator.gameSession = gameSession; gameSession.spectatorsMap.set(spectator.id, spectator); spectator.socket.once("message", spectatorReadyConfirmationListener); @@ -419,7 +421,7 @@ const pingInterval = setInterval( () => { }, 4200); -export function clientTerminate(client: Client) +export async function clientTerminate(client: Client) { client.socket.terminate(); if (client.gameSession) @@ -439,6 +441,23 @@ export function clientTerminate(client: Client) else if (privateMatchmakingMap.has(client.id)) { privateMatchmakingMap.delete(client.id); } + + if (client.role === en.ClientRole.player) + { + const player = client as ClientPlayer; + console.log("/resetuserstatus " + player.username); + const response = await fetch(c.addressBackEnd + "/game/gameserver/resetuserstatus", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({username: player.username}) + }); + if (!response.ok) { + console.log("/resetuserstatus " + player.username + " failed"); + } + } } diff --git a/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts b/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts index 44de4932..b255592f 100644 --- a/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts +++ b/srcs/requirements/nestjs/api_back/src/auth/42/authentication.controller.ts @@ -5,6 +5,7 @@ import { Response } from 'express'; import { TwoFaDto } from './dto/2fa.dto'; import { UsersService } from 'src/users/users.service'; import { User } from 'src/users/entities/user.entity'; +import { STATUS } from 'src/common/constants/constants'; @Controller('auth') export class AuthenticationController { @@ -36,6 +37,7 @@ export class AuthenticationController { console.log('On redirige'); const user : User = request.user if (user.isEnabledTwoFactorAuth === false || user.isTwoFactorAuthenticated === true){ + this.userService.updateStatus(user.id, STATUS.CONNECTED) console.log('ON VA VERS PROFILE'); return response.status(200).redirect('http://' + process.env.WEBSITE_HOST + ':' + process.env.WEBSITE_PORT + '/#/profile'); } @@ -51,7 +53,7 @@ export class AuthenticationController { @UseGuards(AuthenticateGuard) logout(@Req() request, @Res() response, @Next() next) { this.userService.setIsTwoFactorAuthenticatedWhenLogout(request.user.id); - this.userService.updateStatus(request.user.id, 'disconnected'); + this.userService.updateStatus(request.user.id, STATUS.DISCONNECTED); request.logout(function(err) { if (err) { return next(err); } response.redirect('/'); @@ -83,6 +85,7 @@ export class AuthenticationController { throw new UnauthorizedException('Wrong Code.'); await this.userService.authenticateUserWith2FA(request.user.id); console.log('ON REDIRIGE'); + this.userService.updateStatus(user.id, STATUS.CONNECTED) return response.status(200).redirect('http://' + process.env.WEBSITE_HOST + ':' + process.env.WEBSITE_PORT + '/#/profile'); } } diff --git a/srcs/requirements/nestjs/api_back/src/game/game.controller.ts b/srcs/requirements/nestjs/api_back/src/game/game.controller.ts index b393eaf5..57a87978 100644 --- a/srcs/requirements/nestjs/api_back/src/game/game.controller.ts +++ b/srcs/requirements/nestjs/api_back/src/game/game.controller.ts @@ -101,4 +101,9 @@ export class GameController { { return this.gameService.destroySession(token); } + + @Post('gameserver/resetuserstatus') + async resetUserStatus(@Body('username') username){ + this.gameService.resetStatus(username); + } } 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 a6f7cd02..d6ca27c5 100644 --- a/srcs/requirements/nestjs/api_back/src/game/game.service.ts +++ b/srcs/requirements/nestjs/api_back/src/game/game.service.ts @@ -92,12 +92,17 @@ export class GameService { } this.userRepository.save(user); } - // if (grantTicketDto.isGameIsWithInvitation === true && user.status !== STATUS.IN_GAME) // WIP: need to fix STATUS.IN_GAME if (grantTicketDto.isGameIsWithInvitation === true) { - const secondUser : Partial = await this.userService.findOne(grantTicketDto.playerTwoUsername) - if (!secondUser || secondUser.username === user.username) - return res.status(HttpStatus.NOT_FOUND).json({message : "User not found OR you want to play with yourself."}); + if (grantTicketDto.playerTwoUsername === user.username) { + return res.status(HttpStatus.BAD_REQUEST).json({message : "You cant play against yourself."}); + } + const secondUser : User = await this.userRepository.createQueryBuilder('user') + .where("user.username = :username", {username : grantTicketDto.playerTwoUsername}) + .getOne(); + if (!secondUser) { + return res.status(HttpStatus.NOT_FOUND).json({message : "Invited user not found"}); + } const encryptedTextToReturn = await this.encryptToken(user.username + '_' + secondUser.username + '_' + grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date()) const tok = this.tokenGameRepository.create(grantTicketDto); @@ -106,9 +111,9 @@ export class GameService { tok.token = encryptedTextToReturn; this.tokenGameRepository.save(tok); this.userService.updateStatus(user.id, STATUS.IN_POOL) + this.userService.updateStatus(secondUser.id, STATUS.IN_POOL) return res.status(HttpStatus.OK).json({ token : encryptedTextToReturn }); } - // else if (grantTicketDto.isGameIsWithInvitation === false && user.status !== STATUS.IN_GAME) { // WIP: need to fix STATUS.IN_GAME else if (grantTicketDto.isGameIsWithInvitation === false) { const encryptedTextToReturn = await this.encryptToken(user.username + '_' + grantTicketDto.gameOptions + '_' + grantTicketDto.isGameIsWithInvitation + '_' + new Date()) @@ -142,13 +147,11 @@ export class GameService { const userOne : User = await this.userRepository.createQueryBuilder('user') .where("user.username = :username", {username : tokenGame.playerOneUsername}) .getOne(); - this.userService.updateStatus(userOne.id, STATUS.IN_GAME) 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, STATUS.IN_GAME) } return true; } @@ -168,7 +171,6 @@ export class GameService { const user : User = await this.userRepository.createQueryBuilder('user') .where("user.username = :username", {username : tokenGame.playerOneUsername}) .getOne(); - this.userService.updateStatus(user.id, STATUS.IN_GAME) this.deleteToken(user) return true; } @@ -259,6 +261,14 @@ export class GameService { this.gameRepository.save(game); if (!game) return HttpStatus.INTERNAL_SERVER_ERROR + const playerOne : User = await this.userRepository.createQueryBuilder('user') + .where("user.username = :username", {username : creategameDto.playerOneUsername}) + .getOne(); + const playerTwo : User = await this.userRepository.createQueryBuilder('user') + .where("user.username = :username", {username : creategameDto.playerTwoUsername}) + .getOne(); + this.userService.updateStatus(playerOne.id, STATUS.IN_GAME) + this.userService.updateStatus(playerTwo.id, STATUS.IN_GAME) console.log("200 retourné pour la création de partie") return HttpStatus.OK } @@ -280,6 +290,8 @@ export class GameService { const playerTwo = await this.userRepository.findOneBy({username : game.playerTwoUsername}) if (!playerOne || !playerTwo) return new HttpException("Internal Server Error. Impossible to update the database", HttpStatus.INTERNAL_SERVER_ERROR); + this.userService.updateStatus(playerOne.id, STATUS.CONNECTED); + this.userService.updateStatus(playerTwo.id, STATUS.CONNECTED); if (game.playerOneUsernameResult === game.playerTwoUsernameResult) { this.userService.incrementDraws(playerOne.id) @@ -296,9 +308,14 @@ export class GameService { this.userService.incrementVictories(playerOne.id) this.userService.incrementDefeats(playerTwo.id) } - this.userService.updateStatus(playerOne.id, STATUS.CONNECTED) - this.userService.updateStatus(playerTwo.id, STATUS.CONNECTED) return HttpStatus.OK } + + async resetStatus(username : string){ + const user : User = await this.userRepository.findOneBy({username : username}) + if (!user) + return HttpStatus.NOT_FOUND; + this.userService.updateStatus(user.id, STATUS.CONNECTED); + } } diff --git a/srcs/requirements/svelte/api_front/public/global.css b/srcs/requirements/svelte/api_front/public/global.css index 440eb9e6..1390d18f 100644 --- a/srcs/requirements/svelte/api_front/public/global.css +++ b/srcs/requirements/svelte/api_front/public/global.css @@ -13,11 +13,6 @@ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; /* tmp? */ background: bisque; - - /* overflow-x: hidden; */ - /* This seems to have fixed my pages that are too long */ - /* but now i can't scroll anywhere ... */ - /* overflow-y: hidden; */ } a { diff --git a/srcs/requirements/svelte/api_front/public/img/BACKGROUND.png b/srcs/requirements/svelte/api_front/public/img/BACKGROUND.png new file mode 100644 index 00000000..7f39521f Binary files /dev/null and b/srcs/requirements/svelte/api_front/public/img/BACKGROUND.png differ diff --git a/srcs/requirements/svelte/api_front/public/img/SPLASH_PAGE_BACKGROUND.png b/srcs/requirements/svelte/api_front/public/img/SPLASH_PAGE_BACKGROUND.png new file mode 100644 index 00000000..90136036 Binary files /dev/null and b/srcs/requirements/svelte/api_front/public/img/SPLASH_PAGE_BACKGROUND.png differ diff --git a/srcs/requirements/svelte/api_front/public/img/cartoon_potato1.png b/srcs/requirements/svelte/api_front/public/img/cartoon_potato1.png deleted file mode 100644 index 2db693d7..00000000 Binary files a/srcs/requirements/svelte/api_front/public/img/cartoon_potato1.png and /dev/null differ diff --git a/srcs/requirements/svelte/api_front/public/img/cartoon_potato2.jpg b/srcs/requirements/svelte/api_front/public/img/cartoon_potato2.jpg deleted file mode 100644 index 41ba6dba..00000000 Binary files a/srcs/requirements/svelte/api_front/public/img/cartoon_potato2.jpg and /dev/null differ diff --git a/srcs/requirements/svelte/api_front/public/img/logo_potato.png b/srcs/requirements/svelte/api_front/public/img/logo_potato.png new file mode 100644 index 00000000..3a02aebc Binary files /dev/null and b/srcs/requirements/svelte/api_front/public/img/logo_potato.png differ diff --git a/srcs/requirements/svelte/api_front/public/img/potato_only.png b/srcs/requirements/svelte/api_front/public/img/potato_only.png new file mode 100644 index 00000000..b2f1bb12 Binary files /dev/null and b/srcs/requirements/svelte/api_front/public/img/potato_only.png differ diff --git a/srcs/requirements/svelte/api_front/public/img/tmp_mario_banner.png b/srcs/requirements/svelte/api_front/public/img/tmp_mario_banner.png deleted file mode 100644 index af7cf499..00000000 Binary files a/srcs/requirements/svelte/api_front/public/img/tmp_mario_banner.png and /dev/null differ diff --git a/srcs/requirements/svelte/api_front/public/img/wave-haikei.svg b/srcs/requirements/svelte/api_front/public/img/wave-haikei.svg deleted file mode 100644 index 4a002190..00000000 --- a/srcs/requirements/svelte/api_front/public/img/wave-haikei.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/srcs/requirements/svelte/api_front/src/pages/SplashPage.svelte b/srcs/requirements/svelte/api_front/src/pages/SplashPage.svelte index d2497cb5..996728b8 100644 --- a/srcs/requirements/svelte/api_front/src/pages/SplashPage.svelte +++ b/srcs/requirements/svelte/api_front/src/pages/SplashPage.svelte @@ -9,22 +9,8 @@ user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`) .then((resp) => resp.json()) - // i mean i could do a failed to load user or some shit, maybe with a .catch or something? but atm why bother - - console.log('User var'); - console.log(user); - // if (user && user.statusCode && user.statusCode === 403) { - // console.log('user not logged in') - // } - // if (user && user.username) { - // console.log('we have a user'); - // } - - // user === undefined doesn't work cuz we declared user in the scope of onMount - // if (user === undefined) { if (user && user.statusCode && user.statusCode === 403) { console.log('on mount no user, returned status code 403 so logging out of userStore') - // userLogout(); // which i think should delete any previous local storage } }); @@ -34,8 +20,6 @@ console.log('you are now logged in'); } -// i could prolly put this in it's own compoent, i seem to use it in several places... or maybe just some JS? like no need for html -// we could .then( () => replace('/') ) need the func so TS compatible... const logout = async() => { await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/auth/logout`, { method: 'POST', @@ -46,108 +30,71 @@ -
-

Potato Pong

- -

-
Welcome to
-
Potato Pong
-

-
- - - - - +
+
+ {#if user && user.username} + + + {:else} + + {/if} +
+
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 d2d39d21..b45ab9bb 100644 --- a/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte +++ b/srcs/requirements/svelte/api_front/src/pages/game/Game.svelte @@ -268,25 +268,34 @@
game options -
+ +
-
+ Multiples balls + + +
+ Moving walls + +
-

sound :

- - - - -
-
- - + sound : + +
+ + + {#if options.isSomeoneIsInvited} - - - + sound : + + +
{#if matchList.length !== 0}