Skip to content

Commit

Permalink
Merge branch 'main' into emmercm/reader-threads-option
Browse files Browse the repository at this point in the history
  • Loading branch information
emmercm authored Oct 23, 2023
2 parents 190c7b7 + d8ef643 commit 5e5f4cc
Show file tree
Hide file tree
Showing 4 changed files with 250 additions and 78 deletions.
59 changes: 0 additions & 59 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@
"node-disk-info": "1.3.0",
"node-unrar-js": "2.0.0",
"reflect-metadata": "0.1.13",
"robloach-datfile": "2.4.0",
"semver": "7.5.4",
"simple-statistics": "7.8.3",
"strip-ansi": "7.1.0",
Expand Down
62 changes: 44 additions & 18 deletions src/modules/datScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import path from 'node:path';

import { parse } from '@fast-csv/parse';
import async, { AsyncResultCallback } from 'async';
import robloachDatfile from 'robloach-datfile';
import xml2js from 'xml2js';

import ProgressBar, { ProgressBarSymbol } from '../console/progressBar.js';
import ArrayPoly from '../polyfill/arrayPoly.js';
import bufferPoly from '../polyfill/bufferPoly.js';
import fsPoly from '../polyfill/fsPoly.js';
import CMProParser, { DATProps, GameProps, ROMProps } from '../types/dats/cmpro/cmProParser.js';
import DAT from '../types/dats/dat.js';
import DATObject from '../types/dats/datObject.js';
import Game from '../types/dats/game.js';
Expand Down Expand Up @@ -231,7 +231,7 @@ export default class DATScanner extends Scanner {
return xmlDat;
}

const cmproDatParsed = await this.parseCmproDat(datFile, fileContents);
const cmproDatParsed = this.parseCmproDat(datFile, fileContents);
if (cmproDatParsed) {
return cmproDatParsed;
}
Expand Down Expand Up @@ -285,38 +285,56 @@ export default class DATScanner extends Scanner {
return undefined;
}

private async parseCmproDat(datFile: File, fileContents: string): Promise<DAT | undefined> {
private parseCmproDat(datFile: File, fileContents: string): DAT | undefined {
/**
* Sanity check that this might be a CMPro file, otherwise {@link robloachDatfile} has a chance
* to throw fatal errors.
* Sanity check that this might be a CMPro file.
*/
if (fileContents.match(/^(clrmamepro|game|resource) \(\r?\n(\t.+\r?\n)+\)$/m) === null) {
return undefined;
}

this.progressBar.logTrace(`${datFile.toString()}: attempting to parse CMPro DAT`);

let cmproDat;
let cmproDat: DATProps;
try {
cmproDat = await robloachDatfile.parse(fileContents);
cmproDat = new CMProParser(fileContents).parse();
} catch (error) {
this.progressBar.logDebug(`${datFile.toString()}: failed to parse CMPro DAT: ${error}`);
return undefined;
}
if (cmproDat.length === 0) {
this.progressBar.logWarn(`${datFile.toString()}: failed to parse CMPro DAT, no header or games found`);
return undefined;
}

this.progressBar.logTrace(`${datFile.toString()}: parsed CMPro DAT, deserializing to DAT`);

const header = new Header(cmproDat[0]);
const header = new Header({
name: cmproDat.clrmamepro?.name,
description: cmproDat.clrmamepro?.description,
version: cmproDat.clrmamepro?.version,
date: cmproDat.clrmamepro?.date,
author: cmproDat.clrmamepro?.author,
url: cmproDat.clrmamepro?.url,
comment: cmproDat.clrmamepro?.comment,
});

let cmproDatGames: GameProps[] = [];
if (cmproDat.game) {
if (Array.isArray(cmproDat.game)) {
cmproDatGames = cmproDat.game;
} else {
cmproDatGames = [cmproDat.game];
}
}

const games = cmproDatGames.flatMap((game) => {
let gameRoms: ROMProps[] = [];
if (game.rom) {
if (Array.isArray(game.rom)) {
gameRoms = game.rom;
} else {
gameRoms = [game.rom];
}
}

const cmproGames = cmproDat.slice(1);
const games = cmproGames.flatMap((obj) => {
const game = obj as DatfileGame;
// TODO(cemmer): https://github.com/RobLoach/datfile/issues/2
const roms = (game.entries ?? [])
const roms = gameRoms
.filter((rom) => rom.name) // we need ROM filenames
.map((entry) => new ROM({
name: entry.name ?? '',
Expand All @@ -327,7 +345,15 @@ export default class DATScanner extends Scanner {
}));

return new Game({
...game,
name: game.name,
category: undefined,
description: game.description,
bios: undefined,
device: undefined,
cloneOf: game.cloneof,
romOf: game.romof,
sampleOf: undefined,
release: undefined,
rom: roms,
});
});
Expand Down
Loading

0 comments on commit 5e5f4cc

Please sign in to comment.