130 lines
3.9 KiB
TypeScript
130 lines
3.9 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
HttpException,
|
|
HttpStatus,
|
|
Param,
|
|
Post,
|
|
Session,
|
|
Sse,
|
|
UseGuards,
|
|
} from '@nestjs/common';
|
|
import { LobbyService } from '../services/games.lobby.service';
|
|
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 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')
|
|
export class GamesController {
|
|
constructor(
|
|
private readonly lobbyService: LobbyService,
|
|
private readonly gameService: GameService,
|
|
private eventEmitter: EventEmitter2,
|
|
) {}
|
|
|
|
@Post('changeStartingDeck')
|
|
@ApiOperation({ summary: 'Pick a different starting deck' })
|
|
@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(':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: Document<Game> & 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<string, any>,
|
|
@Param('id', GamePipe) game: Document<Game> & 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,
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@Param('id', GamePipe) _game: Document<Game> & Game,
|
|
): Observable<{ data: string }> {
|
|
return fromEvent(this.eventEmitter, 'sse.game.' + id).pipe(
|
|
map((payload: any) => {
|
|
return {
|
|
data: JSON.stringify(payload),
|
|
};
|
|
}),
|
|
);
|
|
}
|
|
}
|