smol bot
Diffstat (limited to 'src/bot/map.rs')
-rw-r--r--src/bot/map.rs81
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(())
}