Skip to content
Snippets Groups Projects
game.service.ts 5.68 KiB
Newer Older
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Not } from 'typeorm';
import { GameEntity, Game_PersonEntity } from './game.entity';
import { GameDTO } from './game.dto';
L4168's avatar
L4168 committed
import { PersonEntity } from '../user/user.entity';
import { GameGroupEntity } from './group.entity';
import { FactionEntity } from './faction.entity';

@Injectable()
export class GameService {
  constructor(
    @InjectRepository(GameEntity)
    private gameRepository: Repository<GameEntity>,
    @InjectRepository(FactionEntity)
    private factionRepository: Repository<FactionEntity>,
    @InjectRepository(PersonEntity)
    private personRepository: Repository<PersonEntity>,
L4168's avatar
L4168 committed
    @InjectRepository(Game_PersonEntity)
    private game_PersonRepository: Repository<Game_PersonEntity>,
    @InjectRepository(GameGroupEntity)
    private game_GroupRepository: Repository<GameGroupEntity>,
  ) {}

  // create a new game
Samuli Virtapohja's avatar
Samuli Virtapohja committed
  async createNewGame(personId: PersonEntity, gameData: GameDTO) {
    try {
      // checks if a game with the same name exists already
      const { name } = gameData;
      if (await this.gameRepository.findOne({ where: { name } })) {
        throw new HttpException('Game already exists', HttpStatus.BAD_REQUEST);
      }
      // else add the game to the database
      const game = await this.gameRepository.create({
        ...gameData,
        factions: gameData.factions,
      });
      await this.gameRepository.insert(game);
      const gamePerson = await this.game_PersonRepository.create({
        faction: null,
        game: game,
        person: personId,
      });
      gamePerson['role'] = 'admin';
      await this.game_PersonRepository.insert(gamePerson);
      return {
        message: 'New game added',
      };
    } catch (error) {
      return error.message;
  }

  // edit already created game
Samuli Virtapohja's avatar
Samuli Virtapohja committed
  async editGame(id: string, gameData: GameDTO) {
L4168's avatar
L4168 committed
    // checks if a game with the same name exists already
    const { name } = gameData;
    if (await this.gameRepository.findOne({ name: name, id: Not(id) })) {
      throw new HttpException('Game already exists', HttpStatus.BAD_REQUEST);
    }
    // update game entry in db
    const updatedGame = await this.gameRepository.create({
      ...gameData,
      factions: gameData.factions,
    });
    updatedGame['id'] = id;
    const gameId = await this.gameRepository.save(updatedGame);
Samuli Virtapohja's avatar
Samuli Virtapohja committed

L4168's avatar
L4168 committed
    // get all the factions that are associated with the game to deny duplicate entries
    const factions = await this.factionRepository.find({
      select: ['factionName'],
L4168's avatar
L4168 committed
      where: { game: gameId },
    });
    const factionNames = factions.map(({ factionName }) => factionName);
L4168's avatar
L4168 committed
    // add the factions to db
    if (gameData.factions) {
      gameData.factions.map(async faction => {
        if (!Object.values(factionNames).includes(faction.name)) {
          let name = await this.factionRepository.create({
            ...faction,
            game: gameId,
          });
          await this.factionRepository.insert(name);
        }
      });
Samuli Virtapohja's avatar
Samuli Virtapohja committed
    }
L4168's avatar
L4168 committed

    return {
      message: 'Game updated',
    };
L4168's avatar
L4168 committed
  }
L4072's avatar
L4072 committed
  async deleteGame(id) {
    // TODO: Delete factions from Faction table associated with the deleted game
L4072's avatar
L4072 committed
    await this.gameRepository.delete({ id });
    return {
      message: 'Game deleted',
    };
  }

  // checks the password, creates an entry in GamePerson table with associated role&faction
  async createGroup(person, gameId, groupData) {
    try {
      // check if the person already is in a group in this game
      const checkDuplicate = await this.game_PersonRepository.findOne({
        person: person,
      });
      if (checkDuplicate) {
        throw new HttpException(
          'You already belong to a group!',
          HttpStatus.BAD_REQUEST,
        );
      }
L4168's avatar
L4168 committed

      // create a group entry and insert it to db
      const group = await this.game_GroupRepository.create({
        ...groupData,
        game: gameId,
      });
      const gameGroup = await this.game_GroupRepository.insert(group);

      // create game_Person entry and insert it to db
      const gamePerson = await this.game_PersonRepository.create({
        role: 'soldier',
        faction: null,
        game: gameId,
        person: person,
        leaderGroup: gameGroup.identifiers[0]['id'],
        group: gameGroup.identifiers[0]['id'],
      });
      await this.game_PersonRepository.insert(gamePerson);
        message: 'created new group',
      };
    } catch (e) {
      return e;
    }
  }

  async showGroups() {
    try {
      return await this.game_GroupRepository.find({
        relations: ['leader', 'players', 'game'],
      });
    } catch (e) {
      return e;
    }
  }

  async joinGroup(person, groupId) {
    try {
      const gameData = await this.game_GroupRepository.findOne({
        where: { id: groupId },
        relations: ['players', 'game'],
      });
      const gamePerson = await this.game_PersonRepository.create({
        role: 'soldier',
        faction: null,
        game: gameData.game,
        person: person,
        leaderGroup: null,
        group: groupId,
      await this.game_PersonRepository.insert(gamePerson);
      return {
        message: 'Joined group',
      };
    } catch (e) {
      return e;
    }
L4168's avatar
L4168 committed
  // returns name and id of each game
  async listGames() {
    const games = await this.gameRepository.find({ relations: ['factions'] });
    return games.map(game => {
      return game.gameObject();
L4168's avatar
L4168 committed

  // returns information about a game identified by id
  async returnGameInfo(id: string) {
    const game = await this.gameRepository.findOne({
      where: { id: id },
      relations: ['factions'],
    });
L4168's avatar
L4168 committed
    return game;
  }