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.
162 lines (161 loc) • 5.92 kB
JavaScript
import { ProgressBarSymbol } from "../../console/progressBar.js";
import { PreferRevision } from "../../models/options.js";
import FsUtil from "../../utils/fsUtil.js";
import IntlUtil from "../../utils/intlUtil.js";
import Module from "../module.js";
class DATPreferer extends Module {
options;
constructor(options, progressBar) {
super(progressBar, DATPreferer.name);
this.options = options;
}
/**
* Prefer some {@link Game}s.
*/
prefer(dat) {
if (!this.options.getSingle()) {
this.prefixedLogger.trace(
`${dat.getName()}: not running in single/1G1R mode, not preferring games`
);
return dat;
}
if (dat.getGames().length === 0) {
this.prefixedLogger.trace(`${dat.getName()}: no games to prefer`);
return dat;
}
if (dat.getGames().length === 0) {
this.prefixedLogger.trace(`${dat.getName()}: no parent has games, not preferring games`);
return dat;
}
this.prefixedLogger.trace(`${dat.getName()}: preferring DAT games`);
this.progressBar.setSymbol(ProgressBarSymbol.DAT_PREFERRING);
this.progressBar.resetProgress(dat.getParents().length);
const preferredGames = dat.getParents().map((parent) => {
this.progressBar.incrementCompleted();
if (parent.getGames().length < 2) {
return parent.getGames().at(0);
}
const preferredGame = parent.getGames().map((game, idx) => [game, idx]).toSorted((one, two) => this.sort(one, two)).at(0);
if (preferredGame === void 0) {
return void 0;
}
this.prefixedLogger.trace(
`${dat.getName()}: ${parent.getName()} (parent): out of ${IntlUtil.toLocaleString(parent.getGames().length)} game${parent.getGames().length === 1 ? "" : "s"}, preferred: ${preferredGame[0].getName()}`
);
return preferredGame[0].withProps({ cloneOf: void 0 });
}).filter((game) => game !== void 0);
const preferredDat = dat.withGames(preferredGames);
const size = preferredDat.getGames().flatMap((game) => game.getRoms()).reduce((sum, rom) => sum + rom.getSize(), 0);
this.prefixedLogger.trace(
`${preferredDat.getName()}: preferred to ${IntlUtil.toLocaleString(preferredGames.length)}/${IntlUtil.toLocaleString(dat.getGames().length)} game${preferredGames.length === 1 ? "" : "s"} (${FsUtil.sizeReadable(size)})`
);
this.prefixedLogger.trace(`${preferredDat.getName()}: done preferring DAT games`);
return preferredDat;
}
/**
*******************
*
* Sorting *
*
*******************
*/
sort(one, two) {
return this.preferGameRegexSort(one[0], two[0]) || this.preferRomRegexSort(one[0], two[0]) || this.preferVerifiedSort(one[0], two[0]) || this.preferGoodSort(one[0], two[0]) || this.preferLanguagesSort(one[0], two[0]) || this.preferRegionsSort(one[0], two[0]) || this.preferRevisionSort(one[0], two[0]) || this.preferRetailSort(one[0], two[0]) || this.preferParentSort(one[0], two[0]) || // If there's truly no preference, then sort by the original index
one[1] - two[1];
}
preferGameRegexSort(a, b) {
const gameRegex = this.options.getPreferGameRegex();
if (gameRegex === void 0 || gameRegex.length === 0) {
return 0;
}
const aMatched = gameRegex.some((regex) => regex.test(a.getName())) ? 0 : 1;
const bMatched = gameRegex.some((regex) => regex.test(b.getName())) ? 0 : 1;
return aMatched - bMatched;
}
preferRomRegexSort(a, b) {
const romRegex = this.options.getPreferRomRegex();
if (romRegex === void 0 || romRegex.length === 0) {
return 0;
}
const aMatched = romRegex.some((regex) => a.getRoms().some((rom) => regex.test(rom.getName()))) ? 0 : 1;
const bMatched = romRegex.some((regex) => b.getRoms().some((rom) => regex.test(rom.getName()))) ? 0 : 1;
return aMatched - bMatched;
}
preferVerifiedSort(a, b) {
if (!this.options.getPreferVerified()) {
return 0;
}
return (a.isVerified() ? 0 : 1) - (b.isVerified() ? 0 : 1);
}
preferGoodSort(a, b) {
if (!this.options.getPreferGood()) {
return 0;
}
return (b.isBad() ? 0 : 1) - (a.isBad() ? 0 : 1);
}
preferLanguagesSort(a, b) {
const preferLanguages = this.options.getPreferLanguages();
if (preferLanguages.length === 0) {
return 0;
}
const aLangs = new Set(a.getLanguages());
const bLangs = new Set(b.getLanguages());
for (const preferredLang of preferLanguages) {
if (aLangs.has(preferredLang) && bLangs.has(preferredLang)) {
return 0;
}
if (aLangs.has(preferredLang)) {
return -1;
}
if (bLangs.has(preferredLang)) {
return 1;
}
}
return 0;
}
preferRegionsSort(a, b) {
const preferRegions = this.options.getPreferRegions();
if (preferRegions.length === 0) {
return 0;
}
const aRegions = new Set(a.getRegions());
const bRegions = new Set(b.getRegions());
for (const preferredRegion of preferRegions) {
if (aRegions.has(preferredRegion) && bRegions.has(preferredRegion)) {
return 0;
}
if (aRegions.has(preferredRegion)) {
return -1;
}
if (bRegions.has(preferredRegion)) {
return 1;
}
}
return 0;
}
preferRevisionSort(a, b) {
if (this.options.getPreferRevision() === PreferRevision.NEWER) {
return b.getRevision() - a.getRevision();
}
if (this.options.getPreferRevision() === PreferRevision.OLDER) {
return a.getRevision() - b.getRevision();
}
return 0;
}
preferRetailSort(a, b) {
if (!this.options.getPreferRetail()) {
return 0;
}
return (a.isRetail() ? 0 : 1) - (b.isRetail() ? 0 : 1);
}
preferParentSort(a, b) {
if (!this.options.getPreferParent()) {
return 0;
}
return (a.isParent() ? 0 : 1) - (b.isParent() ? 0 : 1);
}
}
export {
DATPreferer as default
};
//# sourceMappingURL=datPreferer.js.map