From 790c49261171ed70f997558e59ff42b45b583850 Mon Sep 17 00:00:00 2001 From: Rian8337 <52914632+Rian8337@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:49:00 +0800 Subject: [PATCH] Query official database for player name search when possible --- .../osu! and osu!droid/compare/compare.ts | 8 ++- .../osu! and osu!droid/daily/daily.ts | 8 ++- .../autocomplete/osu! and osu!droid/pp/pp.ts | 5 +- .../osu! and osu!droid/profile/profile.ts | 8 ++- .../osu! and osu!droid/recalc/recalc.ts | 5 +- .../osu! and osu!droid/recent/recent.ts | 8 ++- .../osu! and osu!droid/recent5/recent5.ts | 8 ++- .../osu! and osu!droid/simulate/simulate.ts | 8 ++- src/utils/helpers/DroidHelper.ts | 49 +++++++++++++++++++ 9 files changed, 71 insertions(+), 36 deletions(-) diff --git a/src/interactions/autocomplete/osu! and osu!droid/compare/compare.ts b/src/interactions/autocomplete/osu! and osu!droid/compare/compare.ts index b862eff14..d02f6c0ae 100644 --- a/src/interactions/autocomplete/osu! and osu!droid/compare/compare.ts +++ b/src/interactions/autocomplete/osu! and osu!droid/compare/compare.ts @@ -1,12 +1,10 @@ -import { DatabaseManager } from "@database/DatabaseManager"; import { AutocompleteHandler } from "@structures/core/AutocompleteHandler"; +import { DroidHelper } from "@utils/helpers/DroidHelper"; export const run: AutocompleteHandler["run"] = async (_, interaction) => { - const focusedValue: string = interaction.options.getFocused(); - interaction.respond( - await DatabaseManager.elainaDb.collections.userBind.searchPlayersForAutocomplete( - focusedValue, + await DroidHelper.searchPlayersForAutocomplete( + interaction.options.getFocused(), ), ); }; diff --git a/src/interactions/autocomplete/osu! and osu!droid/daily/daily.ts b/src/interactions/autocomplete/osu! and osu!droid/daily/daily.ts index 6469c612d..5002878e0 100644 --- a/src/interactions/autocomplete/osu! and osu!droid/daily/daily.ts +++ b/src/interactions/autocomplete/osu! and osu!droid/daily/daily.ts @@ -1,12 +1,10 @@ -import { DatabaseManager } from "@database/DatabaseManager"; import { AutocompleteHandler } from "@structures/core/AutocompleteHandler"; +import { DroidHelper } from "@utils/helpers/DroidHelper"; export const run: AutocompleteHandler["run"] = async (_, interaction) => { - const focusedValue: string = interaction.options.getFocused(); - interaction.respond( - await DatabaseManager.elainaDb.collections.userBind.searchPlayersForAutocomplete( - focusedValue, + await DroidHelper.searchPlayersForAutocomplete( + interaction.options.getFocused(), ), ); }; diff --git a/src/interactions/autocomplete/osu! and osu!droid/pp/pp.ts b/src/interactions/autocomplete/osu! and osu!droid/pp/pp.ts index bf6aa01af..c50999229 100644 --- a/src/interactions/autocomplete/osu! and osu!droid/pp/pp.ts +++ b/src/interactions/autocomplete/osu! and osu!droid/pp/pp.ts @@ -1,5 +1,6 @@ import { DatabaseManager } from "@database/DatabaseManager"; import { AutocompleteHandler } from "@structures/core/AutocompleteHandler"; +import { DroidHelper } from "@utils/helpers/DroidHelper"; export const run: AutocompleteHandler["run"] = async (_, interaction) => { // Lots of autocomplete options for this command, but they're all usernames. @@ -28,9 +29,7 @@ export const run: AutocompleteHandler["run"] = async (_, interaction) => { } } else { interaction.respond( - await DatabaseManager.elainaDb.collections.userBind.searchPlayersForAutocomplete( - focused.value, - ), + await DroidHelper.searchPlayersForAutocomplete(focused.value), ); } }; diff --git a/src/interactions/autocomplete/osu! and osu!droid/profile/profile.ts b/src/interactions/autocomplete/osu! and osu!droid/profile/profile.ts index 81ba31c08..85380eee8 100644 --- a/src/interactions/autocomplete/osu! and osu!droid/profile/profile.ts +++ b/src/interactions/autocomplete/osu! and osu!droid/profile/profile.ts @@ -1,12 +1,10 @@ -import { DatabaseManager } from "@database/DatabaseManager"; import { AutocompleteHandler } from "@structures/core/AutocompleteHandler"; +import { DroidHelper } from "@utils/helpers/DroidHelper"; export const run: AutocompleteHandler["run"] = async (_, interaction) => { - const focusedValue: string = interaction.options.getFocused(); - interaction.respond( - await DatabaseManager.elainaDb.collections.userBind.searchPlayersForAutocomplete( - focusedValue, + await DroidHelper.searchPlayersForAutocomplete( + interaction.options.getFocused(), ), ); }; diff --git a/src/interactions/autocomplete/osu! and osu!droid/recalc/recalc.ts b/src/interactions/autocomplete/osu! and osu!droid/recalc/recalc.ts index 062822cfd..286cf149a 100644 --- a/src/interactions/autocomplete/osu! and osu!droid/recalc/recalc.ts +++ b/src/interactions/autocomplete/osu! and osu!droid/recalc/recalc.ts @@ -1,5 +1,6 @@ import { DatabaseManager } from "@database/DatabaseManager"; import { AutocompleteHandler } from "@structures/core/AutocompleteHandler"; +import { DroidHelper } from "@utils/helpers/DroidHelper"; export const run: AutocompleteHandler["run"] = async (_, interaction) => { const focused = interaction.options.getFocused(true); @@ -7,9 +8,7 @@ export const run: AutocompleteHandler["run"] = async (_, interaction) => { switch (focused.name) { case "username": interaction.respond( - await DatabaseManager.elainaDb.collections.userBind.searchPlayersForAutocomplete( - focused.value, - ), + await DroidHelper.searchPlayersForAutocomplete(focused.value), ); break; case "reworktype": diff --git a/src/interactions/autocomplete/osu! and osu!droid/recent/recent.ts b/src/interactions/autocomplete/osu! and osu!droid/recent/recent.ts index b0b85cfd3..fe18e03e8 100644 --- a/src/interactions/autocomplete/osu! and osu!droid/recent/recent.ts +++ b/src/interactions/autocomplete/osu! and osu!droid/recent/recent.ts @@ -1,12 +1,10 @@ -import { DatabaseManager } from "@database/DatabaseManager"; import { AutocompleteHandler } from "@structures/core/AutocompleteHandler"; +import { DroidHelper } from "@utils/helpers/DroidHelper"; export const run: AutocompleteHandler["run"] = async (_, interaction) => { - const focusedValue: string = interaction.options.getFocused(); - interaction.respond( - await DatabaseManager.elainaDb.collections.userBind.searchPlayersForAutocomplete( - focusedValue, + await DroidHelper.searchPlayersForAutocomplete( + interaction.options.getFocused(), ), ); }; diff --git a/src/interactions/autocomplete/osu! and osu!droid/recent5/recent5.ts b/src/interactions/autocomplete/osu! and osu!droid/recent5/recent5.ts index 08df307b9..1c2ff69fe 100644 --- a/src/interactions/autocomplete/osu! and osu!droid/recent5/recent5.ts +++ b/src/interactions/autocomplete/osu! and osu!droid/recent5/recent5.ts @@ -1,12 +1,10 @@ -import { DatabaseManager } from "@database/DatabaseManager"; import { AutocompleteHandler } from "@structures/core/AutocompleteHandler"; +import { DroidHelper } from "@utils/helpers/DroidHelper"; export const run: AutocompleteHandler["run"] = async (_, interaction) => { - const focusedValue: string = interaction.options.getFocused(); - interaction.respond( - await DatabaseManager.elainaDb.collections.userBind.searchPlayersForAutocomplete( - focusedValue, + await DroidHelper.searchPlayersForAutocomplete( + interaction.options.getFocused(), ), ); }; diff --git a/src/interactions/autocomplete/osu! and osu!droid/simulate/simulate.ts b/src/interactions/autocomplete/osu! and osu!droid/simulate/simulate.ts index 08df307b9..1c2ff69fe 100644 --- a/src/interactions/autocomplete/osu! and osu!droid/simulate/simulate.ts +++ b/src/interactions/autocomplete/osu! and osu!droid/simulate/simulate.ts @@ -1,12 +1,10 @@ -import { DatabaseManager } from "@database/DatabaseManager"; import { AutocompleteHandler } from "@structures/core/AutocompleteHandler"; +import { DroidHelper } from "@utils/helpers/DroidHelper"; export const run: AutocompleteHandler["run"] = async (_, interaction) => { - const focusedValue: string = interaction.options.getFocused(); - interaction.respond( - await DatabaseManager.elainaDb.collections.userBind.searchPlayersForAutocomplete( - focusedValue, + await DroidHelper.searchPlayersForAutocomplete( + interaction.options.getFocused(), ), ); }; diff --git a/src/utils/helpers/DroidHelper.ts b/src/utils/helpers/DroidHelper.ts index a37505a9c..dd3eb474a 100644 --- a/src/utils/helpers/DroidHelper.ts +++ b/src/utils/helpers/DroidHelper.ts @@ -12,6 +12,8 @@ import { APIScore, Player, Score } from "@rian8337/osu-droid-utilities"; import { RowDataPacket } from "mysql2"; import { OnlinePlayerRank } from "@structures/utils/OnlinePlayerRank"; import { readFile, stat } from "fs/promises"; +import { ApplicationCommandOptionChoiceData } from "discord.js"; +import { DatabaseManager } from "@database/DatabaseManager"; /** * A helper for osu!droid related requests. @@ -582,6 +584,53 @@ export abstract class DroidHelper { return readFile(avatarPath).catch(() => null); } + /** + * Searches for player names. + * + * In debug mode, this queries the database instead. + * + * @param name The name to search for. + * @param amount The amount of player names to retrieve. Defaults to 25. + * @returns The player names, `null` if in debug mode or the database cannot be queried. + */ + static async searchPlayersForAutocomplete( + name: string, + amount = 25, + ): Promise[]> { + name = name.trim(); + + // Usernames only allow: + // - 2 to 20 characters. + // - alphanumeric characters and underscores. + if ( + name.length < 2 || + name.length > 20 || + !/^[a-zA-Z0-9_]*$/.test(name) + ) { + return []; + } + + if (Config.isDebug) { + return DatabaseManager.elainaDb.collections.userBind.searchPlayersForAutocomplete( + name, + amount, + ); + } + + const playerQuery = await officialPool + .query< + RowDataPacket[] + >(`SELECT username FROM ${constructOfficialDatabaseTable(OfficialDatabaseTables.user)} WHERE username LIKE ? LIMIT ${amount};`, [`${name}%`]) + .then((res) => res[0] as Pick[]); + + return playerQuery.map((v) => { + return { + name: v.username, + value: v.username, + }; + }); + } + /** * Cleans up filenames received from the score table to a proper title. *