From 1aa1baf657b1d2ee2e1e38d78d943b27ca927050 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Tue, 31 Dec 2024 02:38:43 +0100 Subject: [PATCH] Add profile command --- youmubot-osu/src/discord/commands.rs | 71 ++++++++++++++++++++++------ youmubot-osu/src/discord/mod.rs | 16 ++----- youmubot/src/main.rs | 8 ++-- 3 files changed, 65 insertions(+), 30 deletions(-) diff --git a/youmubot-osu/src/discord/commands.rs b/youmubot-osu/src/discord/commands.rs index df01538..9e6e8c0 100644 --- a/youmubot-osu/src/discord/commands.rs +++ b/youmubot-osu/src/discord/commands.rs @@ -4,7 +4,7 @@ use serenity::all::User; use youmubot_prelude::*; /// osu!-related command group. -#[poise::command(slash_command, subcommands("top"))] +#[poise::command(slash_command, subcommands("profile", "top"))] pub async fn osu(_ctx: CmdContext<'_, U>) -> Result<()> { Ok(()) } @@ -22,14 +22,10 @@ async fn top( #[description = "Score listing style"] style: Option, #[description = "Game mode"] mode: Option, #[description = "osu! username"] username: Option, - #[description = "Discord username"] user: Option, + #[description = "Discord username"] discord_name: Option, ) -> Result<()> { let env = ctx.data().osu_env(); - let username_arg = match (username, user) { - (Some(v), _) => Some(UsernameArg::Raw(v)), - (_, Some(u)) => Some(UsernameArg::Tagged(u.id)), - (None, None) => None, - }; + let username_arg = arg_from_username_or_discord(username, discord_name); let ListingArgs { nth, style, @@ -68,10 +64,9 @@ async fn top( ctx.send({ CreateReply::default() .content(format!( - "Here is the #{} top play by [`{}`](<{}>)", + "Here is the #{} top play by {}", nth + 1, - user.username, - user.link() + user.mention() )) .embed( score_embed(&play, &beatmap, &content, user) @@ -88,11 +83,7 @@ async fn top( Nth::All => { let reply = ctx .clone() - .reply(format!( - "Here are the top plays by [`{}`](<{}>)!", - user.username, - user.link() - )) + .reply(format!("Here are the top plays by {}!", user.mention())) .await? .into_message() .await?; @@ -103,3 +94,53 @@ async fn top( } Ok(()) } + +/// Get an user's profile. +#[poise::command(slash_command)] +async fn profile( + ctx: CmdContext<'_, U>, + #[description = "Game mode"] + #[rename = "mode"] + mode_override: Option, + #[description = "osu! username"] username: Option, + #[description = "Discord username"] discord_name: Option, +) -> Result<()> { + let env = ctx.data().osu_env(); + let username_arg = arg_from_username_or_discord(username, discord_name); + let (mode, user) = user_header_or_default_id(username_arg, env, ctx.author().id).await?; + let mode = mode_override.unwrap_or(mode); + + ctx.defer().await?; + + let user = env + .client + .user(&UserID::ID(user.id), |f| f.mode(mode)) + .await?; + + match user { + Some(u) => { + let ex = UserExtras::from_user(env, &u, mode).await?; + ctx.send( + CreateReply::default() + .content(format!("Here is {}'s **{}** profile!", u.mention(), mode)) + .embed(user_embed(u, ex)), + ) + .await?; + } + None => { + ctx.reply("🔍 user not found!").await?; + } + }; + Ok(()) +} + +fn arg_from_username_or_discord( + username: Option, + discord_name: Option, +) -> Option { + match (username, discord_name) { + (Some(v), _) => Some(UsernameArg::Raw(v)), + (_, Some(u)) => Some(UsernameArg::Tagged(u.id)), + (None, None) => None, + } +} diff --git a/youmubot-osu/src/discord/mod.rs b/youmubot-osu/src/discord/mod.rs index 6cae30c..cba91b7 100644 --- a/youmubot-osu/src/discord/mod.rs +++ b/youmubot-osu/src/discord/mod.rs @@ -1007,10 +1007,9 @@ pub async fn top(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult .send_message(&ctx, { CreateMessage::new() .content(format!( - "Here is the #{} top play by [`{}`](<{}>)", + "Here is the #{} top play by {}", nth + 1, - user.username, - user.link() + user.mention() )) .embed( score_embed(&play, &beatmap, &content, user) @@ -1028,11 +1027,7 @@ pub async fn top(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult let reply = msg .reply( &ctx, - format!( - "Here are the top plays by [`{}`](<{}>)!", - user.username, - user.link() - ), + format!("Here are the top plays by {}!", user.mention()), ) .await?; style @@ -1080,10 +1075,7 @@ async fn get_user( .send_message( &ctx, CreateMessage::new() - .content(format!( - "{}: here is the user that you requested", - msg.author - )) + .content(format!("Here is {}'s **{}** profile!", u.mention(), mode)) .embed(user_embed(u, ex)), ) .await?; diff --git a/youmubot/src/main.rs b/youmubot/src/main.rs index af3e658..054bdc4 100644 --- a/youmubot/src/main.rs +++ b/youmubot/src/main.rs @@ -265,12 +265,14 @@ async fn main() { Box::pin(async move { if let poise::FrameworkError::Command { error, ctx, .. } = err { let reply = format!( - "Command '{}' returned error {:?}", + "Command '{}' returned error: {:?}", ctx.invoked_command_name(), error ); - ctx.reply(&reply).await.pls_ok(); - println!("{}", reply) + println!("{}", reply); + ctx.send(poise::CreateReply::default().content(reply).ephemeral(true)) + .await + .pls_ok(); } else { eprintln!("Poise error: {:?}", err) }