Newer
Older
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Not } from 'typeorm';
import {
GameEntity,
Game_PersonEntity,
ObjectivePointEntity,
ObjectivePoint_HistoryEntity,
} from './game.entity';
import { GameDTO, FlagboxEventDTO, GameStateDTO } from './game.dto';
import { FactionEntity } from '../faction/faction.entity';
import { NotificationGateway } from '../notifications/notifications.gateway';
@Injectable()
export class GameService {
constructor(
@InjectRepository(GameEntity)
private gameRepository: Repository<GameEntity>,
@InjectRepository(FactionEntity)
private factionRepository: Repository<FactionEntity>,
@InjectRepository(Game_PersonEntity)
private game_PersonRepository: Repository<Game_PersonEntity>,
@InjectRepository(ObjectivePointEntity)
private objectivePointRepository: Repository<ObjectivePointEntity>,
@InjectRepository(ObjectivePoint_HistoryEntity)
private objectivePoint_HistoryRepository: Repository<
ObjectivePoint_HistoryEntity
>,
private notificationGateway: NotificationGateway,
async createNewGame(personId: PersonEntity, gameData: GameDTO) {
if (await this.gameRepository.findOne({ name: gameData.name })) {
throw new HttpException('Game already exists', HttpStatus.BAD_REQUEST);
const game = await this.gameRepository.create(gameData);
// add gamePerson with role admin to the game
const gamePerson = await this.game_PersonRepository.create({
game: game,
person: personId,
});
await this.game_PersonRepository.insert(gamePerson);
return {
if (
await this.gameRepository.findOne({ name: gameData.name, id: Not(id) })
) {
throw new HttpException(
'Game with the same name already exists',
HttpStatus.BAD_REQUEST,
);
// check for duplicate names in gameData
const factionNames = gameData.factions.map(
({ factionName }) => factionName,
);
const flagboxNodeIds = gameData.objective_points.map(
({ objectivePointDescription }) => objectivePointDescription,
);
if (
new Set(factionNames).size !== factionNames.length ||
new Set(flagboxNodeIds).size !== flagboxNodeIds.length
) {
throw new HttpException(
'No duplicate names allowed!',
HttpStatus.BAD_REQUEST,
);
}
// get factions that have been added previously
let factions = await this.factionRepository.find({ game: id });
// get flagboxes that have been added previously
let flagboxes = await this.objectivePointRepository.find({
game: id,
});
// update game entry in db
const updatedGame = await this.gameRepository.create(gameData);
// iterate factions if any were added
const factionIds = gameData.factions.map(({ factionId }) => factionId);
// delete all existing factions that are not in submitted data
if (!factionIds.includes(faction.factionId)) {
// create / update factions present in the submitted data
gameData.factions.map(async faction => {
let name = await this.factionRepository.create({
...faction,
game: gameId,
});
await this.factionRepository.save(name);
});
} else {
// if no factions are present in data, delete all factions associated with the game
}
// insert the flagboxes to db
if (gameData.objective_points) {
const flagboxIds = gameData.objective_points.map(
({ objectivePointId }) => objectivePointId,
);
flagboxes.map(async flagbox => {
if (!flagboxIds.includes(flagbox.objectivePointDescription)) {
await this.objectivePointRepository.delete(flagbox);
gameData.objective_points.map(async flagbox => {
let newFlagbox = await this.objectivePointRepository.create({
...flagbox,
game: gameId,
});
await this.objectivePointRepository.save(newFlagbox);
});
} else {
await this.objectivePointRepository.delete({ game: id });
// TO DO: ADD FLAGBOX LOCATION TO MAPDRAWING ENTITY
return {
async updateGameStatus(game: GameStateDTO) {
const updatedGame = await this.gameRepository.findOne({ id: game.id });
if (updatedGame) {
updatedGame.state = game.state;
await this.gameRepository.save(updatedGame);
// notify players about game state change
this.notificationGateway.server.emit(game.id, 'event update');
return {
code: 200,
message: 'State was updated',
};
}
throw new HttpException("Game doesn't exist", HttpStatus.BAD_REQUEST);
async listFactions(game: GameEntity) {
return this.factionRepository.find({ game });
}
// TODO: Delete factions from Faction table associated with the deleted game
const games = await this.gameRepository.find();
return games.map(game => {
return game.gameObject();
});
// returns information about a game identified by id
async returnGameInfo(id: string) {
const game = await this.gameRepository.findOne({
where: { id: id },
// sort factions by their name
game.factions.sort(function(a, b) {
return a['factionName'].localeCompare(b['factionName']);
});
// returns flagbox settings
async flagboxQuery(gameId) {
const game = await this.gameRepository.findOne({ id: gameId });
return game.nodesettings;
}
// add events to history and send updates with socket
async flagboxEvent(gameId, data: FlagboxEventDTO) {
// get all the factions associated with the game
const factionRef = await this.factionRepository.find({ game: gameId });
// get reference to the objective
const objectiveRef = await this.objectivePointRepository.findOne({
where: { objectivePointDescription: data.node_id, game: gameId },
});
data.oP_HistoryTimestamp = new Date(Date.now()).toLocaleString();
const eventUpdate = await this.objectivePoint_HistoryRepository.create({
oP_HistoryTimestamp: data.oP_HistoryTimestamp,
action: data.action,
// -1 as 0 means null
capture: data.capture !== 0 ? factionRef[data.capture - 1] : null,
owner: data.owner !== 0 ? factionRef[data.owner - 1] : null,
objective_point: objectiveRef.objectivePointId,
});
await this.objectivePoint_HistoryRepository.insert(eventUpdate);
// send flagbox event to flagbox subscribers
this.notificationGateway.server.emit('flagbox', 'event update');