mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-05-24 09:10:49 +00:00
Implement BeatmapCache and Oppai interface
This commit is contained in:
parent
d68ce9cec8
commit
9aab6e11ec
4 changed files with 148 additions and 1 deletions
|
@ -15,6 +15,8 @@ bitflags = "1"
|
|||
rayon = "1.1"
|
||||
lazy_static = "1"
|
||||
regex = "1"
|
||||
oppai-rs = "0.2.0"
|
||||
dashmap = "3.11.4"
|
||||
|
||||
youmubot-db = { path = "../youmubot-db" }
|
||||
youmubot-prelude = { path = "../youmubot-prelude" }
|
||||
|
|
|
@ -20,6 +20,7 @@ mod cache;
|
|||
mod db;
|
||||
pub(crate) mod embeds;
|
||||
mod hook;
|
||||
mod oppai_cache;
|
||||
mod server_rank;
|
||||
|
||||
use db::OsuUser;
|
||||
|
@ -58,9 +59,10 @@ pub fn setup(
|
|||
// API client
|
||||
let http_client = data.get_cloned::<HTTPClient>();
|
||||
data.insert::<OsuClient>(OsuHttpClient::new(
|
||||
http_client,
|
||||
http_client.clone(),
|
||||
std::env::var("OSU_API_KEY").expect("Please set OSU_API_KEY as osu! api key."),
|
||||
));
|
||||
data.insert::<oppai_cache::BeatmapCache>(oppai_cache::BeatmapCache::new(http_client));
|
||||
|
||||
// Announcer
|
||||
announcers.add(announcer::ANNOUNCER_KEY, announcer::updates);
|
||||
|
|
90
youmubot-osu/src/discord/oppai_cache.rs
Normal file
90
youmubot-osu/src/discord/oppai_cache.rs
Normal file
|
@ -0,0 +1,90 @@
|
|||
use serenity::framework::standard::CommandError;
|
||||
use std::{ffi::CString, sync::Arc};
|
||||
use youmubot_prelude::TypeMapKey;
|
||||
|
||||
/// the information collected from a download/Oppai request.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BeatmapContent {
|
||||
id: u64,
|
||||
content: Arc<CString>,
|
||||
}
|
||||
|
||||
/// the output of "one" oppai run.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct BeatmapInfo {
|
||||
stars: f32,
|
||||
pp: [f32; 4], // 95, 98, 99, 100
|
||||
}
|
||||
|
||||
impl BeatmapContent {
|
||||
/// Get pp given the combo and accuracy.
|
||||
pub fn get_pp_from(
|
||||
&self,
|
||||
combo: oppai_rs::Combo,
|
||||
accuracy: f32,
|
||||
mods: impl Into<oppai_rs::Mods>,
|
||||
) -> Result<f32, CommandError> {
|
||||
Ok(oppai_rs::Oppai::new_from_content(&self.content[..])?
|
||||
.combo(combo)?
|
||||
.accuracy(accuracy)?
|
||||
.mods(mods.into())
|
||||
.pp())
|
||||
}
|
||||
|
||||
/// Get info given mods.
|
||||
pub fn get_info_with(
|
||||
&self,
|
||||
mods: impl Into<oppai_rs::Mods>,
|
||||
) -> Result<BeatmapInfo, CommandError> {
|
||||
let mut oppai = oppai_rs::Oppai::new_from_content(&self.content[..])?;
|
||||
oppai.mods(mods.into()).combo(oppai_rs::Combo::PERFECT)?;
|
||||
let pp = [
|
||||
oppai.accuracy(95.0)?.pp(),
|
||||
oppai.accuracy(98.0)?.pp(),
|
||||
oppai.accuracy(99.0)?.pp(),
|
||||
oppai.accuracy(100.0)?.pp(),
|
||||
];
|
||||
let stars = oppai.stars();
|
||||
Ok(BeatmapInfo { stars, pp })
|
||||
}
|
||||
}
|
||||
|
||||
/// A central cache for the beatmaps.
|
||||
pub struct BeatmapCache {
|
||||
client: reqwest::blocking::Client,
|
||||
cache: Arc<dashmap::DashMap<u64, BeatmapContent>>,
|
||||
}
|
||||
|
||||
impl BeatmapCache {
|
||||
/// Create a new cache.
|
||||
pub fn new(client: reqwest::blocking::Client) -> Self {
|
||||
BeatmapCache {
|
||||
client,
|
||||
cache: Arc::new(dashmap::DashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn download_beatmap(&self, id: u64) -> Result<BeatmapContent, CommandError> {
|
||||
let content = self
|
||||
.client
|
||||
.get(&format!("https://osu.ppy.sh/u/{}", id))
|
||||
.send()?
|
||||
.bytes()?;
|
||||
Ok(BeatmapContent {
|
||||
id,
|
||||
content: Arc::new(CString::new(content.into_iter().collect::<Vec<_>>())?),
|
||||
})
|
||||
}
|
||||
|
||||
/// Get a beatmap from the cache.
|
||||
pub fn get_beatmap(&self, id: u64) -> Result<BeatmapContent, CommandError> {
|
||||
self.cache
|
||||
.entry(id)
|
||||
.or_try_insert_with(|| self.download_beatmap(id))
|
||||
.map(|v| v.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeMapKey for BeatmapCache {
|
||||
type Value = BeatmapCache;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue