From 84b152adf617d4ff2f5f7e1605f9f904f88cf342 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Thu, 20 Feb 2025 14:16:56 +0100 Subject: [PATCH] osu: add /s/{id} links to the link parser, support beatmapsets with mode override --- youmubot-osu/src/discord/beatmap_cache.rs | 6 +++-- youmubot-osu/src/discord/commands.rs | 5 +++- youmubot-osu/src/discord/interaction.rs | 7 ++++-- youmubot-osu/src/discord/link_parser.rs | 29 ++++++++++++++++------- youmubot-osu/src/discord/mod.rs | 8 ++++++- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/youmubot-osu/src/discord/beatmap_cache.rs b/youmubot-osu/src/discord/beatmap_cache.rs index 3fb17f4..005c821 100644 --- a/youmubot-osu/src/discord/beatmap_cache.rs +++ b/youmubot-osu/src/discord/beatmap_cache.rs @@ -100,7 +100,7 @@ impl BeatmapMetaCache { } /// Get a beatmapset from its ID. - pub async fn get_beatmapset(&self, id: u64) -> Result> { + pub async fn get_beatmapset(&self, id: u64, mode: Option) -> Result> { let bms = models::CachedBeatmap::by_beatmapset(id as i64, &self.pool).await?; if !bms.is_empty() { return Ok(bms @@ -110,7 +110,9 @@ impl BeatmapMetaCache { } let mut beatmaps = self .client - .beatmaps(crate::BeatmapRequestKind::Beatmapset(id), |f| f) + .beatmaps(crate::BeatmapRequestKind::Beatmapset(id), |f| { + f.maybe_mode(mode) + }) .await?; if beatmaps.is_empty() { return Err(Error::msg("beatmapset not found")); diff --git a/youmubot-osu/src/discord/commands.rs b/youmubot-osu/src/discord/commands.rs index f07ebee..4b4890d 100644 --- a/youmubot-osu/src/discord/commands.rs +++ b/youmubot-osu/src/discord/commands.rs @@ -709,7 +709,10 @@ async fn parse_map_input( let output = if beatmapset == Some(true) { match output { EmbedType::Beatmap(beatmap, _, _) => { - let beatmaps = env.beatmaps.get_beatmapset(beatmap.beatmapset_id).await?; + let beatmaps = env + .beatmaps + .get_beatmapset(beatmap.beatmapset_id, mode) + .await?; EmbedType::Beatmapset(beatmaps) } bm @ EmbedType::Beatmapset(_) => bm, diff --git a/youmubot-osu/src/discord/interaction.rs b/youmubot-osu/src/discord/interaction.rs index 0dc4caf..9e442d1 100644 --- a/youmubot-osu/src/discord/interaction.rs +++ b/youmubot-osu/src/discord/interaction.rs @@ -313,12 +313,15 @@ async fn handle_last_req( let mods = mods_def.unwrap_or_default(); if is_beatmapset_req { - let beatmapset = env.beatmaps.get_beatmapset(bm.0.beatmapset_id).await?; + let beatmapset = env + .beatmaps + .get_beatmapset(bm.0.beatmapset_id, None) + .await?; let reply = comp .create_followup( &ctx, CreateInteractionResponseFollowup::new() - .content(format!("Beatmapset of `{}`", bm.short_link(&mods))), + .content(format!("Beatmapset `{}`", bm.0.beatmapset_mention())), ) .await?; super::display::display_beatmapset( diff --git a/youmubot-osu/src/discord/link_parser.rs b/youmubot-osu/src/discord/link_parser.rs index 60ff5f2..bb078c5 100644 --- a/youmubot-osu/src/discord/link_parser.rs +++ b/youmubot-osu/src/discord/link_parser.rs @@ -29,7 +29,7 @@ lazy_static! { r"(?:https?://)?osu\.ppy\.sh/beatmapsets/(?P\d+)/?(?:\#(?Posu|taiko|fruits|mania)(?:/(?P\d+)|/?))?(?:(?Pv2|[[:^alpha:]]\S+\b))?" ).unwrap(); static ref SHORT_LINK_REGEX: Regex = Regex::new( - r"(?:^|\s|\W)(?P
/b/(?P\d+)(?:/(?Posu|taiko|fruits|mania))?(?:(?Pv2|[[:^alpha:]]\S+\b))?)" + r"(?:^|\s|\W)(?P
/(?Pb|s)/(?P\d+)(?:/(?Posu|taiko|fruits|mania))?(?:(?Pv2|[[:^alpha:]]\S+\b))?)" ).unwrap(); // Score hook @@ -60,7 +60,7 @@ pub fn parse_old_links<'a>( .unwrap_or_default(); EmbedType::from_beatmap_id(env, capture["id"].parse()?, mode, mods).await } - "s" => EmbedType::from_beatmapset_id(env, capture["id"].parse()?).await, + "s" => EmbedType::from_beatmapset_id(env, capture["id"].parse()?, mode).await, _ => unreachable!(), }?; Ok(ToPrint { @@ -99,6 +99,7 @@ pub fn parse_new_links<'a>( EmbedType::from_beatmapset_id( env, capture.name("set_id").unwrap().as_str().parse()?, + mode, ) .await } @@ -121,11 +122,17 @@ pub fn parse_short_links<'a>( .and_then(|v| Mode::parse_from_new_site(v.as_str())); let link = capture.name("main").unwrap().as_str(); let id: u64 = capture.name("id").unwrap().as_str().parse()?; - let mods = capture - .name("mods") - .and_then(|v| UnparsedMods::from_str(v.as_str()).pls_ok()) - .unwrap_or_default(); - let embed = EmbedType::from_beatmap_id(env, id, mode, mods).await?; + let embed = match capture.name("link_type").unwrap().as_str() { + "b" => { + let mods = capture + .name("mods") + .and_then(|v| UnparsedMods::from_str(v.as_str()).pls_ok()) + .unwrap_or_default(); + EmbedType::from_beatmap_id(env, id, mode, mods).await? + } + "s" => EmbedType::from_beatmapset_id(env, id, mode).await?, + _ => unreachable!(), + }; Ok(ToPrint { embed, link, mode }) }) .collect::>() @@ -154,9 +161,13 @@ impl EmbedType { Ok(Self::Beatmap(Box::new(bm), info, mods)) } - async fn from_beatmapset_id(env: &OsuEnv, beatmapset_id: u64) -> Result { + async fn from_beatmapset_id( + env: &OsuEnv, + beatmapset_id: u64, + mode: Option, + ) -> Result { Ok(Self::Beatmapset( - env.beatmaps.get_beatmapset(beatmapset_id).await?, + env.beatmaps.get_beatmapset(beatmapset_id, mode).await?, )) } } diff --git a/youmubot-osu/src/discord/mod.rs b/youmubot-osu/src/discord/mod.rs index 8f3316e..dc83384 100644 --- a/youmubot-osu/src/discord/mod.rs +++ b/youmubot-osu/src/discord/mod.rs @@ -865,7 +865,13 @@ pub async fn last(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult Some((bm, mods_def)) => { let mods = args.find::().ok(); if beatmapset { - let beatmapset = env.beatmaps.get_beatmapset(bm.0.beatmapset_id).await?; + let beatmapset = env + .beatmaps + .get_beatmapset( + bm.0.beatmapset_id, + None, /* Note that we cannot know, so don't force that */ + ) + .await?; let reply = msg .reply(&ctx, "Here is the beatmapset you requested!") .await?;