Created
December 13, 2016 02:19
-
-
Save chrahunt/c796357137a7d0da8d5a6cbb0caf538f to your computer and use it in GitHub Desktop.
Convert replays
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const {ArgumentParser} = require('argparse'); | |
const glob = require('glob'); | |
const fs = require('fs'); | |
const {round10} = require('round10'); | |
function main() { | |
let parser = new ArgumentParser({ description: "minify replay files."}); | |
parser.addArgument('glob'); | |
let args = parser.parseArgs(); | |
let stats = []; | |
glob(args.glob, (err, matches) => { | |
console.log(`Found ${matches.length} matches`); | |
for (let match of matches) { | |
console.log(`Processing ${match}`); | |
let these_stats = { | |
name: match | |
}; | |
let data = fs.readFileSync(match, { encoding: 'utf-8' }); | |
these_stats.start_length = data.length; | |
let result = convert(data); | |
these_stats.end_length = result.length; | |
fs.writeFileSync(`${match}.min`, result); | |
stats.push(these_stats); | |
} | |
console.dir(stats); | |
}); | |
} | |
main(); | |
function deepEq(a, b) { | |
let a_fields = Object.keys(a); | |
let b_fields = Object.keys(b); | |
if (b_fields.some(f => !a_fields.includes(f))) return false; | |
if (a_fields.some(f => !b_fields.includes(f))) return false; | |
for (let field in a) { | |
if (!(field in b)) return false; | |
if (!eq(a[field], b[field])) return false; | |
} | |
return true; | |
} | |
function eq(a, b) { | |
if (typeof a === typeof b) { | |
if (a !== null && b !== null && typeof a === 'object') { | |
return deepEq(a, b); | |
} else { | |
return a === b; | |
} | |
} else { | |
return false; | |
} | |
} | |
function convertFrameArray(array, clock) { | |
let struct = { | |
init: array[0], | |
changes: [] | |
}; | |
let last_val = struct.init; | |
for (let i = 1; i < array.length; i++) { | |
let val = array[i]; | |
if (!eq(val, last_val)) { | |
struct.changes.push([val, clock[i]]); | |
last_val = val; | |
} | |
} | |
return struct; | |
} | |
function convertDenseArray(array) { | |
let out = [array[0]]; | |
let last = out[0]; | |
for (let i = 1; i < array.length; i++) { | |
out.push(last - array[i]); | |
last = array[i]; | |
} | |
return out; | |
} | |
function convertPlayer(player, clock) { | |
// Arrays | |
let arrays = ["degree", "bomb", "grip", "flag", "tagpro", "auth", "name", "team", "dead", "draw", "flair"]; | |
for (let name of arrays) { | |
let array = player[name]; | |
player[name] = convertFrameArray(array, clock); | |
} | |
// Dense array. | |
arrays = ["x", "y", "angle"]; | |
for (let name of arrays) { | |
player[name] = convertDenseArray(player[name]).map(v => round10(v, -2)); | |
} | |
return player; | |
} | |
function convertFloorTile(tile, clock) { | |
tile.value = convertFrameArray(tile.value, clock); | |
return tile; | |
} | |
function convert(replay) { | |
let struct = JSON.parse(replay); | |
let clock = struct.clock.map(Date.parse); | |
let players = Object.keys(struct).filter(k => k.startsWith('player')); | |
for (let player of players) { | |
//console.log(`Editing player ${player}`); | |
struct[player] = convertPlayer(struct[player], clock); | |
} | |
struct.floorTiles = struct.floorTiles.map(t => convertFloorTile(t, clock)); | |
struct.score = convertFrameArray(struct.score, clock); | |
struct.clock = convertDenseArray(clock); | |
// Generate dynamically during rendering. | |
delete struct.tiles; | |
delete struct.wallMap; | |
return JSON.stringify(struct); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment