mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-04-19 00:38:54 +00:00
Add weighted map length to profile
This commit is contained in:
parent
01c743f866
commit
4ba64a466d
3 changed files with 47 additions and 26 deletions
|
@ -1,5 +1,5 @@
|
||||||
use super::db::{OsuSavedUsers, OsuUser};
|
use super::db::{OsuSavedUsers, OsuUser};
|
||||||
use super::OsuClient;
|
use super::{calculate_weighted_map_length, OsuClient};
|
||||||
use super::{embeds::score_embed, BeatmapWithMode};
|
use super::{embeds::score_embed, BeatmapWithMode};
|
||||||
use crate::{
|
use crate::{
|
||||||
discord::beatmap_cache::BeatmapMetaCache,
|
discord::beatmap_cache::BeatmapMetaCache,
|
||||||
|
@ -200,22 +200,7 @@ impl Announcer {
|
||||||
let scores = client
|
let scores = client
|
||||||
.user_best(UserID::ID(u.id), |f| f.mode(Mode::Std).limit(100))
|
.user_best(UserID::ID(u.id), |f| f.mode(Mode::Std).limit(100))
|
||||||
.await?;
|
.await?;
|
||||||
scores
|
calculate_weighted_map_length(&scores, cache, Mode::Std).await
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, s)| async move {
|
|
||||||
let beatmap = cache.get_beatmap_default(s.beatmap_id).await?;
|
|
||||||
const SCALING_FACTOR: f64 = 0.975;
|
|
||||||
Ok(beatmap
|
|
||||||
.difficulty
|
|
||||||
.apply_mods(s.mods, 0.0 /* dont care */)
|
|
||||||
.drain_length
|
|
||||||
.as_secs_f64()
|
|
||||||
* (SCALING_FACTOR.powi(i as i32)))
|
|
||||||
})
|
|
||||||
.collect::<FuturesUnordered<_>>()
|
|
||||||
.try_fold(0.0, |a, b| future::ready(Ok(a + b)))
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -423,6 +423,7 @@ impl<'a> ScoreEmbedBuilder<'a> {
|
||||||
|
|
||||||
pub(crate) fn user_embed(
|
pub(crate) fn user_embed(
|
||||||
u: User,
|
u: User,
|
||||||
|
map_length: f64,
|
||||||
best: Option<(Score, BeatmapWithMode, BeatmapInfo)>,
|
best: Option<(Score, BeatmapWithMode, BeatmapInfo)>,
|
||||||
) -> CreateEmbed {
|
) -> CreateEmbed {
|
||||||
CreateEmbed::new()
|
CreateEmbed::new()
|
||||||
|
@ -470,6 +471,19 @@ pub(crate) fn user_embed(
|
||||||
),
|
),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
.field(
|
||||||
|
"Weighted Map Length",
|
||||||
|
{
|
||||||
|
let secs = map_length.floor() as u64;
|
||||||
|
let minutes = secs / 60;
|
||||||
|
let seconds = map_length - (60 * minutes) as f64;
|
||||||
|
format!(
|
||||||
|
"**{}** minutes **{:05.2}** seconds (**{:.2}**s)",
|
||||||
|
minutes, seconds, map_length
|
||||||
|
)
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
)
|
||||||
.field(
|
.field(
|
||||||
format!("Level {:.0}", u.level),
|
format!("Level {:.0}", u.level),
|
||||||
format!(
|
format!(
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
discord::beatmap_cache::BeatmapMetaCache,
|
discord::beatmap_cache::BeatmapMetaCache,
|
||||||
discord::display::ScoreListStyle,
|
discord::display::ScoreListStyle,
|
||||||
discord::oppai_cache::{BeatmapCache, BeatmapInfo},
|
discord::oppai_cache::{BeatmapCache, BeatmapInfo},
|
||||||
models::{self, Beatmap, Mode, Mods, User},
|
models::{self, Beatmap, Mode, Mods, Score, User},
|
||||||
request::{BeatmapRequestKind, UserID},
|
request::{BeatmapRequestKind, UserID},
|
||||||
Client as OsuHttpClient,
|
Client as OsuHttpClient,
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@ use serenity::{
|
||||||
utils::MessageBuilder,
|
utils::MessageBuilder,
|
||||||
};
|
};
|
||||||
use std::{str::FromStr, sync::Arc};
|
use std::{str::FromStr, sync::Arc};
|
||||||
use youmubot_prelude::*;
|
use youmubot_prelude::{stream::FuturesUnordered, *};
|
||||||
|
|
||||||
mod announcer;
|
mod announcer;
|
||||||
pub(crate) mod beatmap_cache;
|
pub(crate) mod beatmap_cache;
|
||||||
|
@ -728,12 +728,11 @@ async fn get_user(ctx: &Context, msg: &Message, mut args: Args, mode: Mode) -> C
|
||||||
let oppai = data.get::<BeatmapCache>().unwrap();
|
let oppai = data.get::<BeatmapCache>().unwrap();
|
||||||
match user {
|
match user {
|
||||||
Some(u) => {
|
Some(u) => {
|
||||||
let best = match osu
|
let bests = osu
|
||||||
.user_best(UserID::ID(u.id), |f| f.limit(1).mode(mode))
|
.user_best(UserID::ID(u.id), |f| f.limit(100).mode(mode))
|
||||||
.await?
|
.await?;
|
||||||
.into_iter()
|
let map_length = calculate_weighted_map_length(&bests, cache, mode).await?;
|
||||||
.next()
|
let best = match bests.into_iter().next() {
|
||||||
{
|
|
||||||
Some(m) => {
|
Some(m) => {
|
||||||
let beatmap = cache.get_beatmap(m.beatmap_id, mode).await?;
|
let beatmap = cache.get_beatmap(m.beatmap_id, mode).await?;
|
||||||
let info = oppai
|
let info = oppai
|
||||||
|
@ -752,7 +751,7 @@ async fn get_user(ctx: &Context, msg: &Message, mut args: Args, mode: Mode) -> C
|
||||||
"{}: here is the user that you requested",
|
"{}: here is the user that you requested",
|
||||||
msg.author
|
msg.author
|
||||||
))
|
))
|
||||||
.embed(user_embed(u, best)),
|
.embed(user_embed(u, map_length, best)),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
@ -762,3 +761,26 @@ async fn get_user(ctx: &Context, msg: &Message, mut args: Args, mode: Mode) -> C
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(in crate::discord) async fn calculate_weighted_map_length(
|
||||||
|
from_scores: impl IntoIterator<Item = &Score>,
|
||||||
|
cache: &BeatmapMetaCache,
|
||||||
|
mode: Mode,
|
||||||
|
) -> Result<f64> {
|
||||||
|
from_scores
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, s)| async move {
|
||||||
|
let beatmap = cache.get_beatmap(s.beatmap_id, mode).await?;
|
||||||
|
const SCALING_FACTOR: f64 = 0.975;
|
||||||
|
Ok(beatmap
|
||||||
|
.difficulty
|
||||||
|
.apply_mods(s.mods, 0.0 /* dont care */)
|
||||||
|
.drain_length
|
||||||
|
.as_secs_f64()
|
||||||
|
* (SCALING_FACTOR.powi(i as i32)))
|
||||||
|
})
|
||||||
|
.collect::<FuturesUnordered<_>>()
|
||||||
|
.try_fold(0.0, |a, b| future::ready(Ok(a + b)))
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue