Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
score.service.ts 3.72 KiB
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;
  }
}