Skip to content

Instantly share code, notes, and snippets.

@smrq
Created May 8, 2016 02:12
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 smrq/bec78b3ce91657ee5e5cb1ddd33e778a to your computer and use it in GitHub Desktop.
Save smrq/bec78b3ce91657ee5e5cb1ddd33e778a to your computer and use it in GitHub Desktop.
Hyper Light Drifter script to find gearbit/key IDs
'use strict';
const path = require('path');
const fs = require('fs');
const saveFilename = path.join(process.env.LOCALAPPDATA, 'HyperLightDrifter/HyperLight_RecordOfTheDrifter_0.sav');
let currentSaveData;
init(saveFilename);
fs.watch(saveFilename, { persistent: true }, (event, filename) => {
if (event === 'change') {
run(saveFilename);
}
});
function init(filename) {
const saveData = parseSave(filename);
currentSaveData = saveData;
const gearbits = getGearbits(saveData);
const keys = getKeys(saveData);
console.log(`Watcher initialized for save file ${saveFilename}.`);
console.log(`Current count: ${gearbits.length} gearbits, ${keys.length} keys.`);
console.log('-----------------------------');
console.log('Collected gearbit IDs:');
console.log(gearbits.join(', '));
console.log('-----------------------------');
console.log('Collected key IDs:');
console.log(keys.join(', '));
}
function run(filename) {
const newSaveData = parseSave(filename);
const newGearbits = getGearbits(newSaveData);
const newKeys = getKeys(newSaveData);
const currentGearbits = getGearbits(currentSaveData);
const currentKeys = getKeys(currentSaveData);
const addedGearbits = without(newGearbits, currentGearbits);
const removedGearbits = without(currentGearbits, newGearbits);
const addedKeys = without(newKeys, currentKeys);
const removedKeys = without(currentKeys, newKeys);
let changed = false;
if (removedGearbits.length) {
console.log('---------------------------------');
console.log(new Date());
console.log(`WARNING: Gearbit(s) removed! ${removedGearbits.join(', ')}`);
changed = true;
}
if (addedGearbits.length) {
console.log('---------------------------------');
console.log(new Date());
console.log(`Gearbit(s) added: ${addedGearbits.join(', ')}`)
changed = true;
}
if (removedKeys.length) {
console.log('---------------------------------');
console.log(new Date());
console.log(`WARNING: Key(s) removed! ${removedKeys.join(', ')}`);
changed = true;
}
if (addedKeys.length) {
console.log('---------------------------------');
console.log(new Date());
console.log(`Key(s) added: ${addedKeys.join(', ')}`)
changed = true;
}
if (changed) {
console.log(`New count: ${newGearbits.length} gearbits, ${newKeys.length} keys.`);
}
currentSaveData = newSaveData;
}
function getGearbits(saveData) {
return saveData.cl['0'] || [];
}
function getKeys(saveData) {
return saveData.cl['2'] || [];
}
function parseSave(filename) {
const base64str = fs.readFileSync(filename, 'utf8');
const base64buf = new Buffer(base64str, 'base64');
const jsonStrWithJunk = base64buf.toString();
const jsonStr = jsonStrWithJunk
.slice(jsonStrWithJunk.indexOf('{ '))
.slice(0, -1);
const saveData = JSON.parse(jsonStr);
for (let key in saveData) {
if (!Object.hasOwnProperty.call(saveData, key)) continue;
saveData[key] = parseValue(saveData[key]);
}
return saveData;
}
function parseValue(value) {
if (/>$/.test(value)) {
return parseObjValue(value);
} else if (/\+$/.test(value)) {
return parseArrValue(value, '+');
} else if (/&$/.test(value)) {
return parseArrValue(value, '&');
} else {
return value;
}
}
function parseObjValue(value) {
const split = value.split('>').slice(0, -1);
const result = {};
split.forEach(segment => {
const match = /(.+)=(.+)/.exec(segment);
const key = match[1];
const value = parseValue(match[2]);
result[key] = value;
});
return result;
}
function parseArrValue(value, delim) {
return value.split(delim).slice(0, -1);
}
function without(arr1, arr2) {
return arr1.filter(x => arr2.indexOf(x) === -1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment