Feat : leave game

This commit is contained in:
2024-08-25 11:09:24 +02:00
parent 062fb155e7
commit 1265633f82
2 changed files with 58 additions and 2 deletions
@@ -152,7 +152,7 @@ export class LobbyController {
HttpStatus.FORBIDDEN,
);
}
this.lobbyService.start(game);
await this.lobbyService.start(game);
return;
}
@@ -178,6 +178,20 @@ export class LobbyController {
HttpStatus.BAD_REQUEST,
);
}
return this.lobbyService.joinGame(game, session.user);
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: Document<Game> & Game,
) {
if (game.started) {
throw new HttpException('Game already started', HttpStatus.BAD_REQUEST);
}
return await this.lobbyService.leaveGame(game, session.user);
}
}
+42
View File
@@ -6,6 +6,7 @@ import mongoose, { Document, Model } from 'mongoose';
import {
ReadContainerDto,
ReadGameDto,
ReadPlayerDto,
ReadTeamDto,
} from '../dto/read-games.dto';
import { User } from 'src/users/schemas/user.entity';
@@ -15,6 +16,7 @@ import { StartingDeckDto, UpdateGameDto } from '../dto/update-game.dto';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { GameService } from './games.service';
import { WithTransaction } from '../utils';
import { platform } from 'os';
@Injectable()
export class LobbyService {
@@ -72,6 +74,46 @@ export class LobbyService {
return 'true!';
}
@WithTransaction
async leaveGame(
game: Document<Game> & 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 index = team.players.findIndex((p) => p.user._id.equals(user._id));
const player = team.players[index];
team.players.splice(index, 1);
this.eventEmitter.emit('sse.lobby', {
type: 'leaveGame',
player: new ReadPlayerDto(player),
game: game._id.toHexString(),
});
this.eventEmitter.emit('sse.game.' + game._id.toHexString(), {
type: 'leaveGame',
player: new ReadPlayerDto(player),
});
if (team.players.length == 0) {
const teamIndex = game.teams.indexOf(team);
game.teams.splice(teamIndex, 1);
}
await game.save({ session });
return 'true!';
}
async findAll(): Promise<ReadGameDto[]> {
const games = await this.gameModel.find().exec();
return await Promise.all(