Compare commits
	
		
			5 Commits 
		
	
	
		
			237926fdf6
			...
			7867c1d480
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 7867c1d480 | |
|  | 40931645d1 | |
|  | 840695bf0e | |
|  | 57f093f4dc | |
|  | d18986cb1f | 
|  | @ -0,0 +1,34 @@ | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | const mongoose = require('mongoose'); | ||||||
|  | const Schema = mongoose.Schema; | ||||||
|  | 
 | ||||||
|  | const LogVehicleKillSchema = new Schema({ | ||||||
|  |   war: { | ||||||
|  |     type: mongoose.Schema.Types.ObjectId, | ||||||
|  |     ref: 'War', | ||||||
|  |     required: true | ||||||
|  |   }, | ||||||
|  |   time: { | ||||||
|  |     type: Date, | ||||||
|  |     required: true | ||||||
|  |   }, | ||||||
|  |   shooter: { | ||||||
|  |     type: String | ||||||
|  |   }, | ||||||
|  |   target: { | ||||||
|  |     type: String, | ||||||
|  |     required: true | ||||||
|  |   }, | ||||||
|  |   fraction: { | ||||||
|  |     type: String, | ||||||
|  |     enum: ['BLUFOR', 'OPFOR', 'NONE'], | ||||||
|  |     required: true | ||||||
|  |   } | ||||||
|  | }, { | ||||||
|  |   collection: 'logVehicle' | ||||||
|  | }); | ||||||
|  | // optional more indices
 | ||||||
|  | LogVehicleKillSchema.index({war: 1, shooter: 1, target: 1}); | ||||||
|  | 
 | ||||||
