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,53 +236,107 @@ 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(
let page = page as usize; ctx,
let start = page * ITEMS_PER_PAGE; m.channel_id,
let end = plays.len().min(start + ITEMS_PER_PAGE); |page, e| {
if start >= end { let page = page as usize;
return (e, Err(Error::from("No more pages"))); let start = page * ITEMS_PER_PAGE;
} let end = plays.len().min(start + ITEMS_PER_PAGE);
if start >= end {
return (e, Err(Error::from("No more pages")));
}
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)| {
.ok() v.get_or_insert_with(|| {
.and_then(|v| v.into_iter().next()) if let Some(b) = osu
.map(|b| format!( .beatmaps(BeatmapRequestKind::Beatmap(plays[i].beatmap_id), |f| f)
"[{:.1}*] {} - {} [{}] (#{})", .ok()
b.difficulty.stars, b.artist, b.title, b.difficulty_name, b.beatmap_id)) .and_then(|v| v.into_iter().next())
.unwrap_or("FETCH FAILED".to_owned()))).collect::<Vec<_>>() {
}; let stars = beatmap_cache
let /*mods width*/ mw = plays.iter().map(|v| v.mods.to_string().len()).max().unwrap().max(4); .get_beatmap(b.beatmap_id)
let /*beatmap names*/ bw = beatmaps.iter().map(|v| v.len()).max().unwrap().max(7); .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}*] {} - {} [{}] (#{})",
stars, b.artist, b.title, b.difficulty_name, b.beatmap_id
)
} else {
"FETCH_FAILED".to_owned()
}
})
})
.collect::<Vec<_>>()
};
/*mods width*/
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$}",
// Each row "mods",
for (id, (play, beatmap)) in plays.iter().zip(beatmaps.iter()).enumerate() { "beatmap",
m.push_line( mw = mw,
format!( bw = bw
));
m.push_line(format!(
"---------------------------------{:-<mw$}---{:-<bw$}",
"",
"",
mw = mw,
bw = bw
));
// Each row
for (id, (play, beatmap)) in plays.iter().zip(beatmaps.iter()).enumerate() {
m.push_line(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(),
// End beatmap,
let table = m.build().replace("```", "\\`\\`\\`"); mw = mw,
let mut m = MessageBuilder::new(); bw = bw
m ));
.push_codeblock(table, None) }
.push_line(format!("Page **{}/{}**", page + 1, total_pages)) // End
.push_line("Note: star difficulty don't reflect mods applied."); let table = m.build().replace("```", "\\`\\`\\`");
(e.content(m.build()), Ok(())) let mut m = MessageBuilder::new();
}, std::time::Duration::from_secs(60)) m.push_codeblock(table, None).push_line(format!(
"Page **{}/{}**",
page + 1,
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(()))
},
std::time::Duration::from_secs(60),
)
} }
#[command] #[command]