2020-12-22 22:35:09 +01:00
|
|
|
import fs from 'fs'
|
2021-06-09 09:52:58 +02:00
|
|
|
import Protocol from '../common/Protocol'
|
2021-05-31 20:05:41 +02:00
|
|
|
import Time from '../common/Time'
|
2021-07-08 00:00:17 +02:00
|
|
|
import { DefaultScoreMode, DefaultShapeMode, DefaultSnapMode, Timestamp } from '../common/Types'
|
2021-05-17 01:12:39 +02:00
|
|
|
import { logger } from './../common/Util'
|
|
|
|
|
import { DATA_DIR } from './../server/Dirs'
|
2021-04-13 20:18:41 +02:00
|
|
|
|
|
|
|
|
const log = logger('GameLog.js')
|
2020-12-22 22:35:09 +01:00
|
|
|
|
2021-06-05 17:13:17 +02:00
|
|
|
const LINES_PER_LOG_FILE = 10000
|
2021-05-31 20:05:41 +02:00
|
|
|
const POST_GAME_LOG_DURATION = 5 * Time.MIN
|
|
|
|
|
|
|
|
|
|
const shouldLog = (finishTs: Timestamp, currentTs: Timestamp): boolean => {
|
|
|
|
|
// when not finished yet, always log
|
|
|
|
|
if (!finishTs) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// in finished games, log max POST_GAME_LOG_DURATION after
|
|
|
|
|
// the game finished, to record winning dance moves etc :P
|
|
|
|
|
const timeSinceGameEnd = currentTs - finishTs
|
|
|
|
|
return timeSinceGameEnd <= POST_GAME_LOG_DURATION
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-05 23:02:04 +02:00
|
|
|
export const filename = (gameId: string, offset: number) => `${DATA_DIR}/log_${gameId}-${offset}.log`
|
|
|
|
|
export const idxname = (gameId: string) => `${DATA_DIR}/log_${gameId}.idx.log`
|
2020-12-22 22:54:31 +01:00
|
|
|
|
2021-06-06 08:57:42 +02:00
|
|
|
const create = (gameId: string, ts: Timestamp): void => {
|
2021-06-05 17:13:17 +02:00
|
|
|
const idxfile = idxname(gameId)
|
|
|
|
|
if (!fs.existsSync(idxfile)) {
|
|
|
|
|
fs.appendFileSync(idxfile, JSON.stringify({
|
2021-06-05 23:02:04 +02:00
|
|
|
gameId: gameId,
|
2021-06-05 17:13:17 +02:00
|
|
|
total: 0,
|
2021-06-06 08:57:42 +02:00
|
|
|
lastTs: ts,
|
2021-06-09 09:52:58 +02:00
|
|
|
currentFile: '',
|
2021-06-05 17:13:17 +02:00
|
|
|
perFile: LINES_PER_LOG_FILE,
|
|
|
|
|
}))
|
2020-12-22 22:54:31 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-29 15:36:03 +02:00
|
|
|
const exists = (gameId: string): boolean => {
|
2021-06-05 17:13:17 +02:00
|
|
|
const idxfile = idxname(gameId)
|
|
|
|
|
return fs.existsSync(idxfile)
|
2020-12-22 22:54:31 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-05 23:02:04 +02:00
|
|
|
const _log = (gameId: string, type: number, ...args: Array<any>): void => {
|
2021-06-05 17:13:17 +02:00
|
|
|
const idxfile = idxname(gameId)
|
|
|
|
|
if (!fs.existsSync(idxfile)) {
|
2020-12-22 22:54:31 +01:00
|
|
|
return
|
|
|
|
|
}
|
2021-06-05 17:13:17 +02:00
|
|
|
|
2021-06-09 09:52:58 +02:00
|
|
|
const idxObj = JSON.parse(fs.readFileSync(idxfile, 'utf-8'))
|
|
|
|
|
if (idxObj.total % idxObj.perFile === 0) {
|
|
|
|
|
idxObj.currentFile = filename(gameId, idxObj.total)
|
|
|
|
|
}
|
2021-06-05 17:13:17 +02:00
|
|
|
|
2021-06-09 09:52:58 +02:00
|
|
|
const tsIdx = type === Protocol.LOG_HEADER ? 3 : (args.length - 1)
|
|
|
|
|
const ts: Timestamp = args[tsIdx]
|
|
|
|
|
if (type !== Protocol.LOG_HEADER) {
|
|
|
|
|
// for everything but header save the diff to last log entry
|
|
|
|
|
args[tsIdx] = ts - idxObj.lastTs
|
2021-06-05 17:13:17 +02:00
|
|
|
}
|
2021-06-09 09:52:58 +02:00
|
|
|
const line = JSON.stringify([type, ...args]).slice(1, -1)
|
|
|
|
|
fs.appendFileSync(idxObj.currentFile, line + "\n")
|
|
|
|
|
|
|
|
|
|
idxObj.total++
|
|
|
|
|
idxObj.lastTs = ts
|
|
|
|
|
fs.writeFileSync(idxfile, JSON.stringify(idxObj))
|
2020-12-22 22:35:09 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-05 17:13:17 +02:00
|
|
|
const get = (
|
2021-05-29 11:44:55 +02:00
|
|
|
gameId: string,
|
|
|
|
|
offset: number = 0,
|
2021-06-05 17:13:17 +02:00
|
|
|
): any[] => {
|
|
|
|
|
const idxfile = idxname(gameId)
|
|
|
|
|
if (!fs.existsSync(idxfile)) {
|
|
|
|
|
return []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const file = filename(gameId, offset)
|
2020-12-22 22:54:31 +01:00
|
|
|
if (!fs.existsSync(file)) {
|
|
|
|
|
return []
|
|
|
|
|
}
|
2021-06-05 17:13:17 +02:00
|
|
|
|
2021-07-08 00:00:17 +02:00
|
|
|
const lines = fs.readFileSync(file, 'utf-8').split("\n")
|
|
|
|
|
const log = lines.filter(line => !!line).map(line => {
|
2021-06-05 23:02:04 +02:00
|
|
|
return JSON.parse(`[${line}]`)
|
2020-12-22 22:35:09 +01:00
|
|
|
})
|
2021-07-08 00:00:17 +02:00
|
|
|
if (offset === 0 && log.length > 0) {
|
|
|
|
|
log[0][5] = DefaultScoreMode(log[0][5])
|
|
|
|
|
log[0][6] = DefaultShapeMode(log[0][6])
|
|
|
|
|
log[0][7] = DefaultSnapMode(log[0][7])
|
|
|
|
|
}
|
|
|
|
|
return log
|
2020-12-22 22:35:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default {
|
2021-05-31 20:05:41 +02:00
|
|
|
shouldLog,
|
2020-12-22 22:54:31 +01:00
|
|
|
create,
|
|
|
|
|
exists,
|
2021-04-13 20:18:41 +02:00
|
|
|
log: _log,
|
2020-12-22 22:35:09 +01:00
|
|
|
get,
|
2021-07-11 16:37:34 +02:00
|
|
|
filename,
|
|
|
|
|
idxname,
|
2020-12-22 22:35:09 +01:00
|
|
|
}
|