|  | module.exports = mongoose.model('LogVehicle', LogVehicleKillSchema); | ||||||
|  | @ -24,6 +24,12 @@ const PlayerSchema = new Schema({ | ||||||
|     set: v => Math.round(v), |     set: v => Math.round(v), | ||||||
|     required: true |     required: true | ||||||
|   }, |   }, | ||||||
|  |   vehicle: { | ||||||
|  |     type: Number, | ||||||
|  |     get: v => Math.round(v), | ||||||
|  |     set: v => Math.round(v), | ||||||
|  |     required: true | ||||||
|  |   }, | ||||||
|   death: { |   death: { | ||||||
|     type: Number, |     type: Number, | ||||||
|     get: v => Math.round(v), |     get: v => Math.round(v), | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ const LogBudgetModel = require('../models/logs/budget'); | ||||||
| const LogRespawnModel = require('../models/logs/respawn'); | const LogRespawnModel = require('../models/logs/respawn'); | ||||||
| const LogReviveModel = require('../models/logs/revive'); | const LogReviveModel = require('../models/logs/revive'); | ||||||
| const LogKillModel = require('../models/logs/kill'); | const LogKillModel = require('../models/logs/kill'); | ||||||
|  | const LogVehicleModel = require('../models/logs/vehicle'); | ||||||
| const LogTransportModel = require('../models/logs/transport'); | const LogTransportModel = require('../models/logs/transport'); | ||||||
| const LogFlagModel = require('../models/logs/flag'); | const LogFlagModel = require('../models/logs/flag'); | ||||||
| const LogPointsModel = require('../models/logs/points'); | const LogPointsModel = require('../models/logs/points'); | ||||||
|  | @ -43,6 +44,7 @@ logsRouter.route('/:warId') | ||||||
|             const respawnObjects = LogRespawnModel.find(filter, {}, sort); |             const respawnObjects = LogRespawnModel.find(filter, {}, sort); | ||||||
|             const reviveObjects = LogReviveModel.find(filter, {}, sort); |             const reviveObjects = LogReviveModel.find(filter, {}, sort); | ||||||
|             const killObjects = LogKillModel.find(filter, {}, sort); |             const killObjects = LogKillModel.find(filter, {}, sort); | ||||||
|  |             const vehicleObjects = LogVehicleModel.find(filter, {}, sort); | ||||||
|             const transportObjects = LogTransportModel.find(filter, {}, sort); |             const transportObjects = LogTransportModel.find(filter, {}, sort); | ||||||
|             const flagObjects = LogFlagModel.find(filter, {}, sort); |             const flagObjects = LogFlagModel.find(filter, {}, sort); | ||||||
|             const resources = { |             const resources = { | ||||||
|  | @ -51,6 +53,7 @@ logsRouter.route('/:warId') | ||||||
|               respawn: respawnObjects.exec.bind(respawnObjects), |               respawn: respawnObjects.exec.bind(respawnObjects), | ||||||
|               revive: reviveObjects.exec.bind(reviveObjects), |               revive: reviveObjects.exec.bind(reviveObjects), | ||||||
|               kill: killObjects.exec.bind(killObjects), |               kill: killObjects.exec.bind(killObjects), | ||||||
|  |               vehicle: killObjects.exec.bind(vehicleObjects), | ||||||
|               transport: transportObjects.exec.bind(transportObjects), |               transport: transportObjects.exec.bind(transportObjects), | ||||||
|               flag: flagObjects.exec.bind(flagObjects) |               flag: flagObjects.exec.bind(flagObjects) | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
|  | @ -38,6 +38,7 @@ campaignPlayer.route('/ranking/:campaignId') | ||||||
|                       const resItem = { |                       const resItem = { | ||||||
|                         name: playerName, |                         name: playerName, | ||||||
|                         kill: 0, |                         kill: 0, | ||||||
|  |                         vehicle: 0, | ||||||
|                         death: 0, |                         death: 0, | ||||||
|                         friendlyFire: 0, |                         friendlyFire: 0, | ||||||
|                         revive: 0, |                         revive: 0, | ||||||
|  | @ -48,6 +49,7 @@ campaignPlayer.route('/ranking/:campaignId') | ||||||
|                         resItem.kill += playerInstances[i].kill; |                         resItem.kill += playerInstances[i].kill; | ||||||
|                         resItem.death += playerInstances[i].death; |                         resItem.death += playerInstances[i].death; | ||||||
|                         resItem.friendlyFire += playerInstances[i].friendlyFire; |                         resItem.friendlyFire += playerInstances[i].friendlyFire; | ||||||
|  |                         resItem.vehicle += playerInstances[i].vehicle; | ||||||
|                         resItem.revive += playerInstances[i].revive; |                         resItem.revive += playerInstances[i].revive; | ||||||
|                         resItem.respawn += playerInstances[i].respawn; |                         resItem.respawn += playerInstances[i].respawn; | ||||||
|                         resItem.flagTouch += playerInstances[i].flagTouch; |                         resItem.flagTouch += playerInstances[i].flagTouch; | ||||||
|  | @ -70,6 +72,7 @@ campaignPlayer.route('/ranking/:campaignId') | ||||||
|                       kill: getSortedField('kill'), |                       kill: getSortedField('kill'), | ||||||
|                       death: getSortedField('death'), |                       death: getSortedField('death'), | ||||||
|                       friendlyFire: getSortedField('friendlyFire'), |                       friendlyFire: getSortedField('friendlyFire'), | ||||||
|  |                       vehicle: getSortedField('vehicle'), | ||||||
|                       revive: getSortedField('revive'), |                       revive: getSortedField('revive'), | ||||||
|                       respawn: getSortedField('respawn'), |                       respawn: getSortedField('respawn'), | ||||||
|                       flagTouch: getSortedField('flagTouch') |                       flagTouch: getSortedField('flagTouch') | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ const CampaignModel = require('../models/campaign'); | ||||||
| const WarModel = require('../models/war'); | const WarModel = require('../models/war'); | ||||||
| const PlayerModel = require('../models/player'); | const PlayerModel = require('../models/player'); | ||||||
| const LogKillModel = require('../models/logs/kill'); | const LogKillModel = require('../models/logs/kill'); | ||||||
|  | const LogVehicleKillModel = require('../models/logs/vehicle'); | ||||||
| const LogRespawnModel = require('../models/logs/respawn'); | const LogRespawnModel = require('../models/logs/respawn'); | ||||||
| const LogReviveModel = require('../models/logs/revive'); | const LogReviveModel = require('../models/logs/revive'); | ||||||
| const LogTransportModel = require('../models/logs/transport'); | const LogTransportModel = require('../models/logs/transport'); | ||||||
|  | @ -92,33 +93,36 @@ wars.route('/') | ||||||
|                 return next(err); |                 return next(err); | ||||||
|               } |               } | ||||||
|               LogKillModel.create(statsResult.kills, function () { |               LogKillModel.create(statsResult.kills, function () { | ||||||
|                 LogRespawnModel.create(statsResult.respawn, function () { |                 LogVehicleKillModel.create(statsResult.vehicles, function () { | ||||||
|                   LogReviveModel.create(statsResult.revive, function () { |  | ||||||
|                     LogFlagModel.create(statsResult.flag, function () { |  | ||||||
|                       LogBudgetModel.create(statsResult.budget, function () { |  | ||||||
|                         LogTransportModel.create(statsResult.transport, function () { |  | ||||||
|                           LogPointsModel.create(statsResult.points, function () { |  | ||||||
|                             const folderName = __dirname + '/../resource/logs/' + war._id; |  | ||||||
|                             mkdirp(folderName, function (err) { |  | ||||||
|                               if (err) return next(err); |  | ||||||
| 
 | 
 | ||||||
|                               // save clean log file
 |                   LogRespawnModel.create(statsResult.respawn, function () { | ||||||
|                               const cleanFile = fs.createWriteStream(folderName + '/clean.log'); |                     LogReviveModel.create(statsResult.revive, function () { | ||||||
|                               statsResult.clean.forEach(cleanLine => { |                       LogFlagModel.create(statsResult.flag, function () { | ||||||
|                                 cleanFile.write(cleanLine + '\n\n') |                         LogBudgetModel.create(statsResult.budget, function () { | ||||||
|                               }); |                           LogTransportModel.create(statsResult.transport, function () { | ||||||
|                               cleanFile.end(); |                             LogPointsModel.create(statsResult.points, function () { | ||||||
|  |                               const folderName = __dirname + '/../resource/logs/' + war._id; | ||||||
|  |                               mkdirp(folderName, function (err) { | ||||||
|  |                                 if (err) return next(err); | ||||||
| 
 | 
 | ||||||
|                               // save raw log file
 |                                 // save clean log file
 | ||||||
|                               const rawFile = fs.createWriteStream(folderName + '/war.log'); |                                 const cleanFile = fs.createWriteStream(folderName + '/clean.log'); | ||||||
|                               lineArray.forEach(rawLine => { |                                 statsResult.clean.forEach(cleanLine => { | ||||||
|                                 rawFile.write(rawLine + '\n') |                                   cleanFile.write(cleanLine + '\n\n') | ||||||
|                               }); |                                 }); | ||||||
|                               rawFile.end(); |                                 cleanFile.end(); | ||||||
| 
 | 
 | ||||||
|                               res.status(codes.created); |                                 // save raw log file
 | ||||||
|                               res.locals.items = war; |                                 const rawFile = fs.createWriteStream(folderName + '/war.log'); | ||||||
|                               next(); |                                 lineArray.forEach(rawLine => { | ||||||
|  |                                   rawFile.write(rawLine + '\n') | ||||||
|  |                                 }); | ||||||
|  |                                 rawFile.end(); | ||||||
|  | 
 | ||||||
|  |                                 res.status(codes.created); | ||||||
|  |                                 res.locals.items = war; | ||||||
|  |                                 next(); | ||||||
|  |                               }) | ||||||
|                             }) |                             }) | ||||||
|                           }) |                           }) | ||||||
|                         }) |                         }) | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ const playerArrayContains = require('./util').playerArrayContains; | ||||||
| const WHITESPACE = ' '; | const WHITESPACE = ' '; | ||||||
| 
 | 
 | ||||||
| const parseWarLog = (lineArray, war) => { | const parseWarLog = (lineArray, war) => { | ||||||
|  | 
 | ||||||
|   const NAME_TOO_LONG_ERROR = 'Error: ENAMETOOLONG: name too long, open \''; |   const NAME_TOO_LONG_ERROR = 'Error: ENAMETOOLONG: name too long, open \''; | ||||||
| 
 | 
 | ||||||
|   const stats = { |   const stats = { | ||||||
|  | @ -13,6 +14,7 @@ const parseWarLog = (lineArray, war) => { | ||||||
|     budget: [], |     budget: [], | ||||||
|     points: [], |     points: [], | ||||||
|     kills: [], |     kills: [], | ||||||
|  |     vehicles: [], | ||||||
|     respawn: [], |     respawn: [], | ||||||
|     revive: [], |     revive: [], | ||||||
|     flag: [], |     flag: [], | ||||||
|  | @ -20,6 +22,8 @@ const parseWarLog = (lineArray, war) => { | ||||||
|     players: [] |     players: [] | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   const vehicleBlacklist = ['Prowler (Unbewaffnet)', 'Qilin (Unbewaffnet)', 'Quad Bike', 'HuntIR']; | ||||||
|  | 
 | ||||||
|   const addPlayerIfNotExists = (inputPlayer, steamUUID) => { |   const addPlayerIfNotExists = (inputPlayer, steamUUID) => { | ||||||
|     const player = getPlayerAndFractionFromString(inputPlayer); |     const player = getPlayerAndFractionFromString(inputPlayer); | ||||||
|     if (player && player.name && player.fraction && !playerArrayContains(stats.players, player)) { |     if (player && player.name && player.fraction && !playerArrayContains(stats.players, player)) { | ||||||
|  | @ -38,23 +42,38 @@ const parseWarLog = (lineArray, war) => { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * KILLS |      * KILLS & VEHICLE KILLS | ||||||
|      */ |      */ | ||||||
|     if (line.includes('(Abschuss)') && !line.includes('Fahrzeug')) { |     if (line.includes('(Abschuss)')) { | ||||||
|       stats.clean.push(line); |       stats.clean.push(line); | ||||||
|  | 
 | ||||||
|       const shooterString = line.substring(line.lastIndexOf(' von: ') + 6, line.lastIndexOf('."')); |       const shooterString = line.substring(line.lastIndexOf(' von: ') + 6, line.lastIndexOf('."')); | ||||||
|       const shooter = getPlayerAndFractionFromString(shooterString); |       const shooter = getPlayerAndFractionFromString(shooterString); | ||||||
|       const targetString = line.substring(line.lastIndexOf(' --- ') + 5, line.lastIndexOf(' von:')); |  | ||||||
|       const target = getPlayerAndFractionFromString(targetString); |  | ||||||
| 
 | 
 | ||||||
|       stats.kills.push({ |       if (line.includes('Fahrzeug:')) { | ||||||
|         war: war._id, |         const targetString = line.substring(line.lastIndexOf(' --- Fahrzeug: ') + 15, line.lastIndexOf(' von:')); | ||||||
|         time: getFullTimeDate(war.date, line.split(WHITESPACE)[5]), |         const target = getVehicleAndFractionFromString(targetString); | ||||||
|         shooter: shooter ? shooter.name : null, |         if (target && shooter && target.fraction !== shooter.fraction) { | ||||||
|         target: target ? target.name : null, |           stats.vehicles.push({ | ||||||
|         friendlyFire: shooter ? target.fraction === shooter.fraction : false, |             war: war._id, | ||||||
|         fraction: shooter ? shooter.fraction : 'NONE' |             time: getFullTimeDate(war.date, line.split(WHITESPACE)[5]), | ||||||
|       }); |             shooter: shooter ? shooter.name : null, | ||||||
|  |             target: target ? target.name : null, | ||||||
|  |             fraction: shooter ? shooter.fraction : 'NONE' | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         const targetString = line.substring(line.lastIndexOf(' --- ') + 5, line.lastIndexOf(' von:')); | ||||||
|  |         const target = getPlayerAndFractionFromString(targetString); | ||||||
|  |         stats.kills.push({ | ||||||
|  |           war: war._id, | ||||||
|  |           time: getFullTimeDate(war.date, line.split(WHITESPACE)[5]), | ||||||
|  |           shooter: shooter ? shooter.name : null, | ||||||
|  |           target: target ? target.name : null, | ||||||
|  |           friendlyFire: shooter ? target.fraction === shooter.fraction : false, | ||||||
|  |           fraction: shooter ? shooter.fraction : 'NONE' | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -181,6 +200,7 @@ const parseWarLog = (lineArray, war) => { | ||||||
|     const playerName = stats.players[i].name; |     const playerName = stats.players[i].name; | ||||||
|     stats.players[i]['respawn'] = stats.respawn.filter(res => res.player === playerName).length; |     stats.players[i]['respawn'] = stats.respawn.filter(res => res.player === playerName).length; | ||||||
|     stats.players[i]['kill'] = stats.kills.filter(kill => kill.shooter === playerName && !kill.friendlyFire).length; |     stats.players[i]['kill'] = stats.kills.filter(kill => kill.shooter === playerName && !kill.friendlyFire).length; | ||||||
|  |     stats.players[i]['vehicle'] = stats.vehicles.filter(vehicle => vehicle.shooter === playerName && vehicleBlacklist.indexOf(vehicle.target) < 0).length; | ||||||
|     stats.players[i]['friendlyFire'] = stats.kills.filter(kill => kill.shooter === playerName && kill.friendlyFire).length; |     stats.players[i]['friendlyFire'] = stats.kills.filter(kill => kill.shooter === playerName && kill.friendlyFire).length; | ||||||
|     stats.players[i]['death'] = stats.kills.filter(kill => kill.target === playerName).length; |     stats.players[i]['death'] = stats.kills.filter(kill => kill.target === playerName).length; | ||||||
|     stats.players[i]['revive'] = stats.revive.filter(rev => rev.medic === playerName && !rev.stabilized).length; |     stats.players[i]['revive'] = stats.revive.filter(rev => rev.medic === playerName && !rev.stabilized).length; | ||||||
|  | @ -233,6 +253,21 @@ const getPlayerAndFractionFromString = (nameAndFractionString) => { | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | const getVehicleAndFractionFromString = (nameAndFractionString) => { | ||||||
|  |   const nameArray = nameAndFractionString.trim().split(WHITESPACE); | ||||||
|  |   const fractionPart = nameArray[nameArray.length - 1]; | ||||||
|  | 
 | ||||||
|  |   // escape it is some parachute fraction identifier
 | ||||||
|  |   if (fractionPart === 'OPF_F' || fractionPart === 'BLU_F') { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   const fraction = fractionPart === '(OPT_NATO)' || fractionPart === '(OPT_NATO_T)' ? 'BLUFOR' : 'OPFOR'; | ||||||
|  |   const name = nameAndFractionString.substring(0, nameAndFractionString.indexOf(fractionPart) - 1); | ||||||
|  | 
 | ||||||
|  |   return {name: name, fraction: fraction}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| const transformMoneyString = (budgetString) => { | const transformMoneyString = (budgetString) => { | ||||||
|   if (!budgetString.includes('e+')) { |   if (!budgetString.includes('e+')) { | ||||||
|     return parseInt(budgetString); |     return parseInt(budgetString); | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ export interface Player { | ||||||
|   name?: string; |   name?: string; | ||||||
|   warId?: War; |   warId?: War; | ||||||
|   kill?: number; |   kill?: number; | ||||||
|  |   vehicle?: number; | ||||||
|   death?: number; |   death?: number; | ||||||
|   friendlyFire?: number; |   friendlyFire?: number; | ||||||
|   revive?: number; |   revive?: number; | ||||||
|  |  | ||||||
|  | @ -81,6 +81,26 @@ | ||||||
|       </ngx-charts-line-chart> |       </ngx-charts-line-chart> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|  |     <div class="chart-container"> | ||||||
|  |       <ngx-charts-line-chart | ||||||
|  |         [results]="vehicleKillData" | ||||||
|  |         [showRefLines]="showRefLines" | ||||||
|  |         [showRefLabels]="showRefLabels" | ||||||
|  |         [referenceLines]="killRefLines" | ||||||
|  |         [scheme]="colorScheme" | ||||||
|  |         [gradient]="gradient" | ||||||
|  |         [xAxis]="xAxis" | ||||||
|  |         [yAxis]="yAxis" | ||||||
|  |         [legend]="legend" | ||||||
|  |         [showXAxisLabel]="showXAxisLabel" | ||||||
|  |         [showYAxisLabel]="showYAxisLabel" | ||||||
|  |         [yAxisLabel]="yAxisVehicleKill" | ||||||
|  |         [autoScale]="autoscale" | ||||||
|  |         [timeline]="timeline" | ||||||
|  |         [roundDomains]="roundDomains"> | ||||||
|  |       </ngx-charts-line-chart> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|     <div class="chart-container"> |     <div class="chart-container"> | ||||||
|       <ngx-charts-line-chart |       <ngx-charts-line-chart | ||||||
|         [results]="deathData" |         [results]="deathData" | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ export class CampaignPlayerDetailComponent { | ||||||
|   sumData: any[] = []; |   sumData: any[] = []; | ||||||
|   killData: any[] = []; |   killData: any[] = []; | ||||||
|   friendlyFireData: any[] = []; |   friendlyFireData: any[] = []; | ||||||
|  |   vehicleKillData: any[] = []; | ||||||
|   deathData: any[] = []; |   deathData: any[] = []; | ||||||
|   respawnData: any[] = []; |   respawnData: any[] = []; | ||||||
|   reviveData: any[] = []; |   reviveData: any[] = []; | ||||||
|  | @ -32,6 +33,7 @@ export class CampaignPlayerDetailComponent { | ||||||
| 
 | 
 | ||||||
|   yAxisKill = 'Kills'; |   yAxisKill = 'Kills'; | ||||||
|   yAxisFriendlyFire = 'FriendlyFire'; |   yAxisFriendlyFire = 'FriendlyFire'; | ||||||
|  |   yAxisVehicleKill = 'Farzeug-Kills'; | ||||||
|   yAxisDeath = 'Tode'; |   yAxisDeath = 'Tode'; | ||||||
|   yAxisRespawn = 'Respawn'; |   yAxisRespawn = 'Respawn'; | ||||||
|   yAxisRevive = 'Revive'; |   yAxisRevive = 'Revive'; | ||||||
|  | @ -49,6 +51,7 @@ export class CampaignPlayerDetailComponent { | ||||||
|   showRefLines = true; |   showRefLines = true; | ||||||
|   showRefLabels = true; |   showRefLabels = true; | ||||||
|   killRefLines = []; |   killRefLines = []; | ||||||
|  |   vehicleKillRefLines = []; | ||||||
|   deathRefLines = []; |   deathRefLines = []; | ||||||
|   captureRefLines = []; |   captureRefLines = []; | ||||||
|   friendlyFireRefLines = []; |   friendlyFireRefLines = []; | ||||||
|  | @ -67,6 +70,7 @@ export class CampaignPlayerDetailComponent { | ||||||
| 
 | 
 | ||||||
|   totalKills; |   totalKills; | ||||||
|   totalFriendlyFire; |   totalFriendlyFire; | ||||||
|  |   totalVehicleKills; | ||||||
|   totalDeath; |   totalDeath; | ||||||
|   totalRespawn; |   totalRespawn; | ||||||
|   totalRevive; |   totalRevive; | ||||||
|  | @ -87,6 +91,7 @@ export class CampaignPlayerDetailComponent { | ||||||
|         .subscribe(campaignPlayer => { |         .subscribe(campaignPlayer => { | ||||||
|           this.campaignPlayer = campaignPlayer; |           this.campaignPlayer = campaignPlayer; | ||||||
|           this.killData = this.assignData(this.yAxisKill, "kill"); |           this.killData = this.assignData(this.yAxisKill, "kill"); | ||||||
|  |           this.vehicleKillData = this.assignData(this.yAxisVehicleKill, "vehicle"); | ||||||
|           this.friendlyFireData = this.assignData(this.yAxisFriendlyFire, "friendlyFire"); |           this.friendlyFireData = this.assignData(this.yAxisFriendlyFire, "friendlyFire"); | ||||||
|           this.deathData = this.assignData(this.yAxisDeath, "death"); |           this.deathData = this.assignData(this.yAxisDeath, "death"); | ||||||
|           this.respawnData = this.assignData(this.yAxisRespawn, "respawn"); |           this.respawnData = this.assignData(this.yAxisRespawn, "respawn"); | ||||||
|  | @ -107,6 +112,10 @@ export class CampaignPlayerDetailComponent { | ||||||
|               name: this.yAxisFriendlyFire, |               name: this.yAxisFriendlyFire, | ||||||
|               value: this.totalFriendlyFire |               value: this.totalFriendlyFire | ||||||
|             }, |             }, | ||||||
|  |             { | ||||||
|  |               name: this.yAxisVehicleKill, | ||||||
|  |               value: this.totalVehicleKills | ||||||
|  |             }, | ||||||
|             { |             { | ||||||
|               name: this.yAxisDeath, |               name: this.yAxisDeath, | ||||||
|               value: this.totalDeath |               value: this.totalDeath | ||||||
|  | @ -125,7 +134,7 @@ export class CampaignPlayerDetailComponent { | ||||||
|             } |             } | ||||||
|           ]; |           ]; | ||||||
| 
 | 
 | ||||||
|           Object.assign(this, [this.sumData, this.killData, this.friendlyFireData, this.deathData, this.respawnData, this.reviveData, this.captureData]); |           Object.assign(this, [this.sumData, this.killData, this.friendlyFireData, this.vehicleKillData, this.deathData, this.respawnData, this.reviveData, this.captureData]); | ||||||
|         }); |         }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -138,12 +147,12 @@ export class CampaignPlayerDetailComponent { | ||||||
|     let total = 0; |     let total = 0; | ||||||
|     for (let i = 0; i < playerLength; i++) { |     for (let i = 0; i < playerLength; i++) { | ||||||
|       const warDateString = ChartUtils.getShortDateString(this.campaignPlayer.players[i].warId.date); |       const warDateString = ChartUtils.getShortDateString(this.campaignPlayer.players[i].warId.date); | ||||||
|       const warKills = this.campaignPlayer.players[i][field]; |       const value = this.campaignPlayer.players[i][field]; | ||||||
|       killObj.series.push({ |       killObj.series.push({ | ||||||
|         name: warDateString, |         name: warDateString, | ||||||
|         value: warKills |         value: value | ||||||
|       }); |       }); | ||||||
|       total += warKills; |       total += value; | ||||||
|     } |     } | ||||||
|     switch (field) { |     switch (field) { | ||||||
|       case 'kill': |       case 'kill': | ||||||
|  | @ -154,6 +163,10 @@ export class CampaignPlayerDetailComponent { | ||||||
|         this.friendlyFireRefLines.push({value: total / playerLength, name: this.avgLabel}); |         this.friendlyFireRefLines.push({value: total / playerLength, name: this.avgLabel}); | ||||||
|         this.totalFriendlyFire = total; |         this.totalFriendlyFire = total; | ||||||
|         break; |         break; | ||||||
|  |       case 'vehicle': | ||||||
|  |         this.vehicleKillRefLines.push({value: total / playerLength, name: this.avgLabel}); | ||||||
|  |         this.totalVehicleKills = total; | ||||||
|  |         break; | ||||||
|       case 'death': |       case 'death': | ||||||
|         this.deathRefLines.push({value: total / playerLength, name: this.avgLabel}); |         this.deathRefLines.push({value: total / playerLength, name: this.avgLabel}); | ||||||
|         this.totalDeath = total; |         this.totalDeath = total; | ||||||
|  |  | ||||||
|  | @ -18,8 +18,6 @@ ngx-datatable { | ||||||
|   float: left; |   float: left; | ||||||
|   border: solid #dfdfdf 1px; |   border: solid #dfdfdf 1px; | ||||||
|   border-radius: 10px 10px 2px 2px; |   border-radius: 10px 10px 2px 2px; | ||||||
|   border-right-style: none; |  | ||||||
|   border-top-style: none; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| :host /deep/ .datatable-header { | :host /deep/ .datatable-header { | ||||||
|  |  | ||||||
|  | @ -36,6 +36,48 @@ | ||||||
|     <ngx-datatable-column [width]="valueColWidth" name="Kills" prop="kill"></ngx-datatable-column> |     <ngx-datatable-column [width]="valueColWidth" name="Kills" prop="kill"></ngx-datatable-column> | ||||||
|   </ngx-datatable> |   </ngx-datatable> | ||||||
| 
 | 
 | ||||||
|  |   <ngx-datatable | ||||||
|  |     [rows]="players.friendlyFire" | ||||||
|  |     [messages]="emptyMessage" | ||||||
|  |     [headerHeight]="cellHeight" | ||||||
|  |     [rowHeight]="cellHeight" | ||||||
|  |     [cssClasses]='customClasses' | ||||||
|  |     [columnMode]="'force'" | ||||||
|  |     [scrollbarV]="true" | ||||||
|  |     [selectionType]="'single'"> | ||||||
|  |     <ngx-datatable-column [width]="numberColWidth" name="#" prop="num"></ngx-datatable-column> | ||||||
|  |     <ngx-datatable-column name="Spieler" prop="name" [width]="nameColWidth" style="padding-left:10px"> | ||||||
|  |       <ng-template ngx-datatable-cell-template let-row="row" let-value="value"> | ||||||
|  |         <span class="player-name" | ||||||
|  |               [style.color]="row['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR"> | ||||||
|  |           {{value}} | ||||||
|  |         </span> | ||||||
|  |       </ng-template> | ||||||
|  |     </ngx-datatable-column> | ||||||
|  |     <ngx-datatable-column [width]="valueColWidth" name="FriendlyFire" prop="friendlyFire"></ngx-datatable-column> | ||||||
|  |   </ngx-datatable> | ||||||
|  | 
 | ||||||
|  |   <ngx-datatable | ||||||
|  |     [rows]="players.vehicle" | ||||||
|  |     [messages]="emptyMessage" | ||||||
|  |     [headerHeight]="cellHeight" | ||||||
|  |     [rowHeight]="cellHeight" | ||||||
|  |     [cssClasses]='customClasses' | ||||||
|  |     [columnMode]="'force'" | ||||||
|  |     [scrollbarV]="true" | ||||||
|  |     [selectionType]="'single'"> | ||||||
|  |     <ngx-datatable-column [width]="numberColWidth" name="#" prop="num"></ngx-datatable-column> | ||||||
|  |     <ngx-datatable-column name="Spieler" prop="name" [width]="nameColWidth" style="padding-left:10px"> | ||||||
|  |       <ng-template ngx-datatable-cell-template let-row="row" let-value="value"> | ||||||
|  |         <span class="player-name" | ||||||
|  |               [style.color]="row['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR"> | ||||||
|  |           {{value}} | ||||||
|  |         </span> | ||||||
|  |       </ng-template> | ||||||
|  |     </ngx-datatable-column> | ||||||
|  |     <ngx-datatable-column [width]="valueColWidth" name="Fahrzeug-Kills" prop="vehicle"></ngx-datatable-column> | ||||||
|  |   </ngx-datatable> | ||||||
|  | 
 | ||||||
|   <ngx-datatable |   <ngx-datatable | ||||||
|     [rows]="players.death" |     [rows]="players.death" | ||||||
|     [messages]="emptyMessage" |     [messages]="emptyMessage" | ||||||
|  | @ -78,27 +120,6 @@ | ||||||
|     <ngx-datatable-column [width]="valueColWidth" name="Respawn" prop="respawn"></ngx-datatable-column> |     <ngx-datatable-column [width]="valueColWidth" name="Respawn" prop="respawn"></ngx-datatable-column> | ||||||
|   </ngx-datatable> |   </ngx-datatable> | ||||||
| 
 | 
 | ||||||
|   <ngx-datatable |  | ||||||
|     [rows]="players.friendlyFire" |  | ||||||
|     [messages]="emptyMessage" |  | ||||||
|     [headerHeight]="cellHeight" |  | ||||||
|     [rowHeight]="cellHeight" |  | ||||||
|     [cssClasses]='customClasses' |  | ||||||
|     [columnMode]="'force'" |  | ||||||
|     [scrollbarV]="true" |  | ||||||
|     [selectionType]="'single'"> |  | ||||||
|     <ngx-datatable-column [width]="numberColWidth" name="#" prop="num"></ngx-datatable-column> |  | ||||||
|     <ngx-datatable-column name="Spieler" prop="name" [width]="nameColWidth" style="padding-left:10px"> |  | ||||||
|       <ng-template ngx-datatable-cell-template let-row="row" let-value="value"> |  | ||||||
|         <span class="player-name" |  | ||||||
|               [style.color]="row['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR"> |  | ||||||
|           {{value}} |  | ||||||
|         </span> |  | ||||||
|       </ng-template> |  | ||||||
|     </ngx-datatable-column> |  | ||||||
|     <ngx-datatable-column [width]="valueColWidth" name="FriendlyFire" prop="friendlyFire"></ngx-datatable-column> |  | ||||||
|   </ngx-datatable> |  | ||||||
| 
 |  | ||||||
|   <ngx-datatable |   <ngx-datatable | ||||||
|     [rows]="players.revive" |     [rows]="players.revive" | ||||||
|     [messages]="emptyMessage" |     [messages]="emptyMessage" | ||||||
|  |  | ||||||
|  | @ -86,6 +86,7 @@ export class StatisticHighScoreComponent { | ||||||
|       this.players = { |       this.players = { | ||||||
|         kill: this.filterPlayerAttribute('kill'), |         kill: this.filterPlayerAttribute('kill'), | ||||||
|         friendlyFire: this.filterPlayerAttribute('friendlyFire'), |         friendlyFire: this.filterPlayerAttribute('friendlyFire'), | ||||||
|  |         vehicle: this.filterPlayerAttribute('vehicle'), | ||||||
|         death: this.filterPlayerAttribute('death'), |         death: this.filterPlayerAttribute('death'), | ||||||
|         respawn: this.filterPlayerAttribute('respawn'), |         respawn: this.filterPlayerAttribute('respawn'), | ||||||
|         revive: this.filterPlayerAttribute('revive'), |         revive: this.filterPlayerAttribute('revive'), | ||||||
|  |  | ||||||
|  | @ -28,6 +28,8 @@ | ||||||
|              btnRadio="{{labelKill}}">{{labelKill}}</label> |              btnRadio="{{labelKill}}">{{labelKill}}</label> | ||||||
|       <label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel" |       <label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel" | ||||||
|              btnRadio="{{labelFriendlyFire}}">{{labelFriendlyFire}}</label> |              btnRadio="{{labelFriendlyFire}}">{{labelFriendlyFire}}</label> | ||||||
|  |       <label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel" | ||||||
|  |              btnRadio="{{labelVehicle}}">{{labelVehicle}}</label> | ||||||
|       <label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel" |       <label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel" | ||||||
|              btnRadio="{{labelRevive}}">{{labelRevive}}</label> |              btnRadio="{{labelRevive}}">{{labelRevive}}</label> | ||||||
|       <label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel" |       <label class="btn btn-default btn-dark" [(ngModel)]="chartSelectModel" | ||||||
|  |  | ||||||
|  | @ -34,6 +34,7 @@ export class FractionStatsComponent { | ||||||
|   tmpBudgetData; |   tmpBudgetData; | ||||||
|   tmpKillData; |   tmpKillData; | ||||||
|   tmpFrienlyFireData; |   tmpFrienlyFireData; | ||||||
|  |   tmpVehicleData; | ||||||
|   tmpTransportData; |   tmpTransportData; | ||||||
|   tmpReviveData; |   tmpReviveData; | ||||||
|   tmpStabilizeData; |   tmpStabilizeData; | ||||||
|  | @ -47,6 +48,7 @@ export class FractionStatsComponent { | ||||||
|   labelBudget = 'Budget'; |   labelBudget = 'Budget'; | ||||||
|   labelKill = 'Kills'; |   labelKill = 'Kills'; | ||||||
|   labelFriendlyFire = 'FriendlyFire'; |   labelFriendlyFire = 'FriendlyFire'; | ||||||
|  |   labelVehicle = 'Fahrzeug-Kills'; | ||||||
|   labelTransport = 'Lufttransport'; |   labelTransport = 'Lufttransport'; | ||||||
|   labelRevive = 'Revive'; |   labelRevive = 'Revive'; | ||||||
|   labelStabilize = 'Stabilisiert'; |   labelStabilize = 'Stabilisiert'; | ||||||
|  | @ -111,6 +113,10 @@ export class FractionStatsComponent { | ||||||
|           this.initKillData(); |           this.initKillData(); | ||||||
|           this.lineChartData = this.tmpFrienlyFireData; |           this.lineChartData = this.tmpFrienlyFireData; | ||||||
|           break; |           break; | ||||||
|  |         case this.labelVehicle: | ||||||
|  |           this.initVehicleData(); | ||||||
|  |           this.lineChartData = this.tmpVehicleData; | ||||||
|  |           break; | ||||||
|         case this.labelRevive: |         case this.labelRevive: | ||||||
|           this.initRevive(); |           this.initRevive(); | ||||||
|           this.lineChartData = this.tmpReviveData; |           this.lineChartData = this.tmpReviveData; | ||||||
|  | @ -250,6 +256,30 @@ export class FractionStatsComponent { | ||||||
|     this.initialized.revive = true; |     this.initialized.revive = true; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   initVehicleData() { | ||||||
|  |     if (this.initialized.vehicle) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     let vehicleKillCountBlufor = 0, vehicleKillCountOpfor = 0; | ||||||
|  |     for (const {transportEntry: vehicleEntry, index} of this.logData.vehicle.map((transportEntry, index) => ({ | ||||||
|  |       transportEntry, | ||||||
|  |       index | ||||||
|  |     }))) { | ||||||
|  |       const vehicleEntryDate = new Date(vehicleEntry.time); | ||||||
|  |       if (vehicleEntry.fraction === 'BLUFOR') { | ||||||
|  |         vehicleKillCountBlufor++; | ||||||
|  |       } else { | ||||||
|  |         vehicleKillCountOpfor++; | ||||||
|  |       } | ||||||
|  |       if (this.isTwoMinutesAhead(vehicleEntryDate, this.tmpVehicleData) || index === this.logData.vehicle.length - 1) { | ||||||
|  |         this.tmpVehicleData[0].series.push(ChartUtils.getSeriesEntry(vehicleEntryDate, vehicleKillCountBlufor)); | ||||||
|  |         this.tmpVehicleData[1].series.push(ChartUtils.getSeriesEntry(vehicleEntryDate, vehicleKillCountOpfor)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     this.addFinalTimeData(this.tmpVehicleData); | ||||||
|  |     this.initialized.vehicle = true; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   initTransportData() { |   initTransportData() { | ||||||
|     if (this.initialized.transport) { |     if (this.initialized.transport) { | ||||||
|       return; |       return; | ||||||
|  | @ -272,7 +302,6 @@ export class FractionStatsComponent { | ||||||
|     } |     } | ||||||
|     this.addFinalTimeData(this.tmpTransportData); |     this.addFinalTimeData(this.tmpTransportData); | ||||||
|     this.initialized.transport = true; |     this.initialized.transport = true; | ||||||
| 
 |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   initFlagHoldData() { |   initFlagHoldData() { | ||||||
|  | @ -308,12 +337,13 @@ export class FractionStatsComponent { | ||||||
|     this.tmpBudgetData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpBudgetData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|     this.tmpKillData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpKillData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|     this.tmpFrienlyFireData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpFrienlyFireData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|  |     this.tmpVehicleData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|     this.tmpTransportData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpTransportData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|     this.tmpReviveData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpReviveData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|     this.tmpStabilizeData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpStabilizeData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
|     this.tmpFlagCaptureData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); |     this.tmpFlagCaptureData = ChartUtils.getMultiDataArray(Fraction.BLUFOR, Fraction.OPFOR); | ||||||
| 
 | 
 | ||||||
|     [this.tmpKillData, this.tmpFrienlyFireData, this.tmpReviveData, this.tmpStabilizeData, this.tmpTransportData].forEach(tmp => { |     [this.tmpKillData, this.tmpFrienlyFireData, this.tmpVehicleData, this.tmpReviveData, this.tmpStabilizeData, this.tmpTransportData].forEach(tmp => { | ||||||
|       [0, 1].forEach(index => { |       [0, 1].forEach(index => { | ||||||
|         tmp[index].series.push(ChartUtils.getSeriesEntry(this.startDateObj, 0)); |         tmp[index].series.push(ChartUtils.getSeriesEntry(this.startDateObj, 0)); | ||||||
|       }) |       }) | ||||||
|  |  | ||||||
|  | @ -25,15 +25,16 @@ | ||||||
|     </ngx-datatable-column> |     </ngx-datatable-column> | ||||||
|     <ngx-datatable-column [width]="90" name="Kills" prop="kill"></ngx-datatable-column> |     <ngx-datatable-column [width]="90" name="Kills" prop="kill"></ngx-datatable-column> | ||||||
|     <ngx-datatable-column [width]="104" name="FriendlyFire" prop="friendlyFire"></ngx-datatable-column> |     <ngx-datatable-column [width]="104" name="FriendlyFire" prop="friendlyFire"></ngx-datatable-column> | ||||||
|  |     <ngx-datatable-column [width]="90" name="Fahrzeug" prop="vehicle"></ngx-datatable-column> | ||||||
|     <ngx-datatable-column [width]="80" name="Revive" prop="revive"></ngx-datatable-column> |     <ngx-datatable-column [width]="80" name="Revive" prop="revive"></ngx-datatable-column> | ||||||
|     <ngx-datatable-column [width]="100" name="Eroberung" prop="flagTouch"></ngx-datatable-column> |     <ngx-datatable-column [width]="100" name="Eroberung" prop="flagTouch"></ngx-datatable-column> | ||||||
|     <ngx-datatable-column [width]="70" name="Tod" prop="death"></ngx-datatable-column> |     <ngx-datatable-column [width]="70" name="Tod" prop="death"></ngx-datatable-column> | ||||||
|     <ngx-datatable-column [width]="90" name="Respawn" prop="respawn"></ngx-datatable-column> |     <ngx-datatable-column [width]="90" name="Respawn" prop="respawn"></ngx-datatable-column> | ||||||
|     <ngx-datatable-column [width]="80" name="" prop="name"> |     <!--<ngx-datatable-column [width]="80" name="" prop="name">--> | ||||||
|       <ng-template ngx-datatable-cell-template let-value="value"> |       <!--<ng-template ngx-datatable-cell-template let-value="value">--> | ||||||
|         <span class="btn btn-sm btn-default in-table-btn disabled">Detail</span> |         <!--<span class="btn btn-sm btn-default in-table-btn disabled">Detail</span>--> | ||||||
|       </ng-template> |       <!--</ng-template>--> | ||||||
|     </ngx-datatable-column> |     <!--</ngx-datatable-column>--> | ||||||
|     <ngx-datatable-column [width]="80" name="" prop="name"> |     <ngx-datatable-column [width]="80" name="" prop="name"> | ||||||
|       <ng-template ngx-datatable-cell-template let-value="value"> |       <ng-template ngx-datatable-cell-template let-value="value"> | ||||||
|         <span class="btn btn-sm btn-default in-table-btn" (click)="selectPlayerDetail(1, value)">Gesamt</span> |         <span class="btn btn-sm btn-default in-table-btn" (click)="selectPlayerDetail(1, value)">Gesamt</span> | ||||||
|  |  | ||||||
|  | @ -1,21 +1,3 @@ | ||||||
| .war-header { |  | ||||||
|   position: fixed; |  | ||||||
|   left: 35%; |  | ||||||
|   border-bottom: thin solid lightgrey; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @media only screen and (max-width: 1950px) { |  | ||||||
|   .war-header { |  | ||||||
|     left: 30%; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| @media only screen and (max-width: 1500px) { |  | ||||||
|   .war-header { |  | ||||||
|     left: 380px; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .war-header-container { | .war-header-container { | ||||||
|   width: 920px; |   width: 920px; | ||||||
|   min-height: 168px; |   min-height: 168px; | ||||||
|  | @ -28,6 +10,10 @@ | ||||||
|   margin-bottom: 10px; |   margin-bottom: 10px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .war-header { | ||||||
|  |   border-bottom: thin solid lightgrey; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .nav-tabs > li.active > a { | .nav-tabs > li.active > a { | ||||||
|   background: #222222; |   background: #222222; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue