mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-21 17:12:44 +02:00
* Add decrypt-save.js * Update scripts/decrypt-save.js Co-authored-by: Amani H. <109637146+xsn34kzx@users.noreply.github.com> --------- Co-authored-by: Amani H. <109637146+xsn34kzx@users.noreply.github.com>
150 lines
3.9 KiB
JavaScript
150 lines
3.9 KiB
JavaScript
import pkg from "crypto-js";
|
|
const { AES, enc } = pkg;
|
|
// biome-ignore lint: This is how you import fs from node
|
|
import * as fs from "node:fs";
|
|
|
|
const SAVE_KEY = "x0i2O7WRiANTqPmZ";
|
|
|
|
/**
|
|
* A map of condensed keynames to their associated full names
|
|
* NOTE: Update this if `src/system/game-data#systemShortKeys` ever changes!
|
|
*/
|
|
const systemShortKeys = {
|
|
seenAttr: "$sa",
|
|
caughtAttr: "$ca",
|
|
natureAttr: "$na",
|
|
seenCount: "$s",
|
|
caughtCount: "$c",
|
|
hatchedCount: "$hc",
|
|
ivs: "$i",
|
|
moveset: "$m",
|
|
eggMoves: "$em",
|
|
candyCount: "$x",
|
|
friendship: "$f",
|
|
abilityAttr: "$a",
|
|
passiveAttr: "$pa",
|
|
valueReduction: "$vr",
|
|
classicWinCount: "$wc",
|
|
};
|
|
|
|
/**
|
|
* Replace the shortened key names with their full names
|
|
* @param {string} dataStr - The string to convert
|
|
* @returns {string} The string with shortened keynames replaced with full names
|
|
*/
|
|
function convertSystemDataStr(dataStr) {
|
|
const fromKeys = Object.values(systemShortKeys);
|
|
const toKeys = Object.keys(systemShortKeys);
|
|
for (const k in fromKeys) {
|
|
dataStr = dataStr.replace(new RegExp(`${fromKeys[k].replace("$", "\\$")}`, "g"), toKeys[k]);
|
|
}
|
|
|
|
return dataStr;
|
|
}
|
|
|
|
/**
|
|
* Decrypt a save
|
|
* @param {string} path - The path to the encrypted save file
|
|
* @returns {string} The decrypted save data
|
|
*/
|
|
function decryptSave(path) {
|
|
// Check if the file exists
|
|
if (!fs.existsSync(path)) {
|
|
console.error(`File not found: ${path}`);
|
|
process.exit(1);
|
|
}
|
|
let fileData;
|
|
try {
|
|
fileData = fs.readFileSync(path, "utf8");
|
|
} catch (e) {
|
|
switch (e.code) {
|
|
case "ENOENT":
|
|
console.error(`File not found: ${path}`);
|
|
break;
|
|
case "EACCES":
|
|
console.error(`Could not open ${path}: Permission denied`);
|
|
break;
|
|
case "EISDIR":
|
|
console.error(`Unable to read ${path} as it is a directory`);
|
|
break;
|
|
default:
|
|
console.error(`Error reading file: ${e.message}`);
|
|
}
|
|
process.exit(1);
|
|
}
|
|
return convertSystemDataStr(AES.decrypt(fileData, SAVE_KEY).toString(enc.Utf8));
|
|
}
|
|
|
|
/* Print the usage message and exits */
|
|
function printUsage() {
|
|
console.log(`
|
|
Usage: node decrypt-save.js <encrypted-file> [save-file]
|
|
|
|
Arguments:
|
|
file-path Path to the encrypted save file to decrypt.
|
|
save-file Path to where the decrypted data should be written. If not provided, the decrypted data will be printed to the console.
|
|
|
|
Options:
|
|
-h, --help Show this help message and exit.
|
|
|
|
Description:
|
|
This script decrypts an encrypted pokerogue save file
|
|
`);
|
|
}
|
|
|
|
/**
|
|
* Write `data` to `filePath`, gracefully communicating errors that arise
|
|
* @param {string} filePath
|
|
* @param {string} data
|
|
*/
|
|
function writeToFile(filePath, data) {
|
|
try {
|
|
fs.writeFileSync(filePath, data);
|
|
} catch (e) {
|
|
switch (e.code) {
|
|
case "EACCES":
|
|
console.error(`Could not open ${filePath}: Permission denied`);
|
|
break;
|
|
case "EISDIR":
|
|
console.error(`Unable to write to ${filePath} as it is a directory`);
|
|
break;
|
|
default:
|
|
console.error(`Error writing file: ${e.message}`);
|
|
}
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
function main() {
|
|
let args = process.argv.slice(2);
|
|
// Get options
|
|
const options = args.filter(arg => arg.startsWith("-"));
|
|
// get args
|
|
args = args.filter(arg => !arg.startsWith("-"));
|
|
|
|
if (args.length === 0 || options.includes("-h") || options.includes("--help") || args.length > 2) {
|
|
printUsage();
|
|
process.exit(0);
|
|
}
|
|
// If the user provided a second argument, check if the file exists already and refuse to write to it.
|
|
if (args.length === 2) {
|
|
const destPath = args[1];
|
|
if (fs.existsSync(destPath)) {
|
|
console.error(`Refusing to overwrite ${destPath}`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Otherwise, commence decryption.
|
|
const decrypt = decryptSave(args[0]);
|
|
|
|
if (args.length === 1) {
|
|
process.stdout.write(decrypt);
|
|
process.exit(0);
|
|
}
|
|
|
|
writeToFile(destPath, decrypt);
|
|
}
|
|
|
|
main();
|