mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-15 02:29:28 +03:00
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:
+2
-1
@@ -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"
|
||||
|
||||
Generated
+20
-4
@@ -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:
|
||||
|
||||
@@ -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.`);
|
||||
})();
|
||||
}
|
||||
Vendored
+8
-6
@@ -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],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user