UNPKG

dolphin-tool

Version:

🐬 dolphin-tool binaries and wrapper for Node.js.

75 lines 3.49 kB
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