diff --git a/youmubot-osu/src/models/deser.rs b/youmubot-osu/src/models/deser.rs index a667946..d87acca 100644 --- a/youmubot-osu/src/models/deser.rs +++ b/youmubot-osu/src/models/deser.rs @@ -30,6 +30,7 @@ impl<'de> Deserialize<'de> for User { count_sh: parse_from_str(&raw.count_rank_sh)?, count_a: parse_from_str(&raw.count_rank_a)?, rank: parse_from_str(&raw.pp_rank)?, + country_rank: parse_from_str(&raw.pp_country_rank)?, level: parse_from_str(&raw.level)?, pp: Some(parse_from_str(&raw.pp_raw)?).filter(|v| *v != 0.0), accuracy: parse_from_str(&raw.accuracy)?, diff --git a/youmubot-osu/src/models/mod.rs b/youmubot-osu/src/models/mod.rs index 5432f73..645b96b 100644 --- a/youmubot-osu/src/models/mod.rs +++ b/youmubot-osu/src/models/mod.rs @@ -175,6 +175,7 @@ pub struct User { pub events: Vec, // Rankings pub rank: u64, + pub country_rank: u64, pub level: f64, pub pp: Option, pub accuracy: f64, diff --git a/youmubot/src/commands/mod.rs b/youmubot/src/commands/mod.rs index b5faeb9..089c9a8 100644 --- a/youmubot/src/commands/mod.rs +++ b/youmubot/src/commands/mod.rs @@ -17,6 +17,7 @@ pub mod osu; pub use admin::ADMIN_GROUP; pub use community::COMMUNITY_GROUP; pub use fun::FUN_GROUP; +pub use osu::OSU_GROUP; // A help command #[help] diff --git a/youmubot/src/commands/osu/mod.rs b/youmubot/src/commands/osu/mod.rs index b9e711e..19b82e9 100644 --- a/youmubot/src/commands/osu/mod.rs +++ b/youmubot/src/commands/osu/mod.rs @@ -1,4 +1,18 @@ -use serenity::framework::standard::macros::group; +use crate::commands::args::Duration; +use crate::http; +use serenity::{ + builder::CreateEmbed, + framework::standard::{ + macros::{command, group}, + Args, CommandResult, + }, + model::channel::Message, + prelude::*, +}; +use youmubot_osu::{ + models::{Mode, User}, + request::UserID, +}; mod hook; @@ -10,5 +24,102 @@ group!({ prefix: "osu", description: "osu! related commands.", }, - commands: [], + commands: [std, taiko, catch, mania], }); + +#[command] +#[aliases("osu", "osu!")] +#[description = "Receive information about an user in osu!std mode."] +#[usage = "[username or user_id = your saved username]"] +#[max_args(1)] +pub fn std(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult { + get_user(ctx, msg, args, Mode::Std) +} + +#[command] +#[aliases("osu!taiko")] +#[description = "Receive information about an user in osu!taiko mode."] +#[usage = "[username or user_id = your saved username]"] +#[max_args(1)] +pub fn taiko(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult { + get_user(ctx, msg, args, Mode::Taiko) +} + +#[command] +#[aliases("fruits", "osu!catch", "ctb")] +#[description = "Receive information about an user in osu!catch mode."] +#[usage = "[username or user_id = your saved username]"] +#[max_args(1)] +pub fn catch(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult { + get_user(ctx, msg, args, Mode::Catch) +} + +#[command] +#[aliases("osu!mania")] +#[description = "Receive information about an user in osu!mania mode."] +#[usage = "[username or user_id = your saved username]"] +#[max_args(1)] +pub fn mania(ctx: &mut Context, msg: &Message, args: Args) -> CommandResult { + get_user(ctx, msg, args, Mode::Mania) +} + +fn get_user(ctx: &mut Context, msg: &Message, mut args: Args, mode: Mode) -> CommandResult { + let username = args.single::()?; + let data = ctx.data.write(); + let reqwest = data.get::().unwrap(); + let osu = data.get::().unwrap(); + let user = osu.user(reqwest, UserID::Auto(username), |f| f.mode(mode))?; + match user { + Some(u) => msg.channel_id.send_message(&ctx, |m| { + m.content(format!( + "{}: here is the user that you requested", + msg.author + )) + .embed(|m| user_embed(u, m)) + }), + None => msg.reply(&ctx, "🔍 user not found!"), + }?; + Ok(()) +} + +fn user_embed(u: User, m: &mut CreateEmbed) -> &mut CreateEmbed { + m.title(u.username) + .url(format!("https://osu.ppy.sh/users/{}", u.id)) + .color(0xffb6c1) + .thumbnail(format!("https://a.ppy.sh/{}", u.id)) + .description(format!("Member since **{}**", u.joined.format("%F %T"))) + .field( + "Performance Points", + u.pp.map(|v| format!("{:.2}pp", v)) + .unwrap_or("Inactive".to_owned()), + false, + ) + .field("World Rank", format!("#{}", u.rank), true) + .field( + "Country Rank", + format!(":flag_{}: #{}", u.country.to_lowercase(), u.country_rank), + true, + ) + .field("Accuracy", format!("{:.2}%", u.accuracy), true) + .field( + "Play count", + format!("{} (play time: {})", u.play_count, Duration(u.played_time)), + false, + ) + .field( + "Ranks", + format!( + "{} SSH | {} SS | {} SH | {} S | {} A", + u.count_ssh, u.count_ss, u.count_sh, u.count_s, u.count_a + ), + false, + ) + .field( + "Level", + format!( + "Level **{:.0}**: {} total score, {} ranked score", + u.level, u.total_score, u.ranked_score + ), + false, + ) +} diff --git a/youmubot/src/main.rs b/youmubot/src/main.rs index e19d343..3e31d51 100644 --- a/youmubot/src/main.rs +++ b/youmubot/src/main.rs @@ -131,7 +131,8 @@ fn setup_framework(mut client: Client) -> Client { // groups here .group(&commands::ADMIN_GROUP) .group(&commands::FUN_GROUP) - .group(&commands::COMMUNITY_GROUP), + .group(&commands::COMMUNITY_GROUP) + .group(&commands::OSU_GROUP) ); client }