Files
webapp-back/src/games/controllers/games.lobby.controller.ts
T
2024-12-27 22:54:31 +01:00

132 lines
3.4 KiB
TypeScript

import {
Controller,
Get,
Post,
Param,
Delete,
UseGuards,
Session,
HttpException,
HttpStatus,
Patch,
Body,
Sse,
} from '@nestjs/common';
import { LobbyService } from '../services/lobby.service';
import { AuthGuard } from '../guards/auth.guard';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { GamePipe } from '../pipe/game.pipe';
import { Game } from '../schemas/game.schema';
import { Observable, fromEvent, map } from 'rxjs';
import { EventEmitter2 } from '@nestjs/event-emitter';
@ApiTags('lobby')
@Controller('games')
export class LobbyController {
constructor(
private readonly lobbyService: LobbyService,
private eventEmitter: EventEmitter2,
) {}
@Post()
@ApiOperation({ summary: 'Create game' })
@ApiResponse({
status: 201,
description: 'Game successfully created.',
// type: ReadGameDto,
})
@ApiResponse({
status: 400,
description: 'You can only create one game at a time',
})
@ApiResponse({ status: 403, description: 'Forbidden.' })
@UseGuards(AuthGuard)
async create(@Session() session: Record<string, any>) {
const games = await this.lobbyService.findByOwner(session.user);
if (games) {
throw new HttpException(
'You can only create one game at a time',
HttpStatus.BAD_REQUEST,
);
}
return await this.lobbyService.create(session.user);
}
@Get()
@ApiOperation({ summary: 'List all games' })
findAll() {
const games = this.lobbyService.findAll();
return games;
}
@Sse('/subscribe')
subscribe(): Observable<{ data: string }> {
return fromEvent(this.eventEmitter, 'sse.lobby').pipe(
map((payload) => {
return {
data: JSON.stringify(payload),
};
}),
);
}
@Get(':id')
@ApiOperation({ summary: 'Get game information' })
async findOne(@Param('id') id: string, @Param('id', GamePipe) game: Game) {
return game;
// return new ReadGameDto(game);
}
@Delete(':id')
@ApiOperation({ summary: 'Delete game' })
@UseGuards(AuthGuard)
async remove(
@Param('id') id: string,
@Session() session: Record<string, any>,
@Param('id', GamePipe) game: Game,
) {
if (game.owner.userId == session.user.userId) {
throw new HttpException(
'You can only delete games you own',
HttpStatus.FORBIDDEN,
);
}
await this.lobbyService.remove(game);
}
@Post(':id/join')
@ApiOperation({ summary: 'Join game' })
@UseGuards(AuthGuard)
async join(
@Param('id') id: string,
@Session() session: Record<string, any>,
@Param('id', GamePipe) game: Game,
) {
if (game.started) {
throw new HttpException('Game already started', HttpStatus.BAD_REQUEST);
}
if (game.players.some((p) => p.user.userId == session.user.userId)) {
throw new HttpException(
'You are already in this game',
HttpStatus.BAD_REQUEST,
);
}
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<string, any>,
@Param('id', GamePipe) game: Game,
) {
if (game.started) {
throw new HttpException('Game already started', HttpStatus.BAD_REQUEST);
}
return await this.lobbyService.leaveGame(game, session.user);
}
}