mirror of
https://github.com/zkldi/Tachi.git
synced 2026-09-30 02:48:01 +03:00
@@ -184,6 +184,22 @@ export async function SearchGamesSongs(search: string, games: Array<Game>) {
|
||||
return res.flat(1).sort((a, b) => b.__textScore - a.__textScore);
|
||||
}
|
||||
|
||||
export async function SearchGamesSongsCharts(search: string, games: Array<Game>) {
|
||||
const promises = [];
|
||||
|
||||
for (const game of games) {
|
||||
promises.push(
|
||||
SearchSpecificGameSongsAndCharts(game, search).then((e) => ({
|
||||
game,
|
||||
songs: e.songs,
|
||||
charts: e.charts,
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
export async function SearchForChartHash(search: string) {
|
||||
const results = (await Promise.all([
|
||||
db.charts.bms.findOne({ $or: [{ "data.hashMD5": search }, { "data.hashSHA256": search }] }),
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
import { Router } from "express";
|
||||
import { SearchAllGamesSongs, SearchForChartHash, SearchUsersRegExp } from "lib/search/search";
|
||||
import { SYMBOL_TACHI_API_AUTH } from "lib/constants/tachi";
|
||||
import {
|
||||
SearchFolders,
|
||||
SearchForChartHash,
|
||||
SearchGamesSongsCharts,
|
||||
SearchUsersRegExp,
|
||||
} from "lib/search/search";
|
||||
import { TachiConfig } from "lib/setup/config";
|
||||
import { RequireBokutachi } from "server/middleware/type-require";
|
||||
import { IsString } from "utils/misc";
|
||||
import { GetAllUserRivals, GetUserPlayedGPTs } from "utils/user";
|
||||
import type { FilterQuery } from "mongodb";
|
||||
import type { FolderDocument, Game, PublicUserDocument, SongDocument } from "tachi-common";
|
||||
|
||||
const router: Router = Router({ mergeParams: true });
|
||||
|
||||
@@ -20,17 +30,56 @@ router.get("/", async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
const [users, songs] = await Promise.all([
|
||||
const userID = req[SYMBOL_TACHI_API_AUTH].userID;
|
||||
|
||||
let filter: FilterQuery<FolderDocument & PublicUserDocument & SongDocument> = {};
|
||||
let relevantGames: Array<Game> = TachiConfig.GAMES;
|
||||
|
||||
if (userID !== null) {
|
||||
// if the requesting user exists, and they've set this param,
|
||||
// only return info related to games they've played.
|
||||
if (IsString(req.query.hasPlayedGame)) {
|
||||
const gpts = await GetUserPlayedGPTs(userID);
|
||||
|
||||
// @hack This is a bit lazy. We should really be filtering the user stuff
|
||||
// on GPTs with an $or query.
|
||||
filter = {
|
||||
game: { $in: gpts.map((e) => e.game) },
|
||||
playtype: { $in: gpts.map((e) => e.playtype) },
|
||||
};
|
||||
|
||||
relevantGames = gpts.map((e) => e.game);
|
||||
}
|
||||
}
|
||||
|
||||
const [users, songChartData, folders] = await Promise.all([
|
||||
SearchUsersRegExp(req.query.search),
|
||||
SearchAllGamesSongs(req.query.search),
|
||||
SearchGamesSongsCharts(req.query.search, relevantGames),
|
||||
SearchFolders(req.query.search, filter),
|
||||
]);
|
||||
|
||||
const songs = songChartData.map((e) => e.songs.map((song) => ({ game: e.game, ...song })));
|
||||
const charts = songChartData.map((e) => e.charts.map((chart) => ({ game: e.game, ...chart })));
|
||||
|
||||
// @ts-expect-error Handled below -- the field is added by the below for loop.
|
||||
const usersWithRivalTag: Array<PublicUserDocument & { __isRival: boolean }> = users;
|
||||
|
||||
if (userID !== null) {
|
||||
const rivals = await GetAllUserRivals(userID);
|
||||
|
||||
for (const user of usersWithRivalTag) {
|
||||
user.__isRival = rivals.includes(user.id);
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
description: `Searched everything.`,
|
||||
body: {
|
||||
users,
|
||||
songs,
|
||||
charts,
|
||||
folders,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -265,3 +265,23 @@ export async function IsRequesterAdmin(request: APITokenDocument) {
|
||||
|
||||
return user.authLevel === UserAuthLevels.ADMIN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the GPTs this userID has played.
|
||||
*/
|
||||
export async function GetUserPlayedGPTs(userID: integer) {
|
||||
const gpts = (await db["game-stats"].find(
|
||||
{ userID },
|
||||
{ projection: { game: 1, playtype: 1 } }
|
||||
)) as Array<Pick<UserGameStats, "game" | "playtype">>;
|
||||
|
||||
return gpts;
|
||||
}
|
||||
|
||||
export async function GetAllUserRivals(userID: integer) {
|
||||
const rivals = (await db["game-settings"].find({ userID }, { projection: { rivals: 1 } }))
|
||||
.map((e) => e.rivals)
|
||||
.flat();
|
||||
|
||||
return rivals;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user