Files
back/src/games/controllers/games.controller.ts
T
2024-12-29 00:06:57 +01:00

116 lines
3.1 KiB
TypeScript

import {
Body,
Controller,
HttpException,
HttpStatus,
Param,
Post,
Session,
Sse,
UseGuards,
} from '@nestjs/common';
import { LobbyService } from '../services/lobby.service';
import { AuthGuard } from '../guards/auth.guard';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Game } from '../entities/game.entity';
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 { ConfigService } from '@nestjs/config';
import { SessionData } from 'express-session';
@ApiTags('game')
@Controller('games/:id')
export class GamesController {
constructor(
private readonly lobbyService: LobbyService,
private readonly gameService: GameService,
private eventEmitter: EventEmitter2,
private configService: ConfigService,
) {}
@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 start(
@Param('id') id: string,
@Session() session: SessionData,
@Param('id', GamePipe) game: Game,
) {
if (game.started) {
throw new HttpException('Game already started', HttpStatus.BAD_REQUEST);
}
if (game.players.length < 2 && !this.configService.get('DEV_MODE')) {
throw new HttpException(
'Not enough teams to start the game',
HttpStatus.BAD_REQUEST,
);
}
if (game.owner.id != session.user.id) {
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 has already started' })
@UseGuards(AuthGuard)
surrender(
@Param('id') id: string,
@Session() session: SessionData,
@Param('id', GamePipe) game: Game,
) {
if (!game.started) {
throw new HttpException('Game has not started', HttpStatus.BAD_REQUEST);
}
return this.lobbyService.leaveGame(game, session.user);
}
@Post('kick/:playerId')
@ApiOperation({ summary: 'Kick a player' })
@UseGuards(AuthGuard)
kick(
@Param('id') id: string,
@Session() session: SessionData,
@Param('id', GamePipe) game: Game,
@Param('playerId') playerId: string,
) {
if (session.user.id != game.owner.id) {
throw new HttpException(
'You do do not own this game',
HttpStatus.FORBIDDEN,
);
}
return this.lobbyService.kickPlayer(game, session.user, playerId);
}
@Sse('/subscribe')
subscribe(@Param('id') id: string): Observable<{ data: string }> {
return fromEvent(this.eventEmitter, 'sse.game.' + id).pipe(
map((payload: any) => {
return {
data: JSON.stringify(payload),
};
}),
);
}
}