diff --git a/youmubot/src/commands/osu/cache.rs b/youmubot/src/commands/osu/cache.rs new file mode 100644 index 0000000..614bcce --- /dev/null +++ b/youmubot/src/commands/osu/cache.rs @@ -0,0 +1,36 @@ +use super::BeatmapWithMode; +use crate::db::{DBWriteGuard, OsuLastBeatmap}; +use serenity::{ + framework::standard::{CommandError as Error, CommandResult}, + model::id::ChannelId, + prelude::*, +}; +use youmubot_osu::models::Mode; + +/// Save the beatmap into the server data storage. +pub(crate) fn save_beatmap( + data: &mut ShareMap, + channel_id: ChannelId, + bm: &BeatmapWithMode, +) -> CommandResult { + let mut db: DBWriteGuard<_> = data + .get_mut::() + .expect("DB is implemented") + .into(); + let mut db = db.borrow_mut()?; + + db.insert(channel_id, (bm.0.beatmap_id, bm.mode())); + + Ok(()) +} + +/// Get the last beatmap requested from this channel. +pub(crate) fn get_beatmap( + data: &ShareMap, + channel_id: ChannelId, +) -> Result, Error> { + let db = data.get::().expect("DB is implemented"); + let db = db.borrow_data()?; + + Ok(db.get(&channel_id).cloned()) +} diff --git a/youmubot/src/commands/osu/hook.rs b/youmubot/src/commands/osu/hook.rs index 15e46fd..4db3d8a 100644 --- a/youmubot/src/commands/osu/hook.rs +++ b/youmubot/src/commands/osu/hook.rs @@ -30,14 +30,26 @@ pub fn hook(ctx: &mut Context, msg: &Message) -> () { let mut v = move || -> CommandResult { let old_links = handle_old_links(ctx, &msg.content)?; let new_links = handle_new_links(ctx, &msg.content)?; + let mut last_beatmap = None; for l in old_links.into_iter().chain(new_links.into_iter()) { if let Err(v) = msg.channel_id.send_message(&ctx, |m| match l.embed { - EmbedType::Beatmap(b) => handle_beatmap(b, l.link, l.mode, l.mods, m), + EmbedType::Beatmap(b) => { + let t = handle_beatmap(&b, l.link, l.mode, l.mods, m); + let mode = l.mode.unwrap_or(b.mode); + last_beatmap = Some(super::BeatmapWithMode(b, mode)); + t + } EmbedType::Beatmapset(b) => handle_beatmapset(b, l.link, l.mode, l.mods, m), }) { println!("Error in osu! hook: {:?}", v) } } + // Save the beatmap for query later. + if let Some(t) = last_beatmap { + if let Err(v) = super::cache::save_beatmap(&mut *ctx.data.write(), msg.channel_id, &t) { + dbg!(v); + } + } Ok(()) }; if let Err(v) = v() { @@ -159,7 +171,7 @@ fn handle_new_links<'a>(ctx: &mut Context, content: &'a str) -> Result( - beatmap: Beatmap, + beatmap: &Beatmap, link: &'_ str, mode: Option, mods: Option<&'_ str>, @@ -171,7 +183,7 @@ fn handle_beatmap<'a, 'b>( .push_mono_safe(link) .build(), ) - .embed(|b| beatmap_embed(&beatmap, mode.unwrap_or(beatmap.mode), b)) + .embed(|b| beatmap_embed(beatmap, mode.unwrap_or(beatmap.mode), b)) } fn handle_beatmapset<'a, 'b>( diff --git a/youmubot/src/commands/osu/mod.rs b/youmubot/src/commands/osu/mod.rs index 487d211..d634e32 100644 --- a/youmubot/src/commands/osu/mod.rs +++ b/youmubot/src/commands/osu/mod.rs @@ -209,6 +209,9 @@ pub fn recent(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult .embed(|m| score_embed(&recent_play, &beatmap, &user, None, m)) })?; + // Save the beatmap... + cache::save_beatmap(&mut *data, msg.channel_id, &beatmap)?; + Ok(()) } diff --git a/youmubot/src/db/mod.rs b/youmubot/src/db/mod.rs index 247af05..ce8cb80 100644 --- a/youmubot/src/db/mod.rs +++ b/youmubot/src/db/mod.rs @@ -5,11 +5,12 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serenity::{ client::Client, framework::standard::CommandError as Error, - model::id::{GuildId, RoleId, UserId}, + model::id::{ChannelId, GuildId, RoleId, UserId}, prelude::*, }; use std::collections::HashMap; use std::path::{Path, PathBuf}; +use youmubot_osu::models::Mode; /// GuildMap defines the guild-map type. /// It is basically a HashMap from a GuildId to a data structure. @@ -38,6 +39,9 @@ pub type SoftBans = DB>; /// Save the user IDs. pub type OsuSavedUsers = DB>; +/// Save each channel's last requested beatmap. +pub type OsuLastBeatmap = DB>; + /// Sets up all databases in the client. pub fn setup_db(client: &mut Client) -> Result<(), Error> { let path: PathBuf = var("DBPATH").map(|v| PathBuf::from(v)).unwrap_or_else(|e| { @@ -47,6 +51,7 @@ pub fn setup_db(client: &mut Client) -> Result<(), Error> { let mut data = client.data.write(); SoftBans::insert_into(&mut *data, &path.join("soft_bans.ron"))?; OsuSavedUsers::insert_into(&mut *data, &path.join("osu_saved_users.ron"))?; + OsuLastBeatmap::insert_into(&mut *data, &path.join("last_beatmaps.ron"))?; Ok(()) }