dolphin-tool
Version:
🐬 dolphin-tool binaries and wrapper for Node.js.
75 lines • 3.49 kB
JavaScript
import util from 'node:util';
import fs from 'node:fs';
import DolphinToolBin from './dolphinToolBin.js';
import { CompressionMethodWiaRvz, ContainerFormat } from './common.js';
import utils from './utils.js';
export default {
async convert(options, attempt = 1) {
const blockSize = options.blockSize ?? {
// Unchangeable defaults of Dolphin v2412
[ContainerFormat.ISO]: undefined,
[ContainerFormat.GCZ]: 32 * 1024,
[ContainerFormat.WIA]: 2 * 1024 * 1024,
[ContainerFormat.RVZ]: 128 * 1024,
}[options.containerFormat];
const compressionMethod = options.compressionMethod ?? {
// Defaults of Dolphin v2412
[ContainerFormat.ISO]: undefined,
[ContainerFormat.GCZ]: undefined, // deflate
[ContainerFormat.WIA]: CompressionMethodWiaRvz.NONE,
[ContainerFormat.RVZ]: CompressionMethodWiaRvz.ZSTD,
}[options.containerFormat];
const compressionLevel = options.compressionLevel ?? (
// Defaults of Dolphin v2412
compressionMethod !== undefined && compressionMethod !== CompressionMethodWiaRvz.NONE
? 5
: undefined);
const runOptions = [
'convert',
'-i', options.inputFilename,
'-o', options.outputFilename,
'-f', options.containerFormat,
...(options.scrubJunk ? ['-s'] : []),
...(blockSize === undefined ? [] : ['-b', String(blockSize)]),
...(compressionMethod === undefined ? [] : ['-c', compressionMethod]),
...(compressionLevel === undefined ? [] : ['-l', String(compressionLevel)]),
];
const runFunction = async (runArguments) => {
const convertOutput = await DolphinToolBin.run(runArguments, options);
// Try to detect failures, and then retry them automatically
try {
await util.promisify(fs.stat)(options.outputFilename);
}
catch {
if (attempt <= 3) {
await new Promise((resolve) => {
setTimeout(resolve, Math.random() * (2 ** (attempt - 1) * 20));
});
return this.convert(options, attempt + 1);
}
throw new Error(`failed to convert file: ${convertOutput}`);
}
return convertOutput;
};
if (process.platform === 'win32' && options.userFolderPath === undefined) {
/**
* Windows (and seemingly no other OS) has issues with concurrent or rapid execution of
* `DolphinTool.exe`, resulting in popups with messages such as:
* "IOS_FS: Failed to write new FST"
* "IOS_FS: Failed to rename temporary FST file"
* "File <userDir>/Wii/shared2/sys/SYSCONF could not be opened! This may happen with
* improper permissions or use by another process."
* To combat this, we have to use separate user directories per process.
*/
return utils.wrapTempDir(async (temporaryDirectory) => runFunction([
...runOptions,
'-u', temporaryDirectory,
]));
}
return runFunction([
...runOptions,
...(options.userFolderPath ? ['-u', options.userFolderPath] : []),
]);
},
};
//# sourceMappingURL=dolphinToolConvert.js.map