smol bot
Diffstat (limited to 'src/bot/map.rs')
| -rw-r--r-- | src/bot/map.rs | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/src/bot/map.rs b/src/bot/map.rs index 4188fc9..0c6e3aa 100644 --- a/src/bot/map.rs +++ b/src/bot/map.rs @@ -97,25 +97,74 @@ async fn render(m: Map, deser_took: Duration) -> (Timings, Vec<u8>) { .unwrap() } +pub async fn find( + msg: &Message, + c: &serenity::client::Context, +) -> Result<Option<(String, Map, Duration)>> { + match scour(msg).await? { + None => Ok(None), + Some((Err(e), _)) => { + msg.reply(c, string(e)).await?; + Ok(None) + } + Some((Ok(m), deser_took)) => Ok(Some(( + msg.author_nick(c).await.unwrap_or(msg.author.name.clone()), + m, + deser_took, + ))), + } +} + pub async fn with(msg: &Message, c: &serenity::client::Context) -> Result<()> { - let auth = msg.author_nick(c).await.unwrap_or(msg.author.name.clone()); - let (m, deser_took) = match scour(msg).await? { - None => return Ok(()), - Some((Err(e), _)) => return Ok(drop(msg.reply(c, string(e)).await?)), - Some((Ok(m), deser_took)) => (m, deser_took), + let Some((auth, m, deser_took)) = find(msg, c).await? else { + return Ok(()); }; let t = msg.channel_id.start_typing(&c.http); - let name = strip_colors(m.tags.get("name").or(m.tags.get("mapname")).unwrap()); - let ( - Timings { - deser_took, - render_took, - compression_took, - total, - }, - png, - ) = render(m, deser_took).await; + let (png, embed) = embed(m, &auth, deser_took).await; t.stop(); - msg.channel_id.send_message(c,CreateMessage::new().add_file(CreateAttachment::bytes(png,"map.png")).embed(CreateEmbed::new().title(&name).footer(CreateEmbedFooter::new(format!("render of {name} (requested by {auth}) took: {:.3}s (deser: {}ms, render: {:.3}s, compression: {:.3}s)", total.as_secs_f32(), deser_took.as_millis(), render_took.as_secs_f32(), compression_took.as_secs_f32()))).attachment("map.png").color(SUCCESS))).await?; + msg.channel_id + .send_message(c, CreateMessage::new().add_file(png).embed(embed)) + .await?; + Ok(()) +} + +async fn embed(m: Map, auth: &str, deser_took: Duration) -> (CreateAttachment, CreateEmbed) { + let name = strip_colors(m.tags.get("name").or(m.tags.get("mapname")).unwrap()); + let (timings, png) = render(m, deser_took).await; + ( + CreateAttachment::bytes(png, "map.png"), + CreateEmbed::new() + .title(&name) + .footer(footer((&name, auth), timings)) + .attachment("map.png") + .color(SUCCESS), + ) +} + +fn footer( + (name, auth): (&str, &str), + Timings { + deser_took, + render_took, + compression_took, + total, + }: Timings, +) -> CreateEmbedFooter { + CreateEmbedFooter::new(format!("render of {name} (requested by {auth}) took: {:.3}s (deser: {}ms, render: {:.3}s, compression: {:.3}s)", total.as_secs_f32(), deser_took.as_millis(), render_took.as_secs_f32(), compression_took.as_secs_f32())) +} + +#[poise::command( + context_menu_command = "Render map", + install_context = "User", + interaction_context = "Guild|PrivateChannel" +)] +/// Renders map inside a message. +pub async fn render_message(c: super::Context<'_>, m: Message) -> Result<()> { + let Some((auth, m, deser_took)) = find(&m, c.serenity_context()).await? else { + poise::say_reply(c, "no map").await?; + return Ok(()); + }; + let (png, embed) = embed(m, &auth, deser_took).await; + poise::send_reply(c, CreateReply::default().attachment(png).embed(embed)).await?; Ok(()) } |