Fix first line parse error; Add file save; Add player sum-point-value
parent
fb5e5388f7
commit
75019a619f
|
@ -53,6 +53,11 @@ const PlayerSchema = new Schema({
|
||||||
get: v => Math.round(v),
|
get: v => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: v => Math.round(v),
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
sort: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v)
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
collection: 'player',
|
collection: 'player',
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
// modules
|
// modules
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const mkdirp = require("mkdirp");
|
const mkdirp = require("mkdirp");
|
||||||
const {exec} = require('child_process');
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const multer = require('multer');
|
const multer = require('multer');
|
||||||
const storage = multer.memoryStorage();
|
const storage = multer.memoryStorage();
|
||||||
|
@ -88,16 +87,35 @@ wars.route('/')
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
LogKillModel.create(statsResult.kills, function (err) {
|
LogKillModel.create(statsResult.kills, function () {
|
||||||
LogRespawnModel.create(statsResult.respawn, function (err) {
|
LogRespawnModel.create(statsResult.respawn, function () {
|
||||||
LogReviveModel.create(statsResult.revive, function (err) {
|
LogReviveModel.create(statsResult.revive, function () {
|
||||||
LogFlagModel.create(statsResult.flag, function (err) {
|
LogFlagModel.create(statsResult.flag, function () {
|
||||||
LogBudgetModel.create(statsResult.budget, function (err) {
|
LogBudgetModel.create(statsResult.budget, function () {
|
||||||
LogTransportModel.create(statsResult.transport, function (err) {
|
LogTransportModel.create(statsResult.transport, function () {
|
||||||
LogPointsModel.create(statsResult.points, function (err) {
|
LogPointsModel.create(statsResult.points, function () {
|
||||||
res.status(codes.created);
|
const folderName = __dirname + '/../resource/logs/' + war._id;
|
||||||
res.locals.items = war;
|
mkdirp(folderName, function (err) {
|
||||||
next();
|
if (err) return next(err);
|
||||||
|
|
||||||
|
// save clean log file
|
||||||
|
const cleanFile = fs.createWriteStream(folderName + '/clean.log');
|
||||||
|
statsResult.clean.forEach(cleanLine => {
|
||||||
|
cleanFile.write(cleanLine + '\n\n')
|
||||||
|
});
|
||||||
|
cleanFile.end();
|
||||||
|
|
||||||
|
// save raw log file
|
||||||
|
const rawFile = fs.createWriteStream(folderName + '/war.log');
|
||||||
|
lineArray.forEach(rawLine => {
|
||||||
|
rawFile.write(rawLine + '\n')
|
||||||
|
});
|
||||||
|
rawFile.end();
|
||||||
|
|
||||||
|
res.status(codes.created);
|
||||||
|
res.locals.items = war;
|
||||||
|
next();
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -105,7 +123,7 @@ wars.route('/')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -132,7 +150,7 @@ wars.route('/:id')
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
PlayerModel.find({warId: item._id}, {}, {sort: {kill: 'desc'}}, (err, items) => {
|
PlayerModel.find({warId: item._id}, {}, {sort: {sort: 'desc'}}, (err, items) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
const arrayContains = require('./util').arrayContains;
|
const arrayContains = require('./util').arrayContains;
|
||||||
|
|
||||||
const parseWarLog = (lineArray, war) => {
|
const parseWarLog = (lineArray, war) => {
|
||||||
|
const nameToLongError = 'Error: ENAMETOOLONG: name too long, open \'';
|
||||||
const stats = {
|
const stats = {
|
||||||
war: war,
|
war: war,
|
||||||
clean: [],
|
clean: [],
|
||||||
|
@ -25,7 +26,14 @@ const parseWarLog = (lineArray, war) => {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
lineArray.forEach(line => {
|
lineArray.some(line => {
|
||||||
|
/**
|
||||||
|
* sanitize nameToLongError coming up in first line
|
||||||
|
*/
|
||||||
|
if (line.includes(nameToLongError)) {
|
||||||
|
line = line.substring(line.indexOf(nameToLongError) + nameToLongError.length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KILLS
|
* KILLS
|
||||||
*/
|
*/
|
||||||
|
@ -94,6 +102,7 @@ const parseWarLog = (lineArray, war) => {
|
||||||
if (line.includes('Endpunktestand')) {
|
if (line.includes('Endpunktestand')) {
|
||||||
stats.war['ptBlufor'] = parseInt(pt[11]);
|
stats.war['ptBlufor'] = parseInt(pt[11]);
|
||||||
stats.war['ptOpfor'] = parseInt(pt[14].slice(0, -1));
|
stats.war['ptOpfor'] = parseInt(pt[14].slice(0, -1));
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
stats.points.push(getPointsEntry(pt, line, war._id))
|
stats.points.push(getPointsEntry(pt, line, war._id))
|
||||||
}
|
}
|
||||||
|
@ -148,7 +157,7 @@ const parseWarLog = (lineArray, war) => {
|
||||||
war: war._id,
|
war: war._id,
|
||||||
time: getDateTime(line.split(' ')[5]),
|
time: getDateTime(line.split(' ')[5]),
|
||||||
driver: driver.name,
|
driver: driver.name,
|
||||||
passenger: passenger.name,
|
passenger: passenger ? passenger.name : null,
|
||||||
fraction: driver.fraction,
|
fraction: driver.fraction,
|
||||||
distance: distance
|
distance: distance
|
||||||
});
|
});
|
||||||
|
@ -165,6 +174,8 @@ const parseWarLog = (lineArray, war) => {
|
||||||
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;
|
||||||
stats.players[i]['flagTouch'] = stats.flag.filter(flag => flag.player === playerName).length;
|
stats.players[i]['flagTouch'] = stats.flag.filter(flag => flag.player === playerName).length;
|
||||||
|
stats.players[i]['sort'] = stats.players[i]['kill'] + stats.players[i]['revive'] + stats.players[i]['flagTouch']
|
||||||
|
- stats.players[i]['friendlyFire'] - stats.players[i]['death'] - stats.players[i]['respawn']
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.war.playersBlufor = stats.players.filter(player => player.fraction === 'BLUFOR').length;
|
stats.war.playersBlufor = stats.players.filter(player => player.fraction === 'BLUFOR').length;
|
||||||
|
@ -187,7 +198,7 @@ const getPointsEntry = (pt, line, warId) => {
|
||||||
time: getDateTime(pt[5]),
|
time: getDateTime(pt[5]),
|
||||||
ptBlufor: parseInt(pt[12]),
|
ptBlufor: parseInt(pt[12]),
|
||||||
ptOpfor: parseInt(pt[15].slice(0, -1)),
|
ptOpfor: parseInt(pt[15].slice(0, -1)),
|
||||||
fraction: line.includes('no Domination') ? 'NONE': line.includes('NATO +1') ? 'BLUFOR' : 'OPFOR'
|
fraction: line.includes('no Domination') ? 'NONE' : line.includes('NATO +1') ? 'BLUFOR' : 'OPFOR'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
FILE="$1/war.log"
|
|
||||||
|
|
||||||
while IFS='' read -r line || [[ -n "$line" ]]; do
|
|
||||||
case "$line" in
|
|
||||||
*"Budget"* | *"Mission"* | *"Abschuss"* | *"Respawn"* | *"Punkte"* | *"Flagge"* | *"Revive"* | *"Transport"*)
|
|
||||||
echo $line;
|
|
||||||
echo ""
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done < ${FILE}
|
|
||||||
|
|
||||||
# Add OPT Scoreboard
|
|
||||||
while IFS= read -r line; do
|
|
||||||
if [[ $line =~ [^[:space:]] ]]; then
|
|
||||||
echo "$line"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
done < <(grep -A 100 Scoreboard ${FILE} )
|
|
|
@ -1,97 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
createScoreboard() {
|
|
||||||
NAME="$1"
|
|
||||||
FILE="$2"
|
|
||||||
WAR_ID="$3"
|
|
||||||
|
|
||||||
KILL=0
|
|
||||||
FF=0
|
|
||||||
REVIVE=0
|
|
||||||
DEATH=0
|
|
||||||
RESPAWN=0
|
|
||||||
FLAG=0
|
|
||||||
FRACTION=
|
|
||||||
|
|
||||||
#escape '[' -> somehow escapes all special chars, hah?
|
|
||||||
ESC_NAME=$(echo "$NAME" | sed -r 's/[\[]+/\\[/g')
|
|
||||||
|
|
||||||
while IFS= read -r line; do
|
|
||||||
case "$line" in
|
|
||||||
*\(WEST\)[" "]von:[" "]${ESC_NAME}[" "]\(EAST\)* | *\(EAST\)[" "]von:[" "]${ESC_NAME}[" "]\(WEST\)*)
|
|
||||||
((KILL++))
|
|
||||||
;;
|
|
||||||
*\(EAST\)[" "]von:[" "]${ESC_NAME}[" "]\(EAST\)* | *\(WEST\)[" "]von:[" "]${ESC_NAME}[" "]\(WEST\)*)
|
|
||||||
((FF++))
|
|
||||||
;;
|
|
||||||
*\(EAST\)[" "]wurde[" "]von[" "]${ESC_NAME}[" "]\(EAST\)[" "]wiederbelebt* | *\(WEST\)[" "]wurde[" "]von[" "]${ESC_NAME}[" "]\(WEST\)[" "]wiederbelebt*)
|
|
||||||
((REVIVE++))
|
|
||||||
;;
|
|
||||||
*${ESC_NAME}[" "]*von:*)
|
|
||||||
((DEATH++))
|
|
||||||
;;
|
|
||||||
*Flagge[" "]erobert[" "]von[" "]${ESC_NAME}* | *Flagge[" "]gesichert[" "]von[" "]${ESC_NAME}*)
|
|
||||||
((FLAG++))
|
|
||||||
;;
|
|
||||||
*Spieler:*${ESC_NAME}*)
|
|
||||||
((RESPAWN++))
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [[ -z ${FRACTION} && ( "$line" == *${ESC_NAME}[" "]\(WEST\)* || "$line" == *${ESC_NAME}[" "]\(NATO\)* ) ]]; then
|
|
||||||
FRACTION="BLUFOR"
|
|
||||||
fi
|
|
||||||
if [[ -z ${FRACTION} && ( "$line" == *${ESC_NAME}[" "]\(EAST\)* || "$line" == *${ESC_NAME}[" "]\(CSAT\)* ) ]]; then
|
|
||||||
FRACTION="OPFOR"
|
|
||||||
fi
|
|
||||||
done < <(grep -- "${ESC_NAME}" ${FILE})
|
|
||||||
|
|
||||||
printf "\t{\"name\":\"$NAME\", \"fraction\":\"$FRACTION\", \"kill\":${KILL}, \"friendlyFire\":${FF}, \"revive\":${REVIVE}, \"death\":${DEATH}, \"respawn\":${RESPAWN}, \"flagTouch\":${FLAG}, \"warId\":\"${WAR_ID}\"} "
|
|
||||||
if [[ -z ${4} ]]; then
|
|
||||||
printf ",\n"
|
|
||||||
else
|
|
||||||
printf "\n"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FILE="$1/war.log"
|
|
||||||
WAR_ID="$2"
|
|
||||||
PLAYERS=()
|
|
||||||
|
|
||||||
while IFS='' read -r line || [[ -n "$line" ]]; do
|
|
||||||
if [[ -n $line ]]; then
|
|
||||||
case "$line" in
|
|
||||||
*"TFAR_RadioRequestEvent"*)
|
|
||||||
RES=$(echo "$(grep -oP ':[0-9]+\s\(\K.*?(?=\)\sREMOTE)' <<< "$line")")
|
|
||||||
;;
|
|
||||||
*"Respawn"*)
|
|
||||||
RES=$(echo "$(grep -oP '\|\|\sSpieler:\s\K.*?(?=\s-\sKosten:)' <<< "$line")")
|
|
||||||
;;
|
|
||||||
*"Abschuss"*)
|
|
||||||
RES=$(echo "$(grep -oP '\|\|\s\K.*?(?=\s\((EAST|WEST|CIV))' <<< "$line")")
|
|
||||||
RES1=$(echo "$(grep -oP 'von:\s\K.*?(?=\s\((EAST|WEST|CIV))' <<< "$line")")
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [[ $RES != *"Error: No unit"* && $RES1 != *"Error: No unit"* ]]; then
|
|
||||||
if [[ -n $RES && " ${PLAYERS[*]} " != *" $RES "* ]]; then
|
|
||||||
PLAYERS+=("$RES")
|
|
||||||
fi
|
|
||||||
if [[ -n $RES1 && " ${PLAYERS[*]} " != *" $RES1 "* ]]; then
|
|
||||||
PLAYERS+=("$RES1")
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done < ${FILE}
|
|
||||||
|
|
||||||
echo "["
|
|
||||||
|
|
||||||
for ((i=0; i<${#PLAYERS[*]}; i++));
|
|
||||||
do
|
|
||||||
if [[ "$((i+1))" -eq "${#PLAYERS[*]}" ]]; then
|
|
||||||
last="true"
|
|
||||||
fi
|
|
||||||
createScoreboard "${PLAYERS[i]}" ${FILE} ${WAR_ID} ${last}
|
|
||||||
done
|
|
||||||
echo "]"
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div #overview class="overview fade-in" xmlns="http://www.w3.org/1999/html">
|
<div #overview class="overview fade-in" xmlns="http://www.w3.org/1999/html">
|
||||||
<div class=vertical-spacer>
|
<div class=vertical-spacer>
|
||||||
</div>
|
</div>
|
||||||
<div style="overflow:hidden">
|
<div style="overflow:hidden">
|
||||||
<div style="width: 920px;min-height: 263px;">
|
<div style="width: 920px;min-height: 263px;">
|
||||||
<h2>{{war.title}} - vom {{war.date | date: 'dd.MM.yyyy'}}</h2>
|
<h2>{{war.title}} - vom {{war.date | date: 'dd.MM.yyyy'}}</h2>
|
||||||
<h3 class="pull-left" style="width: 250px">
|
<h3 class="pull-left" style="width: 250px">
|
||||||
|
@ -52,10 +52,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!--may be added in future: [sorts]="[{prop: 'sort', dir: 'desc'}]"-->
|
||||||
<ngx-datatable
|
<ngx-datatable
|
||||||
[rows]="rows"
|
[rows]="rows"
|
||||||
[reorderable]="reorderable"
|
[reorderable]="reorderable"
|
||||||
[sorts]="[{prop: 'kill', dir: 'desc'}]"
|
|
||||||
[messages]="{emptyMessage: 'Loading...'}"
|
[messages]="{emptyMessage: 'Loading...'}"
|
||||||
[headerHeight]="cellHeight"
|
[headerHeight]="cellHeight"
|
||||||
[rowHeight]="cellHeight"
|
[rowHeight]="cellHeight"
|
||||||
|
@ -82,6 +82,7 @@
|
||||||
<ngx-datatable-column [width]="100" name="Tod" prop="death"></ngx-datatable-column>
|
<ngx-datatable-column [width]="100" name="Tod" prop="death"></ngx-datatable-column>
|
||||||
<ngx-datatable-column [width]="100" name="Respawn" prop="respawn"></ngx-datatable-column>
|
<ngx-datatable-column [width]="100" name="Respawn" prop="respawn"></ngx-datatable-column>
|
||||||
</ngx-datatable>
|
</ngx-datatable>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue