Skip to content

Instantly share code, notes, and snippets.

@tfausak
Created October 25, 2017 21:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tfausak/4cb555d7164c689b99ff0d422107a182 to your computer and use it in GitHub Desktop.
Save tfausak/4cb555d7164c689b99ff0d422107a182 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
'use strict';
// This is a little JavaScript utility meant to be used with Rattletrap to
// reduce the size of Rocket League replay files. See this issue for more:
// <https://github.com/tfausak/rattletrap/issues/49>. Example usage:
//
// $ stack exec rattletrap decode < original.replay > original.json
// $ node strip-replay.js < original.json > stripped.json
// $ stack exec rattletrap encode < stripped.json > stripped.replay
//
// The resulting stripped replay will usually be about 10% smaller than the
// original one. The exact savings depend on the contents of the replay though.
process.stdin.setEncoding('utf8');
let data = '';
process.stdin.on('data', function (chunk) {
data += chunk;
});
function isEqual (x, y) {
if (x === y) {
return true;
}
if (x instanceof Object && y instanceof Object) {
const keys = Object.keys(x).sort();
for (const key of keys) {
if (!isEqual(x[key], y[key])) {
return false;
}
}
return true;
}
return false;
}
process.stdin.on('end', function () {
const replay = JSON.parse(data);
replay.header.properties.keys = [];
replay.header.properties.value = {};
replay.content.key_frames = [];
replay.content.marks = [];
replay.content.messages = [];
replay.content.stream_size = 0;
const state = {};
for (const frame of replay.content.frames) {
const newReplications = [];
for (let index = 0; index < frame.replications.length; index += 1) {
const replication = frame.replications[index];
const actorId = replication.actor_id.value;
if (replication.value.hasOwnProperty('spawned_replication_value')) {
// spawned
if (!state.hasOwnProperty(actorId)) {
state[actorId] = {};
newReplications.push(replication);
}
} else if (replication.value.hasOwnProperty('updated_replication_value')) {
// updated
const newAttributes = [];
for (const attribute of replication.value.updated_replication_value) {
if (!isEqual(state[actorId][attribute.name], attribute.value)) {
state[actorId][attribute.name] = attribute.value;
newAttributes.push(attribute);
}
}
if (newAttributes.length > 0) {
replication.value.updated_replication_value = newAttributes;
newReplications.push(replication);
}
} else {
// destroyed
if (state.hasOwnProperty(actorId)) {
newReplications.push(replication);
delete state[actorId];
}
}
}
frame.replications = newReplications;
}
console.log(JSON.stringify(replay));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment