Show actual stars for oppai-enabled maps

This commit is contained in:
Natsu Kagami 2020-06-13 22:19:05 -04:00
parent c43f9067b8
commit 20571d35de
Signed by: nki
GPG key ID: 73376E117CD20735

View file

@ -225,6 +225,7 @@ impl FromStr for Nth {
fn list_plays(plays: &[Score], mode: Mode, ctx: Context, m: &Message) -> CommandResult { fn list_plays(plays: &[Score], mode: Mode, ctx: Context, m: &Message) -> CommandResult {
let watcher = ctx.data.get_cloned::<ReactionWatcher>(); let watcher = ctx.data.get_cloned::<ReactionWatcher>();
let osu = ctx.data.get_cloned::<OsuClient>(); let osu = ctx.data.get_cloned::<OsuClient>();
let beatmap_cache = ctx.data.get_cloned::<BeatmapCache>();
if plays.is_empty() { if plays.is_empty() {
m.reply(&ctx, "No plays found")?; m.reply(&ctx, "No plays found")?;
@ -235,7 +236,10 @@ fn list_plays(plays: &[Score], mode: Mode, ctx: Context, m: &Message) -> Command
const ITEMS_PER_PAGE: usize = 5; const ITEMS_PER_PAGE: usize = 5;
let total_pages = (plays.len() + ITEMS_PER_PAGE - 1) / ITEMS_PER_PAGE; let total_pages = (plays.len() + ITEMS_PER_PAGE - 1) / ITEMS_PER_PAGE;
watcher.paginate_fn(ctx, m.channel_id, |page, e| { watcher.paginate_fn(
ctx,
m.channel_id,
|page, e| {
let page = page as usize; let page = page as usize;
let start = page * ITEMS_PER_PAGE; let start = page * ITEMS_PER_PAGE;
let end = plays.len().min(start + ITEMS_PER_PAGE); let end = plays.len().min(start + ITEMS_PER_PAGE);
@ -246,42 +250,93 @@ fn list_plays(plays: &[Score], mode: Mode, ctx: Context, m: &Message) -> Command
let plays = &plays[start..end]; let plays = &plays[start..end];
let beatmaps = { let beatmaps = {
let b = &mut beatmaps[start..end]; let b = &mut beatmaps[start..end];
b.par_iter_mut().enumerate().map( b.par_iter_mut()
|(i, v)| v.get_or_insert_with( .enumerate()
|| osu.beatmaps(BeatmapRequestKind::Beatmap(plays[i].beatmap_id), |f| f) .map(|(i, v)| {
v.get_or_insert_with(|| {
if let Some(b) = osu
.beatmaps(BeatmapRequestKind::Beatmap(plays[i].beatmap_id), |f| f)
.ok() .ok()
.and_then(|v| v.into_iter().next()) .and_then(|v| v.into_iter().next())
.map(|b| format!( {
let stars = beatmap_cache
.get_beatmap(b.beatmap_id)
.ok()
.and_then(|b| {
mode.to_oppai_mode().and_then(|mode| {
b.get_info_with(Some(mode), plays[i].mods).ok()
})
})
.map(|info| info.stars as f64)
.unwrap_or(b.difficulty.stars);
format!(
"[{:.1}*] {} - {} [{}] (#{})", "[{:.1}*] {} - {} [{}] (#{})",
b.difficulty.stars, b.artist, b.title, b.difficulty_name, b.beatmap_id)) stars, b.artist, b.title, b.difficulty_name, b.beatmap_id
.unwrap_or("FETCH FAILED".to_owned()))).collect::<Vec<_>>() )
} else {
"FETCH_FAILED".to_owned()
}
})
})
.collect::<Vec<_>>()
}; };
let /*mods width*/ mw = plays.iter().map(|v| v.mods.to_string().len()).max().unwrap().max(4); /*mods width*/
let /*beatmap names*/ bw = beatmaps.iter().map(|v| v.len()).max().unwrap().max(7); let mw = plays
.iter()
.map(|v| v.mods.to_string().len())
.max()
.unwrap()
.max(4);
/*beatmap names*/
let bw = beatmaps.iter().map(|v| v.len()).max().unwrap().max(7);
let mut m = MessageBuilder::new(); let mut m = MessageBuilder::new();
// Table header // Table header
m.push_line(format!(" # | pp | accuracy | rank | {:mw$} | {:bw$}", "mods", "beatmap", mw = mw, bw = bw)); m.push_line(format!(
m.push_line(format!("---------------------------------{:-<mw$}---{:-<bw$}", "", "", mw = mw, bw = bw)); " # | pp | accuracy | rank | {:mw$} | {:bw$}",
"mods",
"beatmap",
mw = mw,
bw = bw
));
m.push_line(format!(
"---------------------------------{:-<mw$}---{:-<bw$}",
"",
"",
mw = mw,
bw = bw
));
// Each row // Each row
for (id, (play, beatmap)) in plays.iter().zip(beatmaps.iter()).enumerate() { for (id, (play, beatmap)) in plays.iter().zip(beatmaps.iter()).enumerate() {
m.push_line( m.push_line(format!(
format!(
"{:>3} | {:>6} | {:>8} | {:^4} | {:mw$} | {:bw$}", "{:>3} | {:>6} | {:>8} | {:^4} | {:mw$} | {:bw$}",
id + start + 1, id + start + 1,
play.pp.map(|v| format!("{:.2}", v)).unwrap_or("-".to_owned()), play.pp
.map(|v| format!("{:.2}", v))
.unwrap_or("-".to_owned()),
format!("{:.2}%", play.accuracy(mode)), format!("{:.2}%", play.accuracy(mode)),
play.rank.to_string(), play.mods.to_string(), beatmap, mw = mw, bw = bw)); play.rank.to_string(),
play.mods.to_string(),
beatmap,
mw = mw,
bw = bw
));
} }
// End // End
let table = m.build().replace("```", "\\`\\`\\`"); let table = m.build().replace("```", "\\`\\`\\`");
let mut m = MessageBuilder::new(); let mut m = MessageBuilder::new();
m m.push_codeblock(table, None).push_line(format!(
.push_codeblock(table, None) "Page **{}/{}**",
.push_line(format!("Page **{}/{}**", page + 1, total_pages)) page + 1,
.push_line("Note: star difficulty don't reflect mods applied."); total_pages
));
if let None = mode.to_oppai_mode() {
m.push_line("Note: star difficulty don't reflect mods applied.");
}
(e.content(m.build()), Ok(())) (e.content(m.build()), Ok(()))
}, std::time::Duration::from_secs(60)) },
std::time::Duration::from_secs(60),
)
} }
#[command] #[command]