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.
180 lines (179 loc) • 5.39 kB
JavaScript
import xml2js from "xml2js";
import FsUtil from "../../utils/fsUtil.js";
import { ChecksumBitmask } from "../files/fileChecksums.js";
import Parent from "./parent.js";
class DAT {
filePath;
parents = [];
constructor(props) {
this.filePath = props?.filePath;
}
/**
* Group all {@link Game} clones together into one {@link Parent}. If no parent/clone information
* exists, then there will be one {@link Parent} for every {@link Game}.
*/
generateGameNamesToParents() {
if (this.getGames().length === 0) {
return this;
}
const gameNamesToParents = /* @__PURE__ */ new Map();
const gameIdsToParents = /* @__PURE__ */ new Map();
for (const game of this.getGames()) {
if (game.getCloneOfId() !== void 0) {
continue;
}
const id = game.getId();
if (id !== void 0) {
const parent2 = gameIdsToParents.get(id);
if (parent2 === void 0) {
gameIdsToParents.set(id, new Parent(game));
} else {
parent2.addChild(game);
}
continue;
}
if (game.getCloneOf() !== void 0) {
continue;
}
const parent = gameNamesToParents.get(game.getName());
if (parent === void 0) {
gameNamesToParents.set(game.getName(), new Parent(game));
} else {
parent.addChild(game);
}
}
for (const game of this.getGames()) {
const cloneOfId = game.getCloneOfId();
if (cloneOfId !== void 0) {
const id = game.getId();
const parent = gameIdsToParents.get(cloneOfId);
if (parent) {
parent.addChild(game);
} else if (id !== void 0) {
gameIdsToParents.set(cloneOfId, new Parent(game));
}
continue;
}
const cloneOf = game.getCloneOf();
if (cloneOf !== void 0) {
const parent = gameNamesToParents.get(cloneOf);
if (parent) {
parent.addChild(game);
} else {
gameNamesToParents.set(cloneOf, new Parent(game));
}
}
}
this.parents = [...gameIdsToParents.values(), ...gameNamesToParents.values()];
return this;
}
getFilePath() {
return this.filePath;
}
getParents() {
return this.parents;
}
/**
* Does any {@link Game} in this {@link DAT} have clone information.
*/
hasParentCloneInfo() {
return this.getParents().length > 0 && this.getParents().length !== this.getGames().length;
}
getName() {
return this.getHeader().getName().trim();
}
getDisplayName() {
return this.getName().replaceAll(/-( +-)+/g, "- ").replace(/^[ -]+/, "").replace(/[ -]+$/, "").replaceAll(/ +/g, " ").trim();
}
getDescription() {
return this.getHeader().getDescription();
}
/**
* Get a No-Intro style filename.
*/
getFilename() {
let filename = this.getName();
if (this.getHeader().getVersion()) {
filename += ` (${this.getHeader().getVersion()})`;
}
filename += ".dat";
return FsUtil.makeLegal(filename.trim());
}
getRequiredRomChecksumBitmask() {
let checksumBitmask = 0;
for (const game of this.getGames()) {
for (const rom of game.getRoms()) {
if (rom.getCrc32() && rom.getSize()) {
checksumBitmask |= ChecksumBitmask.CRC32;
} else if (rom.getMd5()) {
checksumBitmask |= ChecksumBitmask.MD5;
} else if (rom.getSha1()) {
checksumBitmask |= ChecksumBitmask.SHA1;
} else if (rom.getSha256()) {
checksumBitmask |= ChecksumBitmask.SHA256;
}
}
}
return checksumBitmask;
}
getRequiredDiskChecksumBitmask() {
let checksumBitmask = 0;
for (const game of this.getGames()) {
for (const disk of game.getDisks()) {
if (disk.getCrc32() && disk.getSize()) {
checksumBitmask |= ChecksumBitmask.CRC32;
} else if (disk.getMd5()) {
checksumBitmask |= ChecksumBitmask.MD5;
} else if (disk.getSha1()) {
checksumBitmask |= ChecksumBitmask.SHA1;
} else if (disk.getSha256()) {
checksumBitmask |= ChecksumBitmask.SHA256;
}
}
}
return checksumBitmask;
}
/**
* Serialize this {@link DAT} to the file contents of an XML file.
*/
toXmlDat() {
return new xml2js.Builder({
renderOpts: { pretty: true, indent: " ", newline: "\n" },
xmldec: { version: "1.0" },
doctype: {
pubID: "-//Logiqx//DTD ROM Management Datafile//EN",
sysID: "http://www.logiqx.com/Dats/datafile.dtd"
},
cdata: true
}).buildObject(this.toXmlDatObj()).replaceAll("<xml_comment>", "<!-- ").replaceAll("</xml_comment>", " -->");
}
toXmlDatObj() {
const parentNames = new Set(this.getParents().map((parent) => parent.getName()));
return {
datafile: {
header: this.getHeader().toXmlDatObj(),
game: this.getGames().map((game) => game.toXmlDatObj(parentNames))
}
};
}
/**
* Return a short string representation of this {@link DAT}.
*/
toString() {
return JSON.stringify(
{
header: this.getHeader(),
games: this.getGames().length,
gamesSize: FsUtil.sizeReadable(
this.getGames().flatMap((game) => game.getRoms()).reduce((sum, rom) => sum + rom.getSize(), 0)
)
},
void 0,
2
);
}
}
export {
DAT as default
};
//# sourceMappingURL=dat.js.map