add player weapon route
This commit is contained in:
Vendored
+2
-2
@@ -9,7 +9,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "Launch Server API",
|
"name": "Launch Server API",
|
||||||
"skipFiles": ["<node_internals>/**"],
|
"skipFiles": ["<node_internals>/**"],
|
||||||
"program": "${workspaceFolder}/src/server.ts",
|
"program": "${workspaceFolder}/src/serverMain.ts",
|
||||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||||
"outFiles": ["${workspaceFolder}/out/**/*.js"]
|
"outFiles": ["${workspaceFolder}/out/**/*.js"]
|
||||||
},
|
},
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "Launch Client API",
|
"name": "Launch Client API",
|
||||||
"skipFiles": ["<node_internals>/**"],
|
"skipFiles": ["<node_internals>/**"],
|
||||||
"program": "${workspaceFolder}/src/client.ts",
|
"program": "${workspaceFolder}/src/clientMain.ts",
|
||||||
"preLaunchTask": "tsc: build - tsconfig.json",
|
"preLaunchTask": "tsc: build - tsconfig.json",
|
||||||
"outFiles": ["${workspaceFolder}/out/**/*.js"]
|
"outFiles": ["${workspaceFolder}/out/**/*.js"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Router } from 'express'
|
import { Router } from 'express'
|
||||||
import weapons from './weapons'
|
import weapons from './weapons'
|
||||||
|
import player from './player'
|
||||||
const router = Router()
|
const router = Router()
|
||||||
//timeout middleware ?
|
//timeout middleware ?
|
||||||
router.get('/*', (req, res, next) => {
|
router.get('/*', (req, res, next) => {
|
||||||
@@ -16,7 +17,7 @@ router.get('/players/:playerId', (req, res, next) => {})
|
|||||||
router.get('/servers/', (req, res, next) => {})
|
router.get('/servers/', (req, res, next) => {})
|
||||||
router.get('/servers/:serverId/', (req, res, next) => {})
|
router.get('/servers/:serverId/', (req, res, next) => {})
|
||||||
router.get('/servers/:serverId/players', (req, res, next) => {})
|
router.get('/servers/:serverId/players', (req, res, next) => {})
|
||||||
router.get('/servers/:serverId/players/:playerId', (req, res, next) => {})
|
router.get('/servers/:serverId/player/:playerId', player)
|
||||||
|
|
||||||
router.use('/', weapons)
|
router.use('/servers/:serverId/weapons', weapons)
|
||||||
export default router
|
export default router
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import { RequestHandler } from 'express'
|
||||||
|
import { param } from 'express-validator'
|
||||||
|
import { validateErrors } from '../common'
|
||||||
|
import cache from '../cache/redis'
|
||||||
|
import { sql } from 'kysely'
|
||||||
|
import db from '../db/db'
|
||||||
|
|
||||||
|
const { count, max } = db.fn
|
||||||
|
|
||||||
|
const middlewares: RequestHandler[] = [
|
||||||
|
param(['serverId', 'playerId']).exists().toInt().isInt(),
|
||||||
|
validateErrors,
|
||||||
|
async (req, res) => {
|
||||||
|
const server = Number(req.params.serverId)
|
||||||
|
const player = Number(req.params.playerId)
|
||||||
|
await processPlayerWeapons(server, player)
|
||||||
|
const killsData = await cache.HGETALL(
|
||||||
|
`servers:${server}:players:${player}:weapons:kills`
|
||||||
|
)
|
||||||
|
const deathData = await cache.HGETALL(
|
||||||
|
`servers:${server}:players:${player}:weapons:deaths`
|
||||||
|
)
|
||||||
|
const data: { [x: string]: { kills: string; deaths: string } } = {}
|
||||||
|
Object.keys(killsData).forEach((key) => {
|
||||||
|
data[key] = { kills: killsData[key], deaths: deathData[key] }
|
||||||
|
})
|
||||||
|
|
||||||
|
res.status(200).send(data)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
async function processPlayerWeapons(server: number, player: number) {
|
||||||
|
let last_entry =
|
||||||
|
Number(
|
||||||
|
await cache.HGET(
|
||||||
|
`servers:${server}:players:${player}:weapons`,
|
||||||
|
'last_entry'
|
||||||
|
)
|
||||||
|
) || 0
|
||||||
|
const newData = await db
|
||||||
|
.with('killdata', () =>
|
||||||
|
db
|
||||||
|
.selectFrom('kill')
|
||||||
|
.select([count('kill.id').as('num_kills'), 'kill.cause_of_death'])
|
||||||
|
.where('attacker_id', '=', player.toString())
|
||||||
|
.where('kill.id', '>', last_entry)
|
||||||
|
.where('kill.server', '=', server)
|
||||||
|
.whereRef('attacker_id', '!=', 'victim_id')
|
||||||
|
.groupBy('cause_of_death')
|
||||||
|
)
|
||||||
|
.with('deathdata', () =>
|
||||||
|
db
|
||||||
|
.selectFrom('kill')
|
||||||
|
.select([count('kill.id').as('num_deaths'), 'kill.cause_of_death'])
|
||||||
|
.where('victim_id', '=', player.toString())
|
||||||
|
.where('kill.id', '>', last_entry)
|
||||||
|
.where('kill.server', '=', server)
|
||||||
|
.groupBy('cause_of_death')
|
||||||
|
)
|
||||||
|
.selectFrom('killdata')
|
||||||
|
.select([
|
||||||
|
sql<number>`coalesce(killdata.num_kills, 0)`.as('kills'),
|
||||||
|
sql<number>`coalesce(deathdata.num_deaths, 0)`.as('deaths'),
|
||||||
|
sql<string>`COALESCE(killdata.cause_of_death, deathdata.cause_of_death)`.as(
|
||||||
|
'weapon'
|
||||||
|
),
|
||||||
|
db
|
||||||
|
.selectFrom('kill')
|
||||||
|
.select(max('kill.id').as('last_entry'))
|
||||||
|
.as('last_entry')
|
||||||
|
])
|
||||||
|
.fullJoin(
|
||||||
|
'deathdata',
|
||||||
|
'deathdata.cause_of_death',
|
||||||
|
'killdata.cause_of_death'
|
||||||
|
)
|
||||||
|
.orderBy('kills', 'desc')
|
||||||
|
.execute()
|
||||||
|
//if no new kills
|
||||||
|
if (newData.length == 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
last_entry = newData.reduce(
|
||||||
|
(acc, current) => (current.last_entry > acc ? current.last_entry : acc),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
console.log(newData)
|
||||||
|
const promises: Promise<number>[] = []
|
||||||
|
newData.forEach(({ weapon, kills, deaths }) => {
|
||||||
|
promises.push(
|
||||||
|
cache.HINCRBY(
|
||||||
|
`servers:${server}:players:${player}:weapons:deaths`,
|
||||||
|
weapon,
|
||||||
|
deaths
|
||||||
|
),
|
||||||
|
cache.HINCRBY(
|
||||||
|
`servers:${server}:players:${player}:weapons:kills`,
|
||||||
|
weapon,
|
||||||
|
kills
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
promises.push(
|
||||||
|
cache.HSET(
|
||||||
|
`servers:${server}:players:${player}:weapons`,
|
||||||
|
'last_entry',
|
||||||
|
newData[0].last_entry
|
||||||
|
)
|
||||||
|
)
|
||||||
|
await Promise.all(promises)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default middlewares
|
||||||
+14
-19
@@ -1,32 +1,24 @@
|
|||||||
import { Router } from 'express'
|
import { RequestHandler } from 'express'
|
||||||
import { param, validationResult } from 'express-validator'
|
import { param } from 'express-validator'
|
||||||
|
import { validateErrors } from '../common'
|
||||||
import cache from '../cache/redis'
|
import cache from '../cache/redis'
|
||||||
import db from '../db/db'
|
import db from '../db/db'
|
||||||
const router = Router()
|
|
||||||
const { count, max } = db.fn
|
const { count, max } = db.fn
|
||||||
|
|
||||||
router.get(
|
const middlewares: RequestHandler[] = [
|
||||||
'/servers/:serverId/weapons',
|
|
||||||
param('serverId').exists().toInt().isInt(),
|
param('serverId').exists().toInt().isInt(),
|
||||||
|
validateErrors,
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
console.error(JSON.stringify(errors))
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
if (!req.params) {
|
|
||||||
res.sendStatus(500)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const server = Number(req.params.serverId)
|
const server = Number(req.params.serverId)
|
||||||
await processTopWeapons(server)
|
await processWeapons(server)
|
||||||
const data = await cache.HGETALL(`servers:${server}:weapons`)
|
const data = await cache.HGETALL(`servers:${server}:weapons`)
|
||||||
delete data.last_entry
|
delete data.last_entry
|
||||||
res.status(200).send(data)
|
res.status(200).send(data)
|
||||||
}
|
}
|
||||||
)
|
]
|
||||||
|
|
||||||
async function processTopWeapons(server: number) {
|
async function processWeapons(server: number) {
|
||||||
let last_entry =
|
let last_entry =
|
||||||
Number(await cache.HGET(`servers:${server}:weapons`, 'last_entry')) || 0
|
Number(await cache.HGET(`servers:${server}:weapons`, 'last_entry')) || 0
|
||||||
const newData = await db
|
const newData = await db
|
||||||
@@ -34,7 +26,10 @@ async function processTopWeapons(server: number) {
|
|||||||
.select([
|
.select([
|
||||||
count<number>('kill.id').as('num_kills'),
|
count<number>('kill.id').as('num_kills'),
|
||||||
'kill.cause_of_death',
|
'kill.cause_of_death',
|
||||||
max('kill.id').as('last_entry')
|
db
|
||||||
|
.selectFrom('kill')
|
||||||
|
.select(max('kill.id').as('last_entry'))
|
||||||
|
.as('last_entry')
|
||||||
])
|
])
|
||||||
.where('server', '=', server)
|
.where('server', '=', server)
|
||||||
.where('kill.id', '>', last_entry)
|
.where('kill.id', '>', last_entry)
|
||||||
@@ -60,4 +55,4 @@ async function processTopWeapons(server: number) {
|
|||||||
await Promise.all(promises)
|
await Promise.all(promises)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default router
|
export default middlewares
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { RequestHandler } from 'express'
|
||||||
|
import { Result, validationResult } from 'express-validator'
|
||||||
import http from 'http'
|
import http from 'http'
|
||||||
import https from 'https'
|
import https from 'https'
|
||||||
|
|
||||||
@@ -29,3 +31,12 @@ export function GetRequest(url: string) {
|
|||||||
.end()
|
.end()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const validateErrors: RequestHandler = (req, res, next) => {
|
||||||
|
const errors = validationResult(req)
|
||||||
|
if (!errors.isEmpty()) {
|
||||||
|
console.error(JSON.stringify(errors))
|
||||||
|
return res.status(400).json({ errors: errors.array() })
|
||||||
|
}
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Router } from 'express'
|
import { Router } from 'express'
|
||||||
import { GetRequest } from '../common'
|
import { GetRequest, validateErrors } from '../common'
|
||||||
import { FindServer, CreateServer } from '../db/db'
|
import { FindServer, CreateServer } from '../db/db'
|
||||||
import { body, validationResult } from 'express-validator'
|
import { body, validationResult } from 'express-validator'
|
||||||
|
|
||||||
@@ -37,12 +37,8 @@ router.post(
|
|||||||
.toInt()
|
.toInt()
|
||||||
.isInt({ min: 1, max: 65535 })
|
.isInt({ min: 1, max: 65535 })
|
||||||
.withMessage('must be between 1 and 65535'),
|
.withMessage('must be between 1 and 65535'),
|
||||||
async (req, res, next) => {
|
validateErrors,
|
||||||
const errors = validationResult(req)
|
async (req, res) => {
|
||||||
console.log(req.body)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
//Check if server name isn't already in database
|
//Check if server name isn't already in database
|
||||||
if (!!(await FindServer({ name: req.body.name }))) {
|
if (!!(await FindServer({ name: req.body.name }))) {
|
||||||
|
|||||||
+3
-13
@@ -3,6 +3,7 @@ import expressBasicAuth from 'express-basic-auth'
|
|||||||
import { body, header, validationResult } from 'express-validator'
|
import { body, header, validationResult } from 'express-validator'
|
||||||
import register from './register'
|
import register from './register'
|
||||||
import { CreateKillRecord, CheckServerToken } from '../db/db'
|
import { CreateKillRecord, CheckServerToken } from '../db/db'
|
||||||
|
import { validateErrors } from '../common'
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
@@ -17,14 +18,7 @@ router.post(
|
|||||||
.bail()
|
.bail()
|
||||||
.contains('Basic')
|
.contains('Basic')
|
||||||
.withMessage('Authorization Token is not Basic'),
|
.withMessage('Authorization Token is not Basic'),
|
||||||
(req, res, next) => {
|
validateErrors,
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
console.log(JSON.stringify(errors))
|
|
||||||
return res.status(403).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
next()
|
|
||||||
},
|
|
||||||
//Huge mess to retrieve server id from expressBasicAuth. We probably should fix it.
|
//Huge mess to retrieve server id from expressBasicAuth. We probably should fix it.
|
||||||
(req, res, next) => {
|
(req, res, next) => {
|
||||||
if (!req) res.sendStatus(500)
|
if (!req) res.sendStatus(500)
|
||||||
@@ -118,12 +112,8 @@ router.post(
|
|||||||
min: 0
|
min: 0
|
||||||
}),
|
}),
|
||||||
body(['cause_of_death', 'victim_id'], 'mandatory').exists().notEmpty(),
|
body(['cause_of_death', 'victim_id'], 'mandatory').exists().notEmpty(),
|
||||||
|
validateErrors,
|
||||||
(req, res) => {
|
(req, res) => {
|
||||||
const errors = validationResult(req)
|
|
||||||
if (!errors.isEmpty()) {
|
|
||||||
console.error(JSON.stringify(errors))
|
|
||||||
return res.status(400).json({ errors: errors.array() })
|
|
||||||
}
|
|
||||||
const {
|
const {
|
||||||
killstat_version,
|
killstat_version,
|
||||||
match_id,
|
match_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user