diff --git a/.gitignore b/.gitignore index 715a9758c..88ab148b2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ /libretro-super .DS_Store +node_modules +pnpm-lock.yaml +package-lock.json \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 000000000..bbaab38f0 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "private": true, + "type": "module", + "scripts": { + "check-duplicate": "node scripts/check-duplicate.js" + }, + "devDependencies": { + "@retrobrainz/dat": "^1.0.1", + "chalk": "^5.6.2" + } +} diff --git a/scripts/check-duplicate.js b/scripts/check-duplicate.js new file mode 100644 index 000000000..3cb798d11 --- /dev/null +++ b/scripts/check-duplicate.js @@ -0,0 +1,30 @@ +import { parse } from "@retrobrainz/dat"; +import chalk from "chalk"; +import { glob, readFile } from "node:fs/promises"; + +for await (const datFile of glob(["dat/**/*.dat", "metadat/**/*.dat"], { exclude: ["dat/DOS.dat"] })) { + console.log(datFile); + const datContent = await readFile(datFile, "utf8"); + const dat = parse(datContent); + const crcSerialMap = {}; + for (const game of dat) { + if ( + game.$class !== "game" || + game.$entries?.length !== 1 || + game.$entries?.[0].$class !== "rom" + ) { + continue; + } + const crc = game.$entries?.[0].crc; + const serial = game.$entries?.[0].serial || game.serial; + // if both crc and serial are the same, mark as duplicate + const key = JSON.stringify({crc, serial}); + crcSerialMap[key] = (crcSerialMap[key] || 0) + 1; + } + for (const [key, count] of Object.entries(crcSerialMap)) { + if (count > 1) { + const {crc, serial} = JSON.parse(key); + console.log(chalk.red(` duplicate: crc(${crc}), serial(${serial}), count(${count})`)); + } + } +}