mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-12 01:08:29 +03:00
checkpoint
This commit is contained in:
@@ -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}}
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
}),
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
const { CreateLogger } = require("mei-logger");
|
||||
|
||||
module.exports = CreateLogger("tachi-database-seed-scripts");
|
||||
@@ -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}].`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user