From ad48f25a7df5c4822ae7e0200c8cc544598cef60 Mon Sep 17 00:00:00 2001 From: legonzaur Date: Tue, 27 Aug 2024 11:57:59 +0200 Subject: [PATCH] Chore : move some routes to game domain --- src/games/controllers/games.controller.ts | 41 ++++++++++++- .../controllers/games.lobby.controller.ts | 35 ----------- src/games/services/games.lobby.service.ts | 56 ------------------ src/games/services/games.service.ts | 58 +++++++++++++++++++ 4 files changed, 97 insertions(+), 93 deletions(-) diff --git a/src/games/controllers/games.controller.ts b/src/games/controllers/games.controller.ts index 577045d..01fee7c 100644 --- a/src/games/controllers/games.controller.ts +++ b/src/games/controllers/games.controller.ts @@ -14,13 +14,15 @@ import { AuthGuard } from '../guards/auth.guard'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { StartingDeckDto } from '../dto/update-game.dto'; import { Game } from '../schemas/game.schema'; -import { Document } from 'mongoose'; +import mongoose, { Document } from 'mongoose'; import { GamePipe, GameStartedPipe } from '../pipe/game.pipe'; import { Observable, fromEvent, map } from 'rxjs'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { GameService } from '../services/games.service'; -import { getCurrentTeam, getPlayer, isInTeam } from '../utils'; +import { getCurrentTeam, getPlayer, isInTeam, WithTransaction } from '../utils'; +import { User } from 'src/users/schemas/user.entity'; +import { ReadTeamDto } from '../dto/read-games.dto'; @ApiTags('game') @Controller('games/:id') @@ -75,6 +77,41 @@ export class GamesController { await this.gameService.endTurn(game); } + @Post(':id/leave') + @ApiOperation({ summary: "Leave a game that hasn't already started" }) + @UseGuards(AuthGuard) + async leave( + @Param('id') id: string, + @Session() session: Record, + @Param('id', GamePipe) game: Document & Game, + ) { + if (game.started) { + throw new HttpException('Game already started', HttpStatus.BAD_REQUEST); + } + return await this.gameService.leaveGame(game, session.user); + } + + @Post(':id/kick/:playerId') + @ApiOperation({ summary: 'Kick a player' }) + @UseGuards(AuthGuard) + async kick( + @Param('id') id: string, + @Session() session: Record, + @Param('id', GamePipe) game: Document & Game, + @Param('playerId') playerId: string, + ) { + if (game.started) { + throw new HttpException('Game already started', HttpStatus.BAD_REQUEST); + } + if (session.user.userId != game.owner.userId) { + throw new HttpException( + 'You do do not own this game', + HttpStatus.FORBIDDEN, + ); + } + return await this.gameService.kickPlayer(game, session.user, playerId); + } + @Sse('/subscribe') subscribe( @Param('id') id: string, diff --git a/src/games/controllers/games.lobby.controller.ts b/src/games/controllers/games.lobby.controller.ts index 9b6c0c0..d36f44e 100644 --- a/src/games/controllers/games.lobby.controller.ts +++ b/src/games/controllers/games.lobby.controller.ts @@ -180,39 +180,4 @@ export class LobbyController { } return await this.lobbyService.joinGame(game, session.user); } - - @Post(':id/leave') - @ApiOperation({ summary: "Leave a game that hasn't already started" }) - @UseGuards(AuthGuard) - async leave( - @Param('id') id: string, - @Session() session: Record, - @Param('id', GamePipe) game: Document & Game, - ) { - if (game.started) { - throw new HttpException('Game already started', HttpStatus.BAD_REQUEST); - } - return await this.lobbyService.leaveGame(game, session.user); - } - - @Post(':id/kick/:playerId') - @ApiOperation({ summary: 'Kick a player' }) - @UseGuards(AuthGuard) - async kick( - @Param('id') id: string, - @Session() session: Record, - @Param('id', GamePipe) game: Document & Game, - @Param('playerId') playerId: string, - ) { - if (game.started) { - throw new HttpException('Game already started', HttpStatus.BAD_REQUEST); - } - if (session.user.userId != game.owner.userId) { - throw new HttpException( - 'You do do not own this game', - HttpStatus.FORBIDDEN, - ); - } - return await this.lobbyService.kickPlayer(game, session.user, playerId); - } } diff --git a/src/games/services/games.lobby.service.ts b/src/games/services/games.lobby.service.ts index e17b81c..93ef7d8 100644 --- a/src/games/services/games.lobby.service.ts +++ b/src/games/services/games.lobby.service.ts @@ -74,62 +74,6 @@ export class LobbyService { return 'true!'; } - @WithTransaction - async leaveGame( - game: Document & Game, - user: User, - session?: mongoose.mongo.ClientSession, - ) { - const team = game.teams.find((t) => - t.players.find((p) => p.user._id.equals(user._id)), - ); - if (team == undefined) { - throw new HttpException('User not in game', HttpStatus.FORBIDDEN); - } - if (game.owner._id.equals(user._id)) { - throw new HttpException( - 'You cannot leave a game you own', - HttpStatus.FORBIDDEN, - ); - } - const player = team.players.find((p) => p.user._id.equals(user._id)); - await this.kickPlayer(game, game.owner, player._id.toHexString(), session); - } - - @WithTransaction - async kickPlayer( - game: Document & Game, - user: User, - kickedPlayerId: string, - session?: mongoose.mongo.ClientSession, - ) { - const team = game.teams.find((t) => - t.players.find((p) => p._id.equals(kickedPlayerId)), - ); - if (team == undefined) { - throw new HttpException('User not in game', HttpStatus.FORBIDDEN); - } - const index = team.players.findIndex((p) => p.user._id.equals(user._id)); - team.players.splice(index, 1); - this.eventEmitter.emit('sse.lobby', { - type: 'leaveTeam', - playerId: kickedPlayerId, - team: new ReadTeamDto(team), - game: game._id.toHexString(), - }); - this.eventEmitter.emit('sse.game.' + game._id.toHexString(), { - type: 'leaveTeam', - team: new ReadTeamDto(team), - playerId: kickedPlayerId, - }); - if (team.players.length == 0) { - const teamIndex = game.teams.indexOf(team); - game.teams.splice(teamIndex, 1); - } - - await game.save({ session }); - } - async findAll(): Promise { const games = await this.gameModel.find().exec(); return await Promise.all( diff --git a/src/games/services/games.service.ts b/src/games/services/games.service.ts index 6c9579f..4be07a6 100644 --- a/src/games/services/games.service.ts +++ b/src/games/services/games.service.ts @@ -13,6 +13,8 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; import { WithTransaction, getCurrentTeam, shuffle } from '../utils'; import { TurnService } from './turn.service'; import { CardRole, CardType } from 'src/cards/schemas/cards.types'; +import { User } from 'src/users/schemas/user.entity'; +import { ReadTeamDto } from '../dto/read-games.dto'; @Injectable() export class GameService { @@ -290,6 +292,62 @@ export class GameService { } } + @WithTransaction + async leaveGame( + game: Document & Game, + user: User, + session?: mongoose.mongo.ClientSession, + ) { + const team = game.teams.find((t) => + t.players.find((p) => p.user._id.equals(user._id)), + ); + if (team == undefined) { + throw new HttpException('User not in game', HttpStatus.FORBIDDEN); + } + if (game.owner._id.equals(user._id)) { + throw new HttpException( + 'You cannot leave a game you own', + HttpStatus.FORBIDDEN, + ); + } + const player = team.players.find((p) => p.user._id.equals(user._id)); + await this.kickPlayer(game, game.owner, player._id.toHexString(), session); + } + + @WithTransaction + async kickPlayer( + game: Document & Game, + user: User, + kickedPlayerId: string, + session?: mongoose.mongo.ClientSession, + ) { + const team = game.teams.find((t) => + t.players.find((p) => p._id.equals(kickedPlayerId)), + ); + if (team == undefined) { + throw new HttpException('User not in game', HttpStatus.FORBIDDEN); + } + const index = team.players.findIndex((p) => p.user._id.equals(user._id)); + team.players.splice(index, 1); + this.eventEmitter.emit('sse.lobby', { + type: 'leaveTeam', + playerId: kickedPlayerId, + team: new ReadTeamDto(team), + game: game._id.toHexString(), + }); + this.eventEmitter.emit('sse.game.' + game._id.toHexString(), { + type: 'leaveTeam', + team: new ReadTeamDto(team), + playerId: kickedPlayerId, + }); + if (team.players.length == 0) { + const teamIndex = game.teams.indexOf(team); + game.teams.splice(teamIndex, 1); + } + + await game.save({ session }); + } + @WithTransaction async endGame( game: Document & Game,