igir
Version:
🕹 A zero-setup ROM collection manager that sorts, filters, extracts or archives, patches, and reports on collections of any size on any OS.
60 lines (59 loc) • 2.73 kB
JavaScript
import { ProgressBarSymbol } from '../console/progressBar.js';
import { ChecksumBitmask } from '../types/files/fileChecksums.js';
import PatchFactory from '../types/patches/patchFactory.js';
import Scanner from './scanner.js';
/**
* Scan for {@link Patch}es and parse them into the correct supported type.
*/
export default class PatchScanner extends Scanner {
constructor(options, progressBar, fileFactory, driveSemaphore) {
super(options, progressBar, fileFactory, driveSemaphore, PatchScanner.name);
}
/**
* Scan & process {@link Patch}es.
*/
async scan() {
this.progressBar.logTrace('scanning patch files');
this.progressBar.setSymbol(ProgressBarSymbol.FILE_SCANNING);
this.progressBar.resetProgress(0);
const patchFilePaths = await this.options.scanPatchFilesWithoutExclusions((increment) => {
this.progressBar.incrementTotal(increment);
});
this.progressBar.logTrace(`found ${patchFilePaths.length.toLocaleString()} patch file${patchFilePaths.length === 1 ? '' : 's'}`);
this.progressBar.resetProgress(patchFilePaths.length);
const patchFiles = await this.getUniqueFilesFromPaths(patchFilePaths, ChecksumBitmask.CRC32);
this.progressBar.resetProgress(patchFiles.length);
const patches = (await this.driveSemaphore.map(patchFiles, async (patchFile) => {
this.progressBar.incrementInProgress();
const childBar = this.progressBar.addChildBar({
name: patchFile.toString(),
});
try {
return await this.patchFromFile(patchFile);
}
catch (error) {
this.progressBar.logWarn(`${patchFile.toString()}: failed to parse patch: ${error}`);
return undefined;
}
finally {
childBar.delete();
this.progressBar.incrementCompleted();
}
})).filter((patch) => patch !== undefined);
this.progressBar.logTrace('done scanning patch files');
return patches;
}
async patchFromFile(file) {
const patchForFilename = await PatchFactory.patchFromFilename(file);
if (patchForFilename) {
this.progressBar.logTrace(`${file.toString()}: found patch by extension: ${typeof patchForFilename}`);
return patchForFilename;
}
const patchForFileContents = await PatchFactory.patchFromFileContents(file);
if (patchForFileContents) {
this.progressBar.logTrace(`${file.toString()}: found patch by contents: ${typeof patchForFileContents}`);
return patchForFileContents;
}
return undefined;
}
}