Initial commit

This commit is contained in:
2024-12-27 22:54:31 +01:00
parent 024834d309
commit a3dc01171a
19 changed files with 272 additions and 2325 deletions
+38 -66
View File
@@ -9,20 +9,15 @@ import {
Sse,
UseGuards,
} from '@nestjs/common';
import { LobbyService } from '../services/games.lobby.service';
import { LobbyService } from '../services/lobby.service';
import { AuthGuard } from '../guards/auth.guard';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { StartingDeckDto } from '../dto/update-game.dto';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Game } from '../schemas/game.schema';
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, WithTransaction } from '../utils';
import { User } from 'src/users/schemas/user.entity';
import { ReadTeamDto } from '../dto/read-games.dto';
@ApiTags('game')
@Controller('games/:id')
@@ -33,76 +28,57 @@ export class GamesController {
private eventEmitter: EventEmitter2,
) {}
@Post('changeStartingDeck')
@ApiOperation({ summary: 'Pick a different starting deck' })
@Post('/start')
@ApiOperation({ summary: 'Start game' })
@ApiResponse({
status: 201,
description: 'Game successfully started.',
})
@ApiResponse({
status: 400,
description: 'Bad Request',
})
@ApiResponse({
status: 403,
description: 'You can only start games you own',
})
@UseGuards(AuthGuard)
async changeStartingDeck(
@Param('id') id: string,
@Param('id', GamePipe) game: Document<Game> & Game,
@Body() startingDeckDto: StartingDeckDto,
@Session() session: Record<string, string>,
) {
if (game.started) {
throw new HttpException(
'You cannot do that after the game has started',
HttpStatus.BAD_REQUEST,
);
}
const player = getPlayer(session, game);
await this.lobbyService.changeStartingDeck(startingDeckDto, player, game);
}
@Post('endTurn')
@UseGuards(AuthGuard)
async endTurn(
@Param('id') id: string,
@Param('id', GameStartedPipe) game: Document<Game> & Game,
@Session() session: Record<string, string>,
) {
const currentTeam = getCurrentTeam(game);
const currentPlayer = getPlayer(session, game);
if (!isInTeam(currentTeam, currentPlayer)) {
throw new HttpException(
'It is not your turn to play',
HttpStatus.FORBIDDEN,
);
}
if (currentPlayer.discardMarkers || currentPlayer.fuckUMarkers) {
throw new HttpException(
'You must consume all your discard markers before ending your turn',
HttpStatus.FORBIDDEN,
);
}
await this.gameService.endTurn(game);
}
@Post('leave')
@ApiOperation({ summary: "Leave a game that hasn't already started" })
@UseGuards(AuthGuard)
async leave(
async start(
@Param('id') id: string,
@Session() session: Record<string, any>,
@Param('id', GamePipe) game: Document<Game> & Game,
@Param('id', GamePipe) game: Game,
) {
if (game.started) {
throw new HttpException('Game already started', HttpStatus.BAD_REQUEST);
}
return await this.gameService.leaveGame(game, session.user);
if (game.players.length < 2 && !process.env.DEV_MODE) {
throw new HttpException(
'Not enough teams to start the game',
HttpStatus.BAD_REQUEST,
);
}
if (game.owner.userId != session.user.userId) {
throw new HttpException(
'You can only start games you own',
HttpStatus.FORBIDDEN,
);
}
await this.gameService.start(game);
return;
}
@Post('surrender')
@ApiOperation({ summary: "Leave a game that hasn't already started" })
@ApiOperation({ summary: 'Leave a game that has already started' })
@UseGuards(AuthGuard)
async surrender(
@Param('id') id: string,
@Session() session: Record<string, any>,
@Param('id', GamePipe) game: Document<Game> & Game,
@Param('id', GamePipe) game: Game,
) {
if (!game.started) {
throw new HttpException('Game has not started', HttpStatus.BAD_REQUEST);
}
return await this.gameService.leaveGame(game, session.user);
return await this.lobbyService.leaveGame(game, session.user);
}
@Post('kick/:playerId')
@@ -111,7 +87,7 @@ export class GamesController {
async kick(
@Param('id') id: string,
@Session() session: Record<string, any>,
@Param('id', GamePipe) game: Document<Game> & Game,
@Param('id', GamePipe) game: Game,
@Param('playerId') playerId: string,
) {
if (session.user.userId != game.owner.userId) {
@@ -120,15 +96,11 @@ export class GamesController {
HttpStatus.FORBIDDEN,
);
}
return await this.gameService.kickPlayer(game, session.user, playerId);
return await this.lobbyService.kickPlayer(game, session.user, playerId);
}
@Sse('/subscribe')
subscribe(
@Param('id') id: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@Param('id', GamePipe) _game: Document<Game> & Game,
): Observable<{ data: string }> {
subscribe(@Param('id') id: string): Observable<{ data: string }> {
return fromEvent(this.eventEmitter, 'sse.game.' + id).pipe(
map((payload: any) => {
return {