diff --git a/src/replay/replay.module.ts b/src/replay/replay.module.ts index d4d5dc095bf95a9fd2316870d4e3d57a17af321f..6df113387f4dd010e31128a39592062517a5872f 100644 --- a/src/replay/replay.module.ts +++ b/src/replay/replay.module.ts @@ -22,6 +22,8 @@ import { import { ScoreService } from '../score/score.service'; import { ScoreEntity } from '../score/score.entity'; import { NotificationModule } from 'src/notifications/notifications.module'; +import { GameService } from 'src/game/game.service'; +import { TickService } from 'src/game/tick.service'; ///////////////////////////////////////////////////////////////////// /// Replay /// @@ -51,6 +53,8 @@ import { NotificationModule } from 'src/notifications/notifications.module'; FactionService, TrackingService, ScoreService, + GameService, + TickService, ], }) export class ReplayModule {} diff --git a/src/replay/replay.service.ts b/src/replay/replay.service.ts index bb06399aa59082ce46cd98b49b0ca21412f912eb..330029b4ea2846e9cd5325703520a372f5f93101 100644 --- a/src/replay/replay.service.ts +++ b/src/replay/replay.service.ts @@ -1,10 +1,14 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Repository, In } from 'typeorm'; +import { Repository } from 'typeorm'; import * as jwt from 'jsonwebtoken'; import { FactionEntity } from '../faction/faction.entity'; -import { GameEntity } from '../game/game.entity'; +import { + GameEntity, + ObjectivePointEntity, + ObjectivePoint_HistoryEntity, +} from '../game/game.entity'; import { TrackingService } from '../tracking/tracking.service'; import { UserService } from '../user/user.service'; import { FactionService } from '../faction/faction.service'; @@ -13,8 +17,9 @@ import { MapDrawingEntity, MapDrawingHistoryEntity, } from '../draw/coordinate.entity'; -import { ScoreService } from 'src/score/score.service'; -import { ScoreEntity } from 'src/score/score.entity'; +import { ScoreService } from '../score/score.service'; +import { ScoreEntity } from '../score/score.entity'; +import { GameService } from '../game/game.service'; @Injectable() export class ReplayService { @@ -31,35 +36,15 @@ export class ReplayService { private mapHistoryRepository: Repository<MapDrawingHistoryEntity>, @InjectRepository(ScoreEntity) private scoreRepository: Repository<ScoreEntity>, + @InjectRepository(ObjectivePointEntity) + private objectivepointRepository: Repository<ObjectivePointEntity>, private trackingService: TrackingService, private userService: UserService, private factionService: FactionService, private scoreService: ScoreService, + private gameService: GameService, ) {} - /* async replayData(gameId) { - let mapDrawingIds = await this.mapdrawingRepository.find({ - where: { gameId: gameId }, - select: ['mapDrawingId'], - // replay data for Factions - async replayData(gameId) { - const replay = await this.factionRepository.find({ - where: { game: gameId }, - relations: ['mapDrawings', 'scores', 'trackdata'], - }); - let drawings = []; - await Promise.all( - mapDrawingIds.map(async mapId => { - drawings.push( - await this.mapHistoryRepository.find({ - mapdrawing: mapId.mapDrawingId, - }), - ); - }), - ); - return drawings; - } */ - async replayData(gameId) { // // this block returns game's initial location @@ -139,6 +124,10 @@ export class ReplayService { }); }), ); + // + // this function returns all flagbox-events from the game + // + let objectivepoints = await this.returnObjectivePointInfo(gameId); return { location: gamelocation, @@ -146,13 +135,73 @@ export class ReplayService { factions: currentFactions, scores: currentScore, drawings: drawData, + objectivepoints: objectivepoints, }; } + + // returns information about game's flagboxes and all of their events + async returnObjectivePointInfo(gameId) { + const info = await this.objectivepointRepository.find({ + where: { game: gameId }, + relations: ['history', 'history.owner', 'history.capture'], + }); + let response = await Promise.all( + info.map(async obj => { + return await { + objectivePointId: obj.objectivePointId, + objectivePointDescription: obj.objectivePointDescription, + objectivePointMultiplier: obj.objectivePointMultiplier, + data: obj.data, + history: await this.parseHistory(obj.history), + }; + }), + ); + return response; + } + + // loops all events in history array and returns an array of objects formatted for replay + private async parseHistory(history: ObjectivePoint_HistoryEntity[]) { + return await Promise.all( + history.map(async event => { + return { + timestamp: event.oP_HistoryTimestamp, + action: { + status: event.action, + message: { + 0: 'No capture ongoing', + 1: `Captured by ${ + event.owner ? event.owner.factionName : 'neutral' + }`, + 2: `Being captured by ${ + event.capture ? event.capture.factionName : 'neutral' + }`, + }[event.action], + }, + owner: await this.infoHelper(event.owner), + capture: await this.infoHelper(event.capture), + }; + }), + ); + } + + // small helper function that formats data for replay + private async infoHelper(obj) { + return (await obj) + ? { + factionName: obj.factionName, + colour: obj.colour, + } + : { + factionName: 'neutral', + colour: '#000000', + }; + } // generate mockdata for a 3 day game // create x amount of players // assign them to two separate factions // assign them to three separate groups // insert x amount of locations for each players around some lat lng area + // insert x amont of flagbox events // insert x amount of score ticks for score mockdata // use the game's initial geojson to draw game area // @@ -165,6 +214,9 @@ export class ReplayService { // set the LAT and LNG for initial location const LAT = 62.24147; const LNG = 25.72088; + // set the x amount of flagbox events + // not used at the moment + const FLAGBOX_EVENTS = 8; // set the score tick amount // not used at the moment const SCORE_TICKS = 10; @@ -188,6 +240,10 @@ export class ReplayService { await game.factions.forEach(async faction => { groups.push(await this.factionService.showGroups(faction.factionId)); }); + // get all objective point refs + const objectivepoints = await this.objectivepointRepository.find({ + game: gameId, + }); // create x amount of users for the mock game with random username for (let i = 0; i < USER_AMOUNT; i++) { let res = await this.userService.register({ @@ -227,6 +283,10 @@ export class ReplayService { let x = 1; // score ticks with players to sync them await this.scoreService.scoreTick(gameId); + // flagbox events with players to sync them + // use helper function to generate a random event + let event = await this.createEvent(objectivepoints); + await this.gameService.flagboxEvent(gameId, event); // add location entry for each gameperson await Promise.all( gamepersons.map(async gameperson => { @@ -252,4 +312,18 @@ export class ReplayService { message: 'all done', }; } + + // creates randomized events for randomly chosen flagbox + // may result in impossible scenarios where owner is capturing their own flagbox + // use only for testing flagbox replay functionalities + private async createEvent(objectivepoints: ObjectivePointEntity[]) { + let point = + objectivepoints[Math.floor(Math.random() * objectivepoints.length)]; + return await { + node_id: point.objectivePointDescription, + owner: Math.round(Math.random()) + 1, + action: Math.round(Math.random()) ? 2 : 0, + capture: Math.round(Math.random()) + 1, + }; + } }