mirror of
https://github.com/JDM170/model_coder
synced 2025-12-10 05:57:19 +07:00
80 lines
2.9 KiB
JavaScript
80 lines
2.9 KiB
JavaScript
const chalk = require('chalk');
|
|
const yargs = require('yargs/yargs')
|
|
const { hideBin } = require('yargs/helpers')
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const ora = require('ora');
|
|
const glob = require("glob");
|
|
const tea = require('mta-tea');
|
|
const crypto = require('crypto');
|
|
|
|
const error = chalk.bold.red;
|
|
|
|
const argv = yargs(hideBin(process.argv))
|
|
.usage('Usage: $0 -pass [pass] -res [path]')
|
|
.example('$0 -pass decryptme -res resourceName', 'Decrypt resourceName')
|
|
.options('pass', {
|
|
alias: 'p',
|
|
describe: 'Password for the decryption',
|
|
type: 'string',
|
|
coerce: arg =>
|
|
arg && arg.length >= 6 ? arg : undefined
|
|
})
|
|
.options('res', {
|
|
alias: 'r',
|
|
describe: 'Resource folder path',
|
|
type: 'string',
|
|
coerce: arg =>
|
|
arg && fs.existsSync(path.resolve(__dirname, arg)) && fs.lstatSync(path.resolve(__dirname, arg)).isDirectory() ? arg : undefined
|
|
})
|
|
.demandOption(['pass'], error("Include password with 6 symbols or more!"))
|
|
.demandOption(['res'], error("Incorrect or no resource folder selected!"))
|
|
.argv;
|
|
|
|
const blockSize = 12; // encoded block length
|
|
const encodeSize = 3000; // encoded byte count
|
|
const decodeSize = blockSize * encodeSize;
|
|
|
|
let getDirectories = (src, callback) => {
|
|
glob(src + '/**/*', callback);
|
|
}
|
|
|
|
const extensions = ['.colrw', '.colc', '.txdrw', '.txdc', '.dffrw', '.dffc']
|
|
|
|
let spinner = ora('Getting files list').start();
|
|
getDirectories(argv.res, (err, res) => {
|
|
if (err) {
|
|
spinner.fail('Something went wrong!')
|
|
} else {
|
|
let files = res.filter(element => fs.lstatSync(path.resolve(__dirname, element)).isFile() && extensions.includes(path.extname(element)))
|
|
spinner.succeed()
|
|
|
|
spinner = ora('Decoding files').start();
|
|
files.forEach(file => {
|
|
const newFilePath = file + '.dec';
|
|
|
|
// Decoding first $decodeSize bytes from file
|
|
const key = crypto.createHash('md5').update(argv.pass).digest('hex').substring(0, 16);
|
|
const data = fs.readFileSync(file);
|
|
const encodedPart = data.toString().substring(0, decodeSize);
|
|
let decoded = [];
|
|
for (let i = 0; i < decodeSize; i += blockSize)
|
|
decoded.push(tea.decode(encodedPart.substring(i, i + blockSize), key));
|
|
|
|
// Checking the file for existence, if the file exists - deleting it
|
|
try {
|
|
fs.accessSync(newFilePath);
|
|
fs.rmSync(newFilePath);
|
|
} catch (err) {
|
|
// console.log("access err: " + err);
|
|
}
|
|
|
|
let fd = fs.openSync(newFilePath, 'a+'); // Open file
|
|
fs.writeSync(fd, Buffer.from(decoded), 0); // Writing decoded part in start of file
|
|
fs.writeSync(fd, data, decodeSize, data.length - decodeSize); // Writing original part after decoded part
|
|
fs.closeSync(fd); // Close file
|
|
});
|
|
spinner.succeed()
|
|
}
|
|
})
|