import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository, Not } from 'typeorm'; import { FactionEntity, GameGroupEntity } from './faction.entity'; import { JoinFactionDTO, GameGroupDTO, JoinGameGroupDTO, FactionDTO, } from './faction.dto'; import { Game_PersonEntity } from '../game/game.entity'; /* FactionService contains functions for - Joining faction - Leaving faction - Change faction multiplier (not implemented) Group - Creating group - List faction players in groups Player - Promote player - verifying user */ @Injectable() export class FactionService { constructor( @InjectRepository(FactionEntity) private factionRepository: Repository<FactionEntity>, @InjectRepository(Game_PersonEntity) private game_PersonRepository: Repository<Game_PersonEntity>, @InjectRepository(GameGroupEntity) private game_GroupRepository: Repository<GameGroupEntity>, ) {} async joinFaction(person, faction: JoinFactionDTO) { // get faction const factionInDb = await this.factionRepository.findOne({ factionId: faction.factionId, }); if (!factionInDb) { throw new HttpException('No factions exist!', HttpStatus.BAD_REQUEST); } //check if password is correct if (factionInDb.passwordCheck(faction.factionPassword)) { const gameperson = await this.game_PersonRepository.create({ faction: factionInDb, game: faction.game, role: 'soldier', person: person, }); //check if user is already in a faction if ( await this.game_PersonRepository.findOne({ person: person, game: faction.game, }) ) { throw new HttpException( 'You have already joined faction!', HttpStatus.BAD_REQUEST, ); } // insert to database return await this.game_PersonRepository.save(gameperson); } else { throw new HttpException('Invalid password!', HttpStatus.UNAUTHORIZED); } } // removes entry from gameperson async leaveFaction(gamepersonId) { await this.game_PersonRepository.delete({ gamepersonId }); return { message: 'leaved faction', }; } // changes factions multiplier to the value given to FactionDTO // async changeFactionMultiplier(body: FactionDTO) { // const faction = await this.factionRepository.findOne({ // where: { factionId: body.factionId }, // }); // faction.multiplier = body.multiplier; // return await this.factionRepository.save(faction); // } async promotePlayer(body) { const gamepersonId = body.player; // get playerdata const gameperson = await this.game_PersonRepository.findOne({ where: { gamepersonId }, }); if (gameperson) { const promotedPlayer = await this.game_PersonRepository.create( gameperson, ); promotedPlayer.role = body.role; if (body.role === 'admin') { promotedPlayer.faction = null; promotedPlayer.group = null; } return await this.game_PersonRepository.save(promotedPlayer); } throw new HttpException('player does not exist', HttpStatus.BAD_REQUEST); } // checks the password, creates an entry in GamePerson table with associated role&faction async createGroup(person, gameId, groupData: GameGroupDTO) { // get gamePerson ref const gamePerson = await this.game_PersonRepository.findOne({ person: person, game: gameId, }); // check if the authenticated person already belongs to a group let check = await this.game_PersonRepository.findOne({ where: { person: person, game: gameId }, relations: ['group'], }); if (check.group) { throw new HttpException( 'You already belong to a group!', HttpStatus.BAD_REQUEST, ); } // create a group entry and insert it to db const group = await this.game_GroupRepository.create({ ...groupData, leader: gamePerson, }); const gameGroup = await this.game_GroupRepository.insert(group); // update the gamePerson entry with group data gamePerson.group = gamePerson.leaderGroup = gameGroup.identifiers[0]['id']; await this.game_PersonRepository.save(gamePerson); return { message: 'created new group', }; } // get the groups in the given Faction async showGroups(factionId) { let players = await this.game_PersonRepository.find({ where: { faction: factionId }, relations: ['person', 'group'], }); players.sort(function(a, b) { return a.person.name.localeCompare(b.person.name); }); let groups = await this.game_GroupRepository.find({ where: { faction: factionId }, relations: ['leader', 'leader.person'], }); let resObj = await Promise.all( groups.map(async group => { return await { id: group.id, name: group.name, class: group.class, leader: group.leader.person.name, players: [], }; }), ); resObj.push({ id: 'empty-group-id', name: 'No group', class: 'infantry', leader: '', players: [], }); await Promise.all( players.map(async player => { for (let i = 0; i < resObj.length; i++) { if (player.group == null) { resObj[resObj.length - 1].players.push({ gamepersonId: player.gamepersonId, role: player.role, name: player.person.name, }); break; } if (resObj[i].name == player.group.name) { resObj[i].players.push({ gamepersonId: player.gamepersonId, role: player.role, name: player.person.name, }); break; } } }), ); return resObj; } // puts a non admin or faction leader player into a specified group async joinGroup(gameperson, data: JoinGameGroupDTO) { gameperson.group = data.groupId; await this.game_PersonRepository.save(gameperson); return { message: 'Joined group', }; } // checks if player is in a faction and what role the player is in async verifyUser(person, game) { const gameperson = await this.game_PersonRepository.findOne({ where: { person, game }, relations: ['faction', 'group'], }); if (gameperson && gameperson.faction) { return { factionId: gameperson.faction.factionId, factionName: gameperson.faction.factionName, role: gameperson.role, group: gameperson.group ? true : false, }; } else { return gameperson ? { role: gameperson.role } : { role: '' }; } } }