diff --git a/server/src/lib/logger/discord-transport.ts b/server/src/lib/logger/discord-transport.ts index 2f4d56c1e..945d43f67 100644 --- a/server/src/lib/logger/discord-transport.ts +++ b/server/src/lib/logger/discord-transport.ts @@ -1,11 +1,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { ONE_MINUTE } from "lib/constants/time"; import { Environment, ServerConfig, TachiConfig } from "lib/setup/config"; import SafeJSONStringify from "safe-json-stringify"; import fetch from "utils/fetch"; import Transport, { TransportStreamOptions } from "winston-transport"; import { DiscordColours } from "./colours"; -import { integer } from "tachi-common"; -import { ONE_MINUTE } from "lib/constants/time"; interface DiscordTransportOptions extends TransportStreamOptions { /** Webhook obtained from Discord */ diff --git a/server/src/lib/score-import/import-types/ir/beatoraja/converter.ts b/server/src/lib/score-import/import-types/ir/beatoraja/converter.ts index d03e11065..6be6b2f21 100644 --- a/server/src/lib/score-import/import-types/ir/beatoraja/converter.ts +++ b/server/src/lib/score-import/import-types/ir/beatoraja/converter.ts @@ -13,6 +13,10 @@ import { ChartDocument, SongDocument } from "tachi-common"; import { HandleOrphanQueue } from "lib/orphan-queue/orphan-queue"; import { Random20Hex } from "utils/misc"; import { ServerConfig, TachiConfig } from "lib/setup/config"; +import db from "external/mongo/db"; +import { ReprocessOrphan } from "lib/score-import/framework/orphans/orphans"; +import { GetBlacklist } from "utils/queries/blacklist"; +import { KtLogger } from "lib/logger/logger"; const LAMP_LOOKUP = { NoPlay: "NO PLAY", @@ -34,6 +38,59 @@ const RANDOM_LOOKUP = { 4: "S-RANDOM", } as const; +async function HandleOrphanChartProcess( + data: BeatorajaScore, + context: BeatorajaContext, + logger: KtLogger +) { + const chartName = `${context.chart.artist} (${context.chart.subartist})- ${context.chart.title} (${context.chart.subtitle})`; + + if (context.chart.hasRandom) { + // If you're someone forking tachi looking to remove this + // check, remember to change the entire score import + // framework and database to be able to handle variable notecounts. + logger.verbose(`Declined to orphan chart ${chartName} as it has #RANDOM declarations.`); + throw new InvalidScoreFailure(`${TachiConfig.NAME} will not support #RANDOM charts.`); + } + + const idString = context.chart.mode === "BEAT_7K" ? "bms:7K" : "bms:14K"; + + const { chartDoc, songDoc } = ConvertBeatorajaChartToTachi(context.chart); + + const chart = await HandleOrphanQueue( + idString, + "bms", + chartDoc, + songDoc, + { + "chartDoc.data.hashSHA256": context.chart.sha256, + }, + ServerConfig.BEATORAJA_QUEUE_SIZE, + context.userID, + chartName + ); + + // If chart wasn't unorphaned as a result of this request + // orphan this score and return ktdnf + if (!chart) { + throw new KTDataNotFoundFailure( + `This chart (${context.chart.artist} - ${context.chart.title}) is orphaned.`, + "ir/beatoraja", + data, + context + ); + } + + const blacklist = await GetBlacklist(); + const scoresToDeorphan = await db["orphan-scores"].find({ + "data.sha256": chartDoc.data.hashSHA256, + }); + + await Promise.all(scoresToDeorphan.map((e) => ReprocessOrphan(e, blacklist, logger))); + + return chart; +} + export const ConverterIRBeatoraja: ConverterFunction = async ( data, context, @@ -49,43 +106,7 @@ export const ConverterIRBeatoraja: ConverterFunction | null; if (!chart) { - const chartName = `${context.chart.artist} (${context.chart.subartist})- ${context.chart.title} (${context.chart.subtitle})`; - - if (context.chart.hasRandom) { - // If you're someone forking tachi looking to remove this - // check, remember to change the entire score import - // framework and database to be able to handle variable notecounts. - logger.verbose(`Declined to orphan chart ${chartName} as it has #RANDOM declarations.`); - throw new InvalidScoreFailure(`${TachiConfig.NAME} will not support #RANDOM charts.`); - } - - const idString = context.chart.mode === "BEAT_7K" ? "bms:7K" : "bms:14K"; - - const { chartDoc, songDoc } = ConvertBeatorajaChartToTachi(context.chart); - - chart = await HandleOrphanQueue( - idString, - "bms", - chartDoc, - songDoc, - { - "chartDoc.data.hashSHA256": context.chart.sha256, - }, - ServerConfig.BEATORAJA_QUEUE_SIZE, - context.userID, - chartName - ); - - // If chart wasn't unorphaned as a result of this request - // orphan this score and return ktdnf - if (!chart) { - throw new KTDataNotFoundFailure( - `This chart (${context.chart.artist} - ${context.chart.title}) is orphaned.`, - "ir/beatoraja", - data, - context - ); - } + chart = await HandleOrphanChartProcess(data, context, logger); } const song = await FindSongOnID("bms", chart.songID); diff --git a/server/src/server/router/ir/beatoraja/router.ts b/server/src/server/router/ir/beatoraja/router.ts index 281db13fb..5781d765a 100644 --- a/server/src/server/router/ir/beatoraja/router.ts +++ b/server/src/server/router/ir/beatoraja/router.ts @@ -2,6 +2,7 @@ import { Router } from "express"; import db from "external/mongo/db"; import { SYMBOL_TachiAPIAuth } from "lib/constants/tachi"; import CreateLogCtx, { KtLogger } from "lib/logger/logger"; +import { HandleOrphanQueue } from "lib/orphan-queue/orphan-queue"; import { ExpressWrappedScoreImportMain } from "lib/score-import/framework/express-wrapper"; import { ParseBeatorajaSingle } from "lib/score-import/import-types/ir/beatoraja/parser"; import { ServerConfig } from "lib/setup/config"; diff --git a/server/src/server/router/ir/usc/router.ts b/server/src/server/router/ir/usc/router.ts index d405bee7a..1b36ccc4e 100644 --- a/server/src/server/router/ir/usc/router.ts +++ b/server/src/server/router/ir/usc/router.ts @@ -30,6 +30,8 @@ import { FormatPrError } from "utils/prudence"; import { USCClientChart } from "./types"; import { HandleOrphanQueue } from "lib/orphan-queue/orphan-queue"; import { ServerConfig, TachiConfig } from "lib/setup/config"; +import { ReprocessOrphan } from "lib/score-import/framework/orphans/orphans"; +import { GetBlacklist } from "utils/queries/blacklist"; const logger = CreateLogCtx(__filename); @@ -305,6 +307,15 @@ router.post("/scores", RequirePermissions("submit_score"), async (req, res) => { req[SYMBOL_TachiAPIAuth].userID!, uscChartName ); + + if (chartDoc) { + const blacklist = await GetBlacklist(); + const scoresToDeorphan = await db["orphan-scores"].find({ + "context.chartHash": chartDoc.data.hashSHA1, + }); + + await Promise.all(scoresToDeorphan.map((e) => ReprocessOrphan(e, blacklist, logger))); + } } const userDoc = await GetUserWithID(req[SYMBOL_TachiAPIAuth]!.userID!);