import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { FactionEntity } from '../faction/faction.entity'; import { ScoreDTO } from './score.dto'; import { ObjectivePoint_HistoryEntity, ObjectivePointEntity, GameEntity, } from '../game/game.entity'; import { ScoreEntity } from './score.entity'; import { NotificationGateway } from '../notifications/notifications.gateway'; @Injectable() export class ScoreService { constructor( @InjectRepository(ScoreEntity) private scoreRepository: Repository<ScoreEntity>, @InjectRepository(ObjectivePointEntity) private flagRepository: Repository<ObjectivePointEntity>, @InjectRepository(ObjectivePoint_HistoryEntity) private flagHistoryRepository: Repository<ObjectivePoint_HistoryEntity>, @InjectRepository(FactionEntity) private factionRepository: Repository<FactionEntity>, private notificationGateway: NotificationGateway, ) {} async addScore(scoreData: ScoreDTO, gameId: GameEntity) { // check if faction exists const faction = await this.factionRepository.findOne({ factionId: scoreData.faction, }); if (!faction) { throw new HttpException('Faction was not found', HttpStatus.BAD_REQUEST); } // get the previous score and add it, if it exists let lastScore = await this.scoreRepository.findOne({ where: { faction: scoreData.faction }, order: { scoreTimeStamp: 'DESC' }, }); if (lastScore) { scoreData.score += lastScore.score * faction.multiplier; } // add the score for Faction const newScore = await this.scoreRepository.create(scoreData); newScore.scoreTimeStamp = Date.now(); await this.scoreRepository.insert(newScore); return { message: 'Score updated!', }; } // function to run on timer tick async scoreTick(gameId) { // get game's flagboxes const flagboxes = await this.flagRepository.find({ game: gameId }); // create an array of DTOs for adding score let scoreData = []; await Promise.all( flagboxes.map(async box => { // get the newest entry in history let current = await this.flagHistoryRepository.findOne({ where: { objective_point: box.objectivePointId }, relations: ['owner'], order: { oP_HistoryTimestamp: 'DESC' }, }); // if result was found, add score to the owner if (current.owner) { let index = await scoreData.findIndex( i => i.faction === current.owner.factionId, ); index !== -1 ? await (scoreData[index]['score'] += box.objectivePointMultiplier * current.owner.multiplier) : await scoreData.push({ score: box.objectivePointMultiplier, faction: current.owner.factionId, }); } }), ); scoreData.map(async data => { await this.addScore(data, gameId); }); this.notificationGateway.server.emit(gameId, { type: 'score-update' }); return { message: 'Scores added', }; } async getScores(gameId: GameEntity) { // find games factions const factions = await this.factionRepository.find({ where: { game: gameId }, relations: ['game'], }); let scores = []; await Promise.all( factions.map(async factionNow => { let score = await this.scoreRepository.findOne({ where: { faction: factionNow }, relations: ['faction'], order: { scoreTimeStamp: 'DESC' }, }); //if score was found, put info to scores array if (score.faction) { scores.push(score); } }), ); return scores; } }