131 lines
4.6 KiB
TypeScript
131 lines
4.6 KiB
TypeScript
/**
|
|
* This script is used to merge multiple stats_playerDrop files into a single file with the last 336 hours of data.
|
|
* NOTE: use npx tsx scripts/dev/makeOldStatsFile.local.ts to run this script
|
|
*/
|
|
import fs from 'node:fs';
|
|
import { shuffle } from 'd3-array';
|
|
import { PDLChangeEventType, PDLFileType } from '../../core/modules/Metrics/playerDrop/playerDropSchemas';
|
|
import { MultipleCounter } from '../../core/modules/Metrics/statsUtils';
|
|
|
|
|
|
type CountersType = {
|
|
drops: MultipleCounter,
|
|
resKicks: MultipleCounter,
|
|
crashes: MultipleCounter,
|
|
changes: PDLChangeEventType[],
|
|
};
|
|
|
|
const getRandomResource = () => {
|
|
const pool = [
|
|
'anticheat', 'anticheat', 'anticheat', 'anticheat',
|
|
'txAdmin', 'txAdmin', 'txAdmin',
|
|
'vMenu',
|
|
'es_extended',
|
|
];
|
|
return pool[Math.floor(Math.random() * pool.length)];
|
|
}
|
|
|
|
|
|
export default (sourceFiles: string[], targetFileName: string) => {
|
|
let logCounters: CountersType[] = [];
|
|
for (const fileName of sourceFiles) {
|
|
const fileData = JSON.parse(fs.readFileSync(fileName, 'utf8')) as PDLFileType;
|
|
console.log('fileData.log.length:', fileData.log.length);
|
|
for (const log of fileData.log) {
|
|
const resKicks = new MultipleCounter();
|
|
const drops = log.dropTypes.map(([type, count]): [string, number] | false => {
|
|
if (type === 'user-initiated') {
|
|
return ['player', count]
|
|
} else if (type === 'server-initiated') {
|
|
resKicks.count('txAdmin', count);
|
|
return ['resource', count];
|
|
} else if (type === 'unknown') {
|
|
if (Math.random() <= 0.2) {
|
|
return [type, count];
|
|
} else {
|
|
resKicks.count(getRandomResource(), count);
|
|
return ['resource', count];
|
|
}
|
|
} else {
|
|
return [type, count];
|
|
}
|
|
}).filter((x): x is [string, number] => Array.isArray(x));
|
|
|
|
|
|
logCounters.push({
|
|
// drops: new MultipleCounter(log.dropTypes.filter(([type]) => type !== 'server-initiated')),
|
|
drops: new MultipleCounter(drops),
|
|
resKicks: resKicks,
|
|
crashes: new MultipleCounter(log.crashTypes),
|
|
changes: log.changes,
|
|
});
|
|
}
|
|
}
|
|
console.log('Logs Hours:', logCounters.length);
|
|
|
|
|
|
//Shuffle and merge all crashes into 336 MultipleCounters and shuffle them again
|
|
logCounters = shuffle(logCounters);
|
|
let mergedCounters: CountersType[] = [];
|
|
for (let i = 0; i < logCounters.length; i++) {
|
|
const writeIndex = i % 336;
|
|
const currCounters = logCounters[i];
|
|
if (!mergedCounters[writeIndex]) {
|
|
mergedCounters[writeIndex] = currCounters;
|
|
} else {
|
|
mergedCounters[writeIndex].drops.merge(currCounters.drops);
|
|
mergedCounters[writeIndex].resKicks.merge(currCounters.resKicks);
|
|
mergedCounters[writeIndex].crashes.merge(currCounters.crashes);
|
|
mergedCounters[writeIndex].changes.push(...currCounters.changes);
|
|
}
|
|
|
|
}
|
|
mergedCounters = shuffle(mergedCounters);
|
|
console.log('mergedCrashes.length:', mergedCounters.length);
|
|
|
|
|
|
//Prepare new hours array
|
|
const last336Hours: Date[] = [];
|
|
const currentDate = new Date();
|
|
currentDate.setMinutes(0, 0, 0);
|
|
for (let i = 335; i >= 0; i--) {
|
|
const hour = new Date(currentDate.getTime() - i * 60 * 60 * 1000);
|
|
last336Hours.push(hour);
|
|
}
|
|
console.log('last336Hours.length:', last336Hours.length);
|
|
|
|
|
|
//Prepare new log with the data
|
|
const newLog: PDLFileType['log'] = [];
|
|
for (const hour of last336Hours) {
|
|
const counters = mergedCounters.pop()!;
|
|
const newHour = {
|
|
hour: hour.toISOString(),
|
|
changes: counters?.changes ?? [],
|
|
dropTypes: counters?.drops.toArray() ?? [],
|
|
resKicks: counters?.resKicks.toArray() ?? [],
|
|
crashTypes: counters?.crashes.toArray() ?? [],
|
|
};
|
|
newLog.push(newHour);
|
|
console.dir({
|
|
hour: newHour.hour,
|
|
changes: newHour.changes.length,
|
|
drops: counters.drops.sum(),
|
|
resKicks: counters.resKicks.sum(),
|
|
crashes: counters.crashes.sum(),
|
|
});
|
|
}
|
|
|
|
|
|
//Write new file
|
|
const newStatsFile: PDLFileType = {
|
|
version: 2,
|
|
lastGameVersion: 'unknown',
|
|
lastServerVersion: 'unknown',
|
|
lastResourceList: [],
|
|
lastUnknownReasons: [],
|
|
log: newLog,
|
|
}
|
|
fs.writeFileSync(targetFileName, JSON.stringify(newStatsFile));
|
|
}
|