checkpoint

This commit is contained in:
zk
2026-03-13 17:35:10 +00:00
parent d7bb9541f6
commit 4d489cbdea
326 changed files with 1535 additions and 6344 deletions
-1
View File
@@ -1 +0,0 @@
{"version":"7.0.0-dev.20260309.1","fileInfos":[],"options":{"allowJs":true,"allowImportingTsExtensions":true,"composite":true,"declaration":true,"declarationMap":true,"jsx":4,"module":7,"noFallthroughCasesInSwitch":true,"noImplicitAny":false,"outDir":"./js","rootDir":"./","skipLibCheck":true,"strict":true,"strictNullChecks":true,"sourceMap":true,"target":9,"tsBuildInfoFile":"./.tsbuildinfo","useDefineForClassFields":true}}
+1 -1
View File
@@ -10,7 +10,7 @@ const { Command } = require("commander");
const fs = require("fs");
const path = require("path");
const logger = require("./logger");
const logger = require("./log");
const program = new Command();
+15
View File
@@ -0,0 +1,15 @@
import pino from "pino";
const useJson = process.env.LOG_JSON === "1" || process.env.LOG_JSON === "true";
export const log = pino({
level: process.env.LOG_LEVEL ?? "info",
...(useJson
? {}
: {
transport: {
options: { colorize: true },
target: "pino-pretty",
},
}),
});
-3
View File
@@ -1,3 +0,0 @@
const { CreateLogger } = require("mei-logger");
module.exports = CreateLogger("tachi-database-seed-scripts");
-1
View File
@@ -37,7 +37,6 @@
"html-entities": "catalog:",
"iconv-lite": "catalog:",
"lodash.get": "catalog:",
"mei-logger": "catalog:",
"monk": "catalog:",
"node-fetch": "catalog:",
"prudence": "catalog:",
@@ -8,12 +8,7 @@ import {
type integer,
type SongDocument,
} from "../../../common/src";
import {
CreateChartID,
GetFreshSongIDGenerator,
ReadCollection,
WriteCollection,
} from "../../util";
import { CreateChartID, ReadCollection, WriteCollection } from "../../util";
type LocalizedText = { en: string } & Record<string, string>;
type LocalizedSearchTerms = Record<string, Array<string>>;
@@ -1,3 +1,4 @@
import { log } from "#log";
import { LoadBMSTable } from "bms-table-loader";
import {
BMS_TABLES,
@@ -6,7 +7,6 @@ import {
type TableDocument,
} from "tachi-common";
import logger from "../../logger";
import { MutateCollection, ReadCollection } from "../../util";
const existsTables = ReadCollection("tables.json").map((e) => e.tableID);
@@ -19,9 +19,9 @@ async function UpdateTable(tableInfo: BMSTableInfo) {
return;
}
logger.info(`Fetching ${tableInfo.url} (${tableInfo.name})...`);
log.info(`Fetching ${tableInfo.url} (${tableInfo.name})...`);
const table = await LoadBMSTable(tableInfo.url);
logger.info(`Fetched.`);
log.info(`Fetched.`);
const levels = table.getLevelOrder();
@@ -58,7 +58,7 @@ async function UpdateTable(tableInfo: BMSTableInfo) {
folders.push(realFolder);
logger.info(`Inserted new folder ${tableInfo.prefix}${level}.`);
log.info(`Inserted new folder ${tableInfo.prefix}${level}.`);
}
MutateCollection("folders.json", (f) => {
@@ -80,9 +80,9 @@ async function UpdateTable(tableInfo: BMSTableInfo) {
return t;
});
logger.info(`Bumped table ${tableInfo.name}.`);
log.info(`Bumped table ${tableInfo.name}.`);
logger.info(`Checking meta-folder...`);
log.info(`Checking meta-folder...`);
const f = {
title: tableInfo.name,
@@ -118,7 +118,7 @@ async function UpdateTable(tableInfo: BMSTableInfo) {
MutateCollection("folders.json", (folders) => [...folders, realFolder]);
}
logger.info(`Done.`);
log.info(`Done.`);
}
(async () => {
@@ -1,7 +1,6 @@
import { Command } from "commander";
import { XMLParser } from "fast-xml-parser";
import { existsSync, readdirSync, readFileSync, statSync } from "fs";
import { CreateLogger } from "mei-logger";
import path from "path";
import {
@@ -11,10 +10,9 @@ import {
type integer,
type SongDocument,
} from "../../../common/src";
import { log } from "../../log.js";
import { CreateChartID, ReadCollection, WriteCollection } from "../../util";
const logger = CreateLogger("chunithm/merge-options");
const OMNIMIX_OPTION_NAMES = ["AOMN", "AOLD", "AKON"];
const DISPLAY_VERSIONS = [
"CHUNITHM",
@@ -152,7 +150,7 @@ const newCharts: Array<ChartDocument<"chunithm:Single">> = [];
for (const optionsDir of options.input) {
for (const option of readdirSync(optionsDir)) {
if (!isOmnimixVersion && OMNIMIX_OPTION_NAMES.includes(option)) {
logger.warn(
log.warn(
`Ignoring omnimix option ${option} because the version specified is not an omnimix version.`,
);
continue;
@@ -170,11 +168,11 @@ for (const optionsDir of options.input) {
}
if (!existsSync(musicsDir) || !statSync(musicsDir).isDirectory()) {
logger.warn(`Option at ${optionDir} does not have a "music" directory.`);
log.warn(`Option at ${optionDir} does not have a "music" directory.`);
continue;
}
logger.info(`Scanning music directory ${musicsDir} for songs.`);
log.info(`Scanning music directory ${musicsDir} for songs.`);
for (const music of readdirSync(musicsDir)) {
const musicDir = path.join(musicsDir, music);
@@ -184,14 +182,14 @@ for (const optionsDir of options.input) {
}
if (!statSync(musicDir).isDirectory()) {
logger.warn(`Ignoring ${musicDir} because it is not a directory.`);
log.warn(`Ignoring ${musicDir} because it is not a directory.`);
continue;
}
const musicXmlLocation = path.join(musicDir, "Music.xml");
if (!existsSync(musicXmlLocation) || !statSync(musicXmlLocation).isFile()) {
logger.warn(`Music directory at ${musicDir} does not have a Music.xml file.`);
log.warn(`Music directory at ${musicDir} does not have a Music.xml file.`);
continue;
}
const data = parser.parse(readFileSync(musicXmlLocation)) as MusicXML;
@@ -209,7 +207,7 @@ for (const optionsDir of options.input) {
// Has this song been disabled in-game?
if (musicData.disableFlag) {
if (tachiSongID !== undefined) {
logger.info(
log.info(
`Removing charts of song ${musicData.artistName.str} - ${musicData.name.str} (ID ${tachiSongID}) from version ${options.version}, because disableFlag is enabled.`,
);
@@ -232,14 +230,14 @@ for (const optionsDir of options.input) {
const existingTitle = songTitleMap.get(musicData.name.str);
if (existingTitle) {
logger.warn(
log.warn(
`A song called ${musicData.name.str} already exists in songs-chunithm (ID ${existingTitle.id}). Is this a duplicate with a given inGameID?`,
);
if (options.force) {
logger.warn("--force was requested, adding this song anyways.");
log.warn("--force was requested, adding this song anyways.");
} else {
logger.warn("Must be resolved manually. Use --force to overwrite anyways.");
log.warn("Must be resolved manually. Use --force to overwrite anyways.");
continue;
}
}
@@ -270,7 +268,7 @@ for (const optionsDir of options.input) {
inGameIDToSongIDMap.set(inGameID, tachiSongID);
songMap.set(tachiSongID, songDoc);
logger.info(`Added new song ${songDoc.artist} - ${songDoc.title}.`);
log.info(`Added new song ${songDoc.artist} - ${songDoc.title}.`);
} else if (songMap.has(tachiSongID)) {
const songDoc = songMap.get(tachiSongID)!;
@@ -308,7 +306,7 @@ for (const optionsDir of options.input) {
if (!difficulty.enable) {
if (versionIndex !== -1) {
logger.info(
log.info(
`Removing ${displayName} from version ${options.version} because it has been disabled.`,
);
exists.versions.splice(versionIndex, 1);
@@ -318,19 +316,19 @@ for (const optionsDir of options.input) {
}
if (versionIndex === -1) {
logger.info(`Adding ${displayName} to version ${options.version}.`);
log.info(`Adding ${displayName} to version ${options.version}.`);
exists.versions.push(options.version);
}
if (isLatestVersion && exists.level !== level) {
logger.info(
log.info(
`Chart ${displayName} has had a level change: ${exists.level} -> ${level}`,
);
exists.level = level;
}
if (isLatestVersion && exists.levelNum !== levelNum) {
logger.info(
log.info(
`Chart ${displayName} has had a levelNum change: ${exists.levelNum} -> ${levelNum}`,
);
exists.levelNum = levelNum;
@@ -344,7 +342,7 @@ for (const optionsDir of options.input) {
}
if (difficultyName === "WORLD'S END") {
logger.warn(
log.warn(
`Song ${musicData.artistName.str} - ${musicData.name.str} (inGameID=${musicData.name.id}) contains a WORLD'S END chart, which should be impossible. Refusing to process this difficulty.`,
);
continue;
@@ -370,7 +368,7 @@ for (const optionsDir of options.input) {
// track of that too. Awesome.
existingCharts.set(`${inGameID}-${difficultyName}`, chartDoc);
logger.info(
log.info(
`Added chart ${musicData.artistName.str} - ${musicData.name.str} [${difficultyName}] (${chartDoc.chartID}).`,
);
}
@@ -1,4 +1,4 @@
const logger = require("../logger");
const logger = require("../log");
const { CreateFolderID, MutateCollection, ReadCollection, WriteCollection } = require("../util");
const translateMap = new Map();
@@ -1,4 +1,4 @@
const logger = require("../logger");
const logger = require("../log");
const { CreateGoalID, MutateCollection, ReadCollection, WriteCollection } = require("../util");
const translateMap = new Map();
@@ -1,3 +1,4 @@
import { log } from "#log";
import { execSync } from "child_process";
/* eslint-disable no-control-regex */
import fs, { mkdirSync } from "fs";
@@ -5,7 +6,6 @@ import iconv from "iconv-lite";
import path from "path";
import { type integer } from "../../../../common/src";
import logger from "../../../logger";
import { ParseDotOneFile } from "./dot-one-parser/parser";
import { type IIDXConvertOutput } from "./dot-one-parser/types";
@@ -38,7 +38,7 @@ mkdirSync(ifsOUT, { recursive: true });
* Extracts an IFS file into the ./ifs-output cache directory.
*/
function ifsExtract(ifsPath: string) {
logger.info(`Extracting ${ifsPath}...`);
log.info(`Extracting ${ifsPath}...`);
execSync(`ifstools "${ifsPath}" -o "${ifsOUT}" -y --super-disable`, { stdio: "ignore" });
}
@@ -52,7 +52,7 @@ export async function ParseIIDXData(
omni: boolean,
alwaysExtract: boolean,
) {
logger.info(`Parsing from ${basedir}.`);
log.info(`Parsing from ${basedir}.`);
const mdbPath = path.join(
basedir,
@@ -61,7 +61,7 @@ export async function ParseIIDXData(
omni ? "music_omni.bin" : "music_data.bin",
);
logger.info(`Parsing MDB ${mdbPath}.`);
log.info(`Parsing MDB ${mdbPath}.`);
const buffer = fs.readFileSync(mdbPath);
@@ -197,11 +197,11 @@ export async function ParseIIDXData(
if (buffer.length <= curLoc) {
moreData = false;
}
logger.error(`${dotOnePath} cannot find file. neither exist.`);
log.error(`${dotOnePath} cannot find file. neither exist.`);
continue;
}
logger.verbose(`Parsing data/sound/${songID}/${songID}.1`);
log.verbose(`Parsing data/sound/${songID}/${songID}.1`);
try {
const charts = await ParseDotOneFile(dotOnePath, {
genre,
@@ -215,7 +215,7 @@ export async function ParseIIDXData(
if (chart.difficulty === "LEGGENDARIA") {
if (notecount !== 0 && notecounts[`${chart.playtype}-LEGGENDARIA`]) {
logger.warn(
log.warn(
`${chart.artist} - ${chart.title} has conflicting ${
chart.playtype
} LEGGENDARIAs.
@@ -228,7 +228,7 @@ Picking the INLINE version, as it's likely to be the correct one, but confirm th
notecounts[`${chart.playtype}-${chart.difficulty}`] = notecount;
}
} catch (err) {
logger.error(err);
log.error(err);
curLoc += structSize;
if (buffer.length <= curLoc) {
@@ -266,7 +266,7 @@ Picking the INLINE version, as it's likely to be the correct one, but confirm th
}
}
logger.info(`Done parsing.`);
log.info(`Done parsing.`);
return parsedData;
}
@@ -1,8 +1,8 @@
import { log } from "#log";
import fs from "fs/promises";
import path from "path";
import { type integer } from "../../../../../common/src";
import logger from "../../../../logger";
import {
type BGMObject,
type BPMObject,
@@ -229,7 +229,7 @@ function ParseEvent(
} else if (data.param === 14) {
obj.col = 1;
} else {
logger.warn(
log.warn(
`(${
parseContext.songTitle ?? "UNKNOWN"
}) Unknown column of scratchObj sent to EventParser: ${
@@ -257,7 +257,7 @@ function ParseEvent(
};
} else if (type === "BPM") {
if (data.param === 0) {
logger.warn(
log.warn(
`(${
parseContext.songTitle ?? "UNKNOWN"
}) Invalid value of 0 for denominator in BPM event (numerator was ${
@@ -302,7 +302,7 @@ function ParseEvent(
const window = IIDX_TIMING_TO_RGC[data.param];
if (!window) {
logger.warn(
log.warn(
`(${
parseContext.songTitle ?? "UNKNOWN"
}) Unknown type of timingWindow: ${window}, from .1 param ${data.param}. Skipping.`,
@@ -341,7 +341,7 @@ function ParseEvent(
if (parseContext.isDP) {
if (data.param !== 0 && data.param !== 1) {
logger.warn(
log.warn(
`(${parseContext.songTitle ?? "UNKNOWN"}) Invalid parameter for measurebar of ${
data.param
}. Defaulting to 0 (left hand side).`,
@@ -374,7 +374,7 @@ function ParseEvent(
// charts. Maybe it was some sort of diverging bga instruction at one point?
return null;
} else {
logger.warn(
log.warn(
`(${parseContext.songTitle ?? "UNKNOWN"}) Unknown event type in .1: ${
data.type
} at ${ms.toFixed(2)}ms. Ignoring.`,
@@ -465,14 +465,14 @@ export function ParseDotOne(
const dir = dirs[i];
if (!dir || (dir.offset === 0 && dir.length === 0)) {
logger.verbose(`Skipped directory ${i}, as there was no data.`);
log.verbose(`Skipped directory ${i}, as there was no data.`);
continue; // no data.
}
const difficulty = IIDX_DIFFICULTY_TO_RGC[i];
if (!difficulty) {
logger.warn(
log.warn(
`(${
context.songTitle ?? "UNKNOWN"
}) Data present inside directory ${i}, but this corresponds to an unknown difficulty. Ignoring.`,
@@ -486,7 +486,7 @@ export function ParseDotOne(
};
if (!eventContext.songTitle) {
logger.warn(
log.warn(
"No filename provided in context.filename to IIDXParser, subsequent warnings will have no way of referring to the chart.",
);
}
@@ -1,3 +1,4 @@
import { log } from "#log";
import { Command } from "commander";
import fs from "fs";
import path from "path";
@@ -10,7 +11,6 @@ import {
type SongDocument,
type Versions,
} from "../../../../common/src";
import logger from "../../../logger";
import {
CreateChartID,
GetFreshSongIDGenerator,
@@ -135,7 +135,7 @@ async function ParseIIDXMDB() {
for (const inp of mdbCharts) {
if (isInBlacklist(`S${inp.songID}`)) {
logger.verbose(
log.debug(
`Skipped ${inp.artist} - ${inp.title} (${inp.songID}) as it was in the blacklist.`,
);
continue;
@@ -150,17 +150,17 @@ async function ParseIIDXMDB() {
const titleAlreadyExists = songTitleMap.get(inp.title);
if (titleAlreadyExists) {
logger.warn(
log.warn(
`A song called '${inp.title}' already exists in songs-iidx (songID:${titleAlreadyExists.id}). Is this a duplicate with a different inGameID?`,
);
if (!options.force) {
logger.warn(
log.warn(
`Must be resolved manually. Use --force to blindly overwrite it anyway.`,
);
continue;
} else {
logger.warn(`--force provided, adding it to the DB anyway.`);
log.warn(`--force provided, adding it to the DB anyway.`);
}
}
@@ -181,16 +181,16 @@ async function ParseIIDXMDB() {
altTitles: [],
};
logger.info(`Added new song ${inp.title}.`);
log.info(`Added new song ${inp.title}.`);
if (inp.title.match(/\?/gu)) {
logger.warn(
log.warn(
`${inp.title} has a potentially konami-screwed title. Investigate it manually.`,
);
}
if (inp.artist.match(/\?/gu)) {
logger.warn(
log.warn(
`${inp.artist} - ${inp.title} has a potentially konami-screwed title. Investigate it manually.`,
);
}
@@ -202,7 +202,7 @@ async function ParseIIDXMDB() {
const sxng = songMap.get(anySongIDMatch.songID);
if (!sxng) {
logger.error(`Song ${anySongIDMatch.songID} has charts but no song?`);
log.error(`Song ${anySongIDMatch.songID} has charts but no song?`);
throw new Error(`Song ${anySongIDMatch.songID} has charts but no song?`);
}
song = sxng;
@@ -212,7 +212,7 @@ async function ParseIIDXMDB() {
for (const diffName of diffNames) {
if (isInBlacklist(`C${inp.songID}-${diffName}`)) {
logger.verbose(
log.verbose(
`Ignored ${song.title} (${inp.songID}) ${diffName} as it was in the blacklist.`,
);
continue;
@@ -224,7 +224,7 @@ async function ParseIIDXMDB() {
const level = inp.levels[diffName];
if (level === 0 && notecount && notecount > 0) {
logger.info(
log.info(
`Chart ${song.title} ${diffName} has notecount ${notecount}, but has no level assigned. Skipping.`,
);
continue;
@@ -262,11 +262,11 @@ async function ParseIIDXMDB() {
},
};
logger.info(`Inserting new chart ${inp.title} ${diffName}.`);
log.info(`Inserting new chart ${inp.title} ${diffName}.`);
existingCharts.push(tachiChart);
} else {
if (!notecount) {
logger.warn(
log.warn(
`Chart ${inp.title} ${diffName} already exists, but has no notecount anymore. Not marking it as part of this version.`,
);
continue;
@@ -274,11 +274,11 @@ async function ParseIIDXMDB() {
// chart already exists, diff notecounts.
if (chart.data.notecount !== notecount) {
logger.warn(
log.warn(
`Chart ${inp.title} ${diffName} has a different notecount in the JSON to the data just parsed. Has this chart been edited? OLD: ${chart.data.notecount} -> NEW: ${notecount}.`,
);
if (!options.force) {
logger.warn(
log.warn(
`Must be resolved manually. Use --force to blindly overwrite it anyway.`,
);
continue;
@@ -287,7 +287,7 @@ async function ParseIIDXMDB() {
}
if (chart.levelNum !== level) {
logger.info(
log.info(
`Chart ${inp.title} ${diffName} has had a level change. ${chart.level} -> ${level}. Updating this.`,
);
chart.level = level.toString();
@@ -3,7 +3,7 @@ const fs = require("fs");
const fetch = require("node-fetch");
const path = require("path");
const logger = require("../../logger");
const logger = require("../../log");
const { MutateCollection, ReadCollection } = require("../../util");
const program = new Command();
@@ -1,8 +1,8 @@
import { log } from "#log";
import { execFileSync } from "child_process";
import { Command } from "commander";
import { XMLParser } from "fast-xml-parser";
import { existsSync, readdirSync, readFileSync, statSync } from "fs";
import { CreateLogger } from "mei-logger";
import path from "path";
import {
@@ -11,14 +11,7 @@ import {
GetGamePTConfig,
type SongDocument,
} from "../../../common/src";
import {
CreateChartID,
GetFreshSongIDGenerator,
ReadCollection,
WriteCollection,
} from "../../util";
const logger = CreateLogger("merge-options");
import { CreateChartID, ReadCollection, WriteCollection } from "../../util";
const VERSION_DISPLAY_NAMES = [
"maimai",
@@ -152,7 +145,7 @@ for (const chart of existingCharts) {
const song = songMap.get(chart.songID);
if (song === undefined) {
logger.error(
log.error(
`CONSISTENCY ERROR: Chart ID ${chart.chartID} does not belong to any songs! (songID was ${chart.songID})`,
);
process.exit(1);
@@ -208,18 +201,16 @@ if (options.vgmsBinary) {
const res = JSON.parse(stdout);
if (res.sampleRate !== 48000) {
logger.warn(
`Sample rate of ${cuePath} is not 48000Hz (${res.sampleRate}Hz)`,
);
log.warn(`Sample rate of ${cuePath} is not 48000Hz (${res.sampleRate}Hz)`);
}
const duration = Number((res.numberOfSamples / res.sampleRate).toFixed(3));
durationMap.set(cueName, duration);
logger.info(`Cue file ${cueName} has duration ${duration} seconds.`);
log.info(`Cue file ${cueName} has duration ${duration} seconds.`);
} catch (e) {
logger.error(`Error parsing song duration: ${e}`);
log.error(`Error parsing song duration: ${e}`);
}
}
}
@@ -251,11 +242,11 @@ for (const optionsDir of options.input) {
const musicsDir = path.join(optionDir, "music");
if (!existsSync(musicsDir)) {
logger.warn(`Option at ${optionDir} does not have a "music" folder.`);
log.warn(`Option at ${optionDir} does not have a "music" folder.`);
continue;
}
logger.info(`Scanning music directory ${musicsDir} for songs.`);
log.info(`Scanning music directory ${musicsDir} for songs.`);
for (const music of readdirSync(musicsDir)) {
if (!music.match(/music\d+$/u)) {
@@ -271,7 +262,7 @@ for (const optionsDir of options.input) {
const musicXmlLocation = path.join(musicDir, "Music.xml");
if (!existsSync(musicXmlLocation)) {
logger.warn(`Music folder at ${musicDir} does not have a Music.xml file.`);
log.warn(`Music folder at ${musicDir} does not have a Music.xml file.`);
continue;
}
@@ -280,7 +271,7 @@ for (const optionsDir of options.input) {
const inGameID = Number(musicData.name.id);
if (isInBlacklist(`S${inGameID}`)) {
logger.verbose(
log.verbose(
`Ignored ${musicData.artistName.str} - ${musicData.name.str} (inGameID ${inGameID}) as it is in the blacklist.`,
);
continue;
@@ -296,7 +287,7 @@ for (const optionsDir of options.input) {
// Has this song been disabled in-game?
if (musicData.disable || Number(musicData.eventName.id) === 0) {
if (tachiSongID !== undefined) {
logger.info(
log.info(
`Removing charts of song ID ${tachiSongID} from version ${options.version}, because the disable flag in Music.xml is enabled.`,
);
@@ -335,7 +326,7 @@ for (const optionsDir of options.input) {
const duration = durationMap.get(`music${musicData.cueName.id.padStart(6, "0")}`);
if (!duration) {
logger.warn(
log.warn(
`Unknown duration for music ID ${inGameID}, cue ID ${musicData.cueName.id}.`,
);
}
@@ -360,7 +351,7 @@ for (const optionsDir of options.input) {
songTitleArtistMap.set(`${songDoc.title}-${songDoc.artist}`, tachiSongID);
songMap.set(tachiSongID, songDoc);
logger.info(
log.info(
`Added new song ${songDoc.artist} - ${songDoc.title} (inGameID ${inGameID}, tachiSongID ${tachiSongID}).`,
);
} else {
@@ -388,7 +379,7 @@ for (const optionsDir of options.input) {
}
if (isInBlacklist(`C${inGameID}-${difficultyName}`)) {
logger.verbose(
log.verbose(
`Ignoring ${musicData.artistName.str} - ${musicData.name.str} [${difficultyName}] (inGameID ${inGameID}) as it is in the blacklist.`,
);
continue;
@@ -415,18 +406,18 @@ for (const optionsDir of options.input) {
const displayName = `${musicData.artistName.str} - ${musicData.name.str} [${exists.difficulty}] (${exists.chartID})`;
if (exists.data.inGameID === null) {
logger.info(`Adding inGameID ${inGameID} for chart ${displayName}.`);
log.info(`Adding inGameID ${inGameID} for chart ${displayName}.`);
exists.data.inGameID = inGameID;
} else if (exists.data.inGameID !== inGameID) {
logger.warn(
log.warn(
`The chart ${displayName} already exists in charts-maimaidx under a different inGameID (${exists.data.inGameID} != ${inGameID}). Is this a duplicate with a different inGameID?`,
);
if (options.force) {
logger.warn("Overwriting anyways, because --force has been requested.");
log.warn("Overwriting anyways, because --force has been requested.");
exists.data.inGameID = inGameID;
} else {
logger.warn(
log.warn(
"Must be resolved manually. Use --force to overwrite anyways.",
);
}
@@ -440,14 +431,14 @@ for (const optionsDir of options.input) {
if (isLatestVersion) {
if (exists.level !== level) {
logger.info(
log.info(
`Chart ${displayName} has had a level change: ${exists.level} -> ${level}.`,
);
exists.level = level;
}
if (exists.levelNum !== levelNum) {
logger.info(
log.info(
`Chart ${displayName} has had a levelNum change: ${exists.levelNum} -> ${levelNum}.`,
);
exists.levelNum = levelNum;
@@ -476,7 +467,7 @@ for (const optionsDir of options.input) {
newCharts.push(chartDoc);
logger.info(
log.info(
`Inserted new chart ${musicData.artistName.str} - ${musicData.name.str} [${chartDoc.difficulty}] (${chartDoc.chartID}).`,
);
}
@@ -1,4 +1,4 @@
import { CreateLogger } from "mei-logger";
import { log } from "#log";
import { type ChartDocument, type Difficulties, type SongDocument } from "../../../common/src";
import {
@@ -8,8 +8,6 @@ import {
WriteCollection,
} from "../../util";
const logger = CreateLogger("parse-maimaidx-dataset");
type BaseDifficulty = "adv" | "bas" | "exp" | "mas" | "remas";
type MaimaiDXDifficulty = `${"" | "dx_"}lev_${BaseDifficulty}`;
@@ -109,7 +107,7 @@ async function ParseInternalLevelData(
const dx = Number(dxMatch[1]!);
if (dx !== 0 && dx !== 1) {
logger.warn(`DX should be 0 or 1, found ${dxMatch[1]} in ${line}`);
log.warn(`DX should be 0 or 1, found ${dxMatch[1]} in ${line}`);
continue;
}
@@ -119,7 +117,7 @@ async function ParseInternalLevelData(
const tmp = JSON.parse(lvMatch[1]!);
if (!Array.isArray(tmp) || tmp.some((c) => typeof c !== "number")) {
logger.warn(`lv should be an array of numbers, found ${lvMatch[1]} in ${line}`);
log.warn(`lv should be an array of numbers, found ${lvMatch[1]} in ${line}`);
continue;
}
@@ -138,7 +136,7 @@ async function ParseInternalLevelData(
lv.remas = tmp[4];
}
} catch (e) {
logger.warn(`lv should be an array of numbers, found ${lvMatch[1]} in ${line}`);
log.warn(`lv should be an array of numbers, found ${lvMatch[1]} in ${line}`);
continue;
}
@@ -159,11 +157,11 @@ async function ParseMaimaiDXDataset() {
const existingSongMap = new Map(songs.map((s) => [`${s.title}-${s.artist}`, s]));
const existingChartMap = new Map(charts.map((c) => [`${c.songID}-${c.difficulty}`, c]));
logger.info(`Fetching official song information from ${DATA_URL}...`);
log.info(`Fetching official song information from ${DATA_URL}...`);
const datum: Array<MaimaiDXSong> = await fetch(DATA_URL).then((r) => r.json());
logger.info(`Fetching internal level information from ${INTERNAL_LEVEL_URL}...`);
log.info(`Fetching internal level information from ${INTERNAL_LEVEL_URL}...`);
const internalLevelData = await ParseInternalLevelData(INTERNAL_LEVEL_URL);
const internalLevelDataMap = new Map(
@@ -182,7 +180,7 @@ async function ParseMaimaiDXDataset() {
if (version > CURRENT_VERSION_NUM) {
// Skipping songs that are newer than currently supported version.
logger.warn(
log.warn(
`Ignoring song ${data.artist} - ${data.title}, which is newer than CURRENT_VERSION_NUM.`,
);
continue;
@@ -221,7 +219,7 @@ async function ParseMaimaiDXDataset() {
songs.push(songDoc);
logger.info(`Added new song ${songDoc.artist} - ${songDoc.title} (ID ${tachiSongID}).`);
log.info(`Added new song ${songDoc.artist} - ${songDoc.title} (ID ${tachiSongID}).`);
}
for (const [key, difficulty] of Object.entries(DIFFICULTY_TO_TACHI_DIFFICULTY) as [
@@ -260,7 +258,7 @@ async function ParseMaimaiDXDataset() {
}
if (existingChart.level !== level) {
logger.info(
log.info(
`Chart ${displayName} has had a level change: ${existingChart.level} -> ${level}.`,
);
existingChart.level = level;
@@ -268,7 +266,7 @@ async function ParseMaimaiDXDataset() {
}
if (existingChart.levelNum !== levelNum) {
logger.info(
log.info(
`Chart ${displayName} has had a levelNum change: ${existingChart.levelNum} -> ${levelNum}.`,
);
existingChart.levelNum = levelNum;
@@ -293,7 +291,7 @@ async function ParseMaimaiDXDataset() {
charts.push(chartDoc);
logger.info(`Added new chart ${data.artist} - ${data.title} [${difficulty}].`);
log.info(`Added new chart ${data.artist} - ${data.title} [${difficulty}].`);
}
}