Add war-log upload endpoint and processing
parent
2fa616570c
commit
84b19310b6
|
@ -11,5 +11,6 @@ module.exports = {
|
|||
squads: '/squads',
|
||||
users: '/users',
|
||||
account: '/account',
|
||||
request: '/request'
|
||||
request: '/request',
|
||||
wars: '/wars'
|
||||
};
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
"use strict";
|
||||
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const PlayerSchema = new Schema({
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
fraction: {
|
||||
type: String,
|
||||
enum: ['BLUFOR', 'OPFOR'],
|
||||
required: true
|
||||
},
|
||||
warId: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: 'War',
|
||||
required: true
|
||||
},
|
||||
kill: {
|
||||
type: Number,
|
||||
get: v => Math.round(v),
|
||||
set: v => Math.round(v),
|
||||
required: true
|
||||
},
|
||||
death: {
|
||||
type: Number,
|
||||
get: v => Math.round(v),
|
||||
set: v => Math.round(v),
|
||||
required: true
|
||||
},
|
||||
friendlyFire: {
|
||||
type: Number,
|
||||
get: v => Math.round(v),
|
||||
set: v => Math.round(v),
|
||||
required: true
|
||||
},
|
||||
respawn: {
|
||||
type: Number,
|
||||
get: v => Math.round(v),
|
||||
set: v => Math.round(v),
|
||||
required: true
|
||||
},
|
||||
flagTouch: {
|
||||
type: Number,
|
||||
get: v => Math.round(v),
|
||||
set: v => Math.round(v),
|
||||
default: 0
|
||||
}
|
||||
}, {
|
||||
collection: 'player',
|
||||
timestamps: {createdAt: 'timestamp'}
|
||||
});
|
||||
// optional more indices
|
||||
PlayerSchema.index({timestamp: 1});
|
||||
|
||||
module.exports = mongoose.model('Player', PlayerSchema);
|
|
@ -0,0 +1,35 @@
|
|||
"use strict";
|
||||
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const WarSchema = new Schema({
|
||||
date: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
ptBlufor: {
|
||||
type: Number,
|
||||
get: v => Math.round(v),
|
||||
set: v => Math.round(v),
|
||||
required: true
|
||||
},
|
||||
ptOpfor: {
|
||||
type: Number,
|
||||
get: v => Math.round(v),
|
||||
set: v => Math.round(v),
|
||||
required: true
|
||||
},
|
||||
bestPlayerId: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: 'Player',
|
||||
default: null
|
||||
}
|
||||
}, {
|
||||
collection: 'war',
|
||||
timestamps: {createdAt: 'timestamp'}
|
||||
});
|
||||
// optional more indices
|
||||
WarSchema.index({timestamp: 1});
|
||||
|
||||
module.exports = mongoose.model('War', WarSchema);
|
File diff suppressed because it is too large
Load Diff
|
@ -25,7 +25,8 @@
|
|||
"jimp": "^0.2.27",
|
||||
"jsonwebtoken": "^7.4.0",
|
||||
"lodash": "^4.17.4",
|
||||
"mongoose": "^4.3.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mongoose": "^4.11.1",
|
||||
"morgan": "~1.6.1",
|
||||
"multer": "^1.3.0",
|
||||
"node-sha1": "^1.0.1",
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
"use strict";
|
||||
|
||||
// modules
|
||||
const fs = require('fs');
|
||||
const mkdirp = require("mkdirp");
|
||||
const {exec} = require('child_process');
|
||||
const express = require('express');
|
||||
const multer = require('multer');
|
||||
const storage = multer.memoryStorage();
|
||||
const upload = multer({storage: storage});
|
||||
const logger = require('debug')('cc:squads');
|
||||
|
||||
// HTTP status codes by name
|
||||
const codes = require('./http-codes');
|
||||
|
||||
const apiAuthenticationMiddleware = require('../middleware/auth-middleware');
|
||||
// const checkMT = require('../middleware/permission-check').checkMT();
|
||||
const routerHandling = require('../middleware/router-handling');
|
||||
|
||||
// Mongoose Model using mongoDB
|
||||
const WarModel = require('../models/war');
|
||||
|
||||
const wars = express.Router();
|
||||
|
||||
// routes **********************
|
||||
wars.route('/')
|
||||
// .get((req, res, next) => {
|
||||
// const filter = {};
|
||||
// WarModel.find(filter, {}, {sort: {date: 'asc'}}, (err, items) => {
|
||||
// if (err) {
|
||||
// err.status = codes.servererror;
|
||||
// return next(err);
|
||||
// }
|
||||
// if (items) {
|
||||
// res.locals.items = items;
|
||||
// } else {
|
||||
// res.locals.items = [];
|
||||
// }
|
||||
// res.locals.processed = true;
|
||||
// next();
|
||||
// });
|
||||
// })
|
||||
|
||||
.post(upload.single('log'), (req, res, next) => {
|
||||
const war = new WarModel(req.body);
|
||||
// timestamp and default are set automatically by Mongoose Schema Validation
|
||||
if (req.file) {
|
||||
const timestamp = new Date();
|
||||
const uploadDate = timestamp.toISOString().slice(0, 10) + '_' + timestamp.toTimeString().slice(0, 8)
|
||||
const folderName = __dirname + '/../resource/logs/' + uploadDate;
|
||||
mkdirp(folderName, function (err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
fs.appendFile(folderName + '/war.log', new Buffer(req.file.buffer), (err) => {
|
||||
if (err) {
|
||||
next(err);
|
||||
}
|
||||
exec(__dirname + '/../war-parser/run.sh ' + folderName + ' | tee resource/logs/' + uploadDate + '/score.log' , (error, stdout, stderr) => {
|
||||
console.log("log")
|
||||
if (error) {
|
||||
return next(error);
|
||||
}
|
||||
console.log(`stdout: ${stdout}`);
|
||||
console.log(`stderr: ${stderr}`);
|
||||
res.locals.items={};
|
||||
return next();
|
||||
});
|
||||
|
||||
// exec(__dirname + '/../war-parser/clean.sh ' + folderName + ' | tee resource/logs/' + uploadDate + '/clean.log' , (error) => {
|
||||
// if (error) {
|
||||
// return next(error);
|
||||
// }
|
||||
//
|
||||
// });
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
// war.save((err) => {
|
||||
// if (err) {
|
||||
// err.status = codes.wrongrequest;
|
||||
// err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors);
|
||||
// return next(err);
|
||||
// }
|
||||
// res.status(codes.created);
|
||||
// res.locals.items = war;
|
||||
// fs.appendFile(__dirname + '/../resource/squad/' + war.id + '.png', new Buffer(req.file.buffer), (err) => {
|
||||
// if (err) next(err);
|
||||
// });
|
||||
// next();
|
||||
// })
|
||||
} else {
|
||||
const err = new Error('no Logfile provided');
|
||||
err.status = codes.wrongmediasend;
|
||||
next(err);
|
||||
}
|
||||
})
|
||||
|
||||
.all(
|
||||
routerHandling.httpMethodNotAllowed
|
||||
);
|
||||
//
|
||||
// wars.route('/:id')
|
||||
// .get((req, res, next) => {
|
||||
// WarModel.findById(req.params.id, (err, item) => {
|
||||
// if (err) {
|
||||
// err.status = codes.servererror;
|
||||
// return next(err);
|
||||
// }
|
||||
// else if (!item) {
|
||||
// err = new Error("item not found");
|
||||
// err.status = codes.notfound;
|
||||
// return next(err);
|
||||
// }
|
||||
// res.locals.items = item;
|
||||
// next();
|
||||
// });
|
||||
// })
|
||||
//
|
||||
// .delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
|
||||
// WarModel.findByIdAndRemove(req.params.id, (err, item) => {
|
||||
// if (err) {
|
||||
// err.status = codes.wrongrequest;
|
||||
// }
|
||||
// else if (!item) {
|
||||
// err = new Error("item not found");
|
||||
// err.status = codes.notfound;
|
||||
// }
|
||||
//
|
||||
// // delete graphic
|
||||
// fs.unlink(__dirname + '/../resource/squad/' + req.params.id + '.png', (err) => {
|
||||
// if (err) next(err);
|
||||
// });
|
||||
//
|
||||
// // we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler user.use(..)
|
||||
// res.locals.processed = true;
|
||||
// next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
||||
// });
|
||||
// })
|
||||
//
|
||||
// .all(
|
||||
// routerHandling.httpMethodNotAllowed
|
||||
// );
|
||||
|
||||
// this middleware function can be used, if you like or remove it
|
||||
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
||||
wars.use(routerHandling.emptyResponse);
|
||||
|
||||
module.exports = wars;
|
|
@ -31,6 +31,7 @@ const awardingRouter = require('./routes/awardings');
|
|||
const requestRouter = require('./routes/request');
|
||||
const signatureRouter = require('./routes/signatures');
|
||||
const commandRouter = require('./routes/command');
|
||||
const warRouter = require('./routes/war');
|
||||
|
||||
// Configuration ***********************************
|
||||
// mongoose promise setup
|
||||
|
@ -75,6 +76,7 @@ app.use(urls.ranks, rankRouter);
|
|||
app.use(urls.decorations, decorationRouter);
|
||||
app.use(urls.request, requestRouter);
|
||||
app.use(urls.awards, awardingRouter);
|
||||
app.use(urls.wars, warRouter);
|
||||
app.use(urls.command, apiAuthenticationMiddleware, checkAdmin, commandRouter);
|
||||
app.use(urls.account, apiAuthenticationMiddleware, checkAdmin, accountRouter);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"use strict"
|
||||
"use strict";
|
||||
|
||||
// modules used for graphic manipulation
|
||||
const jimp = require('jimp');
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
FILE="$1"
|
||||
FILTER=("Budget" "Mission" "Abschuss" "Respawn" "Punkte")
|
||||
FILE="$1/war.log"
|
||||
|
||||
pat=$(echo ${FILTER[@]}|tr " " "|")
|
||||
|
||||
|
||||
while IFS= read -r line; do
|
||||
if [[ $line =~ [^[:space:]] ]]; then
|
||||
RES="$(grep -Ew "$pat" <<< "$line")"
|
||||
if [[ ${RES} =~ [^[:space:]] ]]; then
|
||||
echo ${RES}
|
||||
while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||
case "$line" in
|
||||
*"Budget"* | *"Mission"* | *"Abschuss"* | *"Respawn"* | *"Punkte"*)
|
||||
echo $line;
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
done < <(cat ${FILE} )
|
||||
;;
|
||||
esac
|
||||
done < ${FILE}
|
||||
|
||||
# Add OPT Scoreboard
|
||||
while IFS= read -r line; do
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
createScoreboardHeader() {
|
||||
printf "%25s %8s %8s %8s %8s %8s\n" "Name" "Kill" "FF" "Death" "Respawn"
|
||||
echo "---------------------------------------------------------------------------"
|
||||
}
|
||||
|
||||
createScoreboard() {
|
||||
NAME="$1"
|
||||
FILE="$2"
|
||||
|
@ -34,14 +29,16 @@ createScoreboard() {
|
|||
esac
|
||||
done < <(grep -- "${ESC_NAME}" ${FILE})
|
||||
|
||||
#echo {\"name\":\"$NAME\", \"kill\":${KILL}, \"ff\":${FF}, \"death\":${DEATH}, \"respawn\":${RESPAWN}},
|
||||
if [[ $NAME =~ [^[:space:]] ]]; then
|
||||
printf "%25s %8s %8s %8s %8s %8s\n" "$NAME" $KILL $FF $DEATH $RESPAWN
|
||||
printf "\t{\"name\":\"$NAME\", \"kill\":${KILL}, \"ff\":${FF}, \"death\":${DEATH}, \"respawn\":${RESPAWN}}"
|
||||
if [[ -z ${3} ]]; then
|
||||
printf ",\n"
|
||||
else
|
||||
printf "\n"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
FILE="$1"
|
||||
FILE="$1/war.log"
|
||||
PLAYERS=()
|
||||
|
||||
while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||
|
@ -68,10 +65,13 @@ while IFS='' read -r line || [[ -n "$line" ]]; do
|
|||
fi
|
||||
done < ${FILE}
|
||||
|
||||
createScoreboardHeader
|
||||
echo "["
|
||||
|
||||
for i in "${PLAYERS[@]}"
|
||||
for ((i=0; i<${#PLAYERS[*]}; i++));
|
||||
do
|
||||
:
|
||||
createScoreboard "$i" ${FILE}
|
||||
if [[ "$((i+1))" -eq "${#PLAYERS[*]}" ]]; then
|
||||
last="true"
|
||||
fi
|
||||
createScoreboard "${PLAYERS[i]}" ${FILE} ${last}
|
||||
done
|
||||
echo "]"
|
||||
|
|
Loading…
Reference in New Issue