Merge pull request #353 from TeamNewGuys:zkldi/issue-293-Kiraku/Kichiku/AllScr-ruins-search-functionality

Make 2dxtra difficulties normal difficulties.
This commit is contained in:
zkldi
2021-09-28 22:40:41 +01:00
committed by GitHub
8 changed files with 148 additions and 20 deletions
+2 -1
View File
@@ -66,6 +66,7 @@
"mongodb": "3.6.3",
"monk": "7.3.4",
"multer": "1.4.2",
"node-cache": "^5.1.2",
"node-fetch": "2.6.1",
"nodemailer": "^6.6.3",
"prudence": "0.9.6",
@@ -73,7 +74,7 @@
"redis": "3.1.2",
"rimraf": "3.0.2",
"safe-json-stringify": "1.2.0",
"tachi-common": "0.2.18",
"tachi-common": "0.2.19",
"typescript": "4.3.4",
"winston": "3.3.3",
"winston-transport": "^4.4.0"
+20 -4
View File
@@ -44,6 +44,7 @@ specifiers:
mongodb: 3.6.3
monk: 7.3.4
multer: 1.4.2
node-cache: ^5.1.2
node-fetch: 2.6.1
node-mocks-http: 1.10.1
nodemailer: ^6.6.3
@@ -54,7 +55,7 @@ specifiers:
rimraf: 3.0.2
safe-json-stringify: 1.2.0
supertest: 6.1.3
tachi-common: 0.2.18
tachi-common: 0.2.19
tap: 15.0.9
ts-node: 10.0.0
tsconfig-paths: 3.10.1
@@ -82,6 +83,7 @@ dependencies:
mongodb: 3.6.3
monk: 7.3.4
multer: 1.4.2
node-cache: 5.1.2
node-fetch: 2.6.1
nodemailer: 6.6.3
prudence: 0.9.6
@@ -89,7 +91,7 @@ dependencies:
redis: 3.1.2
rimraf: 3.0.2
safe-json-stringify: 1.2.0
tachi-common: 0.2.18
tachi-common: 0.2.19
typescript: 4.3.4
winston: 3.3.3
winston-transport: 4.4.0
@@ -1189,6 +1191,11 @@ packages:
engines: {node: '>=0.8'}
dev: false
/clone/2.1.2:
resolution: {integrity: sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=}
engines: {node: '>=0.8'}
dev: false
/code-point-at/1.1.0:
resolution: {integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=}
engines: {node: '>=0.10.0'}
@@ -2035,6 +2042,7 @@ packages:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
dev: true
optional: true
@@ -2891,6 +2899,13 @@ packages:
resolution: {integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==}
engines: {node: '>= 0.6'}
/node-cache/5.1.2:
resolution: {integrity: sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==}
engines: {node: '>= 8.0.0'}
dependencies:
clone: 2.1.2
dev: false
/node-fetch/2.6.1:
resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==}
engines: {node: 4.x || >=6.0.0}
@@ -3538,6 +3553,7 @@ packages:
/saslprep/1.0.3:
resolution: {integrity: sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==}
engines: {node: '>=6'}
requiresBuild: true
dependencies:
sparse-bitfield: 3.0.3
dev: false
@@ -3894,8 +3910,8 @@ packages:
strip-ansi: 6.0.0
dev: true
/tachi-common/0.2.18:
resolution: {integrity: sha512-moa+Bmo6ilwJIyxQfHNkxNOKxQCgXFWezdLGwwvhCAzAfpLtiT0B6/QXKJUrkEVOqAy1ujRsLHZdK+NR87rFvg==}
/tachi-common/0.2.19:
resolution: {integrity: sha512-Gy4tr1XmwgpIfJqAKk6PUxTETg+4N00mLrSNBqBwKvRfINBBI6vQ5wp98PHTaCEE8h+dKkv1Uj0u0VnCRrLZig==}
dependencies:
monk: 7.3.4
transitivePeerDependencies:
+1 -1
View File
@@ -4,7 +4,7 @@ import { ChartDocument, IDStrings } from "tachi-common";
import { Random20Hex } from "utils/misc";
export async function QuickInsert<I extends IDStrings>(
base: ChartDocument<I>,
base: Omit<ChartDocument<I>, "chartID">,
content: Partial<ChartDocument<I>>[],
coll: ICollection
) {
@@ -0,0 +1,71 @@
/* eslint-disable no-await-in-loop */
import db from "external/mongo/db";
import { rootLogger } from "lib/logger/logger";
import { ChartDocument, Difficulties } from "tachi-common";
import { FindIIDXChartOnInGameID } from "utils/queries/charts";
async function ConvertChart(chart: ChartDocument<"iidx:SP" | "iidx:DP">) {
// We need to get the related official song. The best way to do this is
// probably with song IDs.
const originalChart = await FindIIDXChartOnInGameID(
chart.data.inGameID,
chart.playtype,
chart.difficulty
);
if (!originalChart) {
rootLogger.error(`Can't find original chart.`, { chart });
throw new Error(`Can't find original chart.`);
}
return {
difficulty: `${chart.data["2dxtraSet"]!} ${chart.difficulty}` as Difficulties[
| "iidx:SP"
| "iidx:DP"],
songID: originalChart!.songID,
};
}
if (require.main === module) {
(async () => {
const modCharts = (await db.charts.iidx.find({
"data.2dxtraSet": { $ne: null },
difficulty: { $in: ["BEGINNER", "NORMAL", "HYPER", "ANOTHER", "LEGGENDARIA"] },
})) as ChartDocument<"iidx:SP" | "iidx:DP">[];
rootLogger.info(`Modifying ${modCharts.length} charts.`);
for (const chart of modCharts) {
const setDoc = await ConvertChart(chart);
await db.charts.iidx.update(
{
chartID: chart.chartID,
},
{ $set: setDoc }
);
// We're also going to have to port over old scores.
await db.scores.update(
{
chartID: chart.chartID,
},
{
$set: {
songID: setDoc.songID,
},
}
);
}
rootLogger.info(`Removing ${modCharts.length} songs.`);
await db.songs.iidx.remove({
id: { $in: modCharts.map((e) => e.songID) },
});
rootLogger.info(`Done.`);
})();
}
+8 -6
View File
@@ -23,16 +23,16 @@ const staticIndexes: Partial<Record<Databases, Index[]>> = {
scores: [
index({ scoreID: 1 }, UNIQUE),
index({ chartID: 1, userID: 1 }),
index({ game: 1, playtype: 1, userID: 1 }),
index({ userID: 1, game: 1, playtype: 1 }),
],
"personal-bests": [
index({ chartID: 1, userID: 1 }, UNIQUE),
index({ chartID: 1, "scoreData.percent": 1 }),
index({ game: 1, playtype: 1, userID: 1 }),
index({ userID: 1, game: 1, playtype: 1 }),
],
sessions: [
// lol
index({ timeStarted: 1, timeEnded: 1, userID: 1, game: 1, playtype: 1 }),
index({ userID: 1, game: 1, playtype: 1, timeStarted: 1, timeEnded: 1 }),
index({ name: "text" }),
],
"game-stats": [index({ userID: 1, game: 1, playtype: 1 }, UNIQUE)],
@@ -58,8 +58,6 @@ const staticIndexes: Partial<Record<Databases, Index[]>> = {
],
folders: [
index({ folderID: 1 }, UNIQUE),
index({ game: 1, playtype: 1 }),
index({ game: 1, playtype: 1, table: 1 }),
index({ game: 1, playtype: 1, table: 1, tableIndex: 1 }),
index({ title: "text", searchTerms: "text" }),
],
@@ -94,12 +92,16 @@ for (const game of ServerTypeInfo.supportedGames) {
index(
{ songID: 1, difficulty: 1, playtype: 1, isPrimary: 1 },
{ unique: true, partialFilterExpression: { isPrimary: { $eq: true } } }
)
),
index({ songID: 1 }),
index({ playtype: 1 })
);
} else {
indexes[`charts-${game}` as Databases] = [
index({ chartID: 1 }, UNIQUE),
index({ songID: 1, difficulty: 1, playtype: 1, isPrimary: 1 }, UNIQUE),
index({ songID: 1 }),
index({ playtype: 1 }),
];
}
@@ -1,4 +1,3 @@
import { Difficulties } from "tachi-common";
import { KtLogger } from "lib/logger/logger";
import ScoreImportFatalError from "../../../framework/score-importing/score-import-error";
import { ParserFunctionReturns } from "../types";
@@ -128,8 +127,8 @@ export function NaiveCSVParse(csvBuffer: Buffer, logger: KtLogger) {
const { hasBeginnerAndLegg } = ResolveHeaders(rawHeaders, logger);
const diffs = hasBeginnerAndLegg
? ["beginner", "normal", "hyper", "another", "leggendaria"]
: ["normal", "hyper", "another"];
? (["beginner", "normal", "hyper", "another", "leggendaria"] as const)
: (["normal", "hyper", "another"] as const);
const iterableData = [];
@@ -188,7 +187,7 @@ export function NaiveCSVParse(csvBuffer: Buffer, logger: KtLogger) {
const di = 5 + d * 7;
scores.push({
difficulty: diff.toUpperCase() as Difficulties["iidx:SP" | "iidx:DP"],
difficulty: diff.toUpperCase() as Uppercase<typeof diff>,
bp: cells[di + 4],
exscore: cells[di + 1],
pgreat: cells[di + 2],
+2 -4
View File
@@ -124,7 +124,7 @@ export function FindIIDXChartOnInGameID(
) {
return db.charts.iidx.findOne({
"data.inGameID": inGameID,
"flags.2dxtra": false,
"data.2dxtraSet": null,
isPrimary: true,
playtype,
difficulty,
@@ -143,7 +143,7 @@ export function FindIIDXChartOnInGameIDVersion(
) {
return db.charts.iidx.findOne({
"data.inGameID": inGameID,
"flags.2dxtra": false,
"data.2dxtraSet": null,
playtype,
difficulty,
versions: version,
@@ -236,8 +236,6 @@ export function FindChartOnARCID(game: "iidx" | "ddr" | "jubeat" | "sdvx", arcID
* Returns the N most popular charts for this game + playtype.
* Popularity is determined by how many scores match in the score
* collection.
*
* Performance of this is untested.
*/
export function FindChartsOnPopularity(
game: Game,
+41
View File
@@ -0,0 +1,41 @@
import { Game, Playtypes, gameClasses, IDStrings, integer } from "tachi-common";
import NodeCache from "node-cache";
import db from "external/mongo/db";
import { ONE_HOUR } from "lib/constants/time";
const classDistCache = new NodeCache();
export async function GetClassDistribution(
game: Game,
playtype: Playtypes[Game],
className: gameClasses.GameClassSets[IDStrings]
) {
const cacheKey = `${game}:${playtype}:${className}`;
const cache = classDistCache.get(cacheKey);
if (!cache) {
const distribution = (await db["game-stats"].aggregate([
{
$match: {
game,
playtype,
},
},
{
$group: {
_id: `$classes.${className}`,
count: { $sum: 1 },
},
},
])) as { _id: string; count: integer }[];
// Converts {_id: "kaiden", count: 3} to {"kaiden": 3}, more or less.
const convert = Object.fromEntries(distribution.map((e) => [e._id, e.count]));
classDistCache.set(cacheKey, convert, ONE_HOUR);
return convert;
} else {
return cache;
}
}