smol bot
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use anyhow::Result;
use mindus::{data::map::ReadError, *};
use poise::serenity_prelude::*;
use std::time::Instant;

use super::{strip_colors, SUCCESS};

pub async fn with(msg: &Message, c: &serenity::client::Context) -> Result<()> {
    let auth = msg.author_nick(c).await.unwrap_or(msg.author.name.clone());
    for a in &msg.attachments {
        if a.filename.ends_with("msav") {
            let s = a.download().await?;
            let then = Instant::now();

            macro_rules! dang {
                ($fmt:literal $(, $args:expr)+) => {{
                    msg.reply_ping(c, format!($fmt $(, $args)+)).await?;
                    return Ok(());
                }};
            }
            // could ignore, but i think if you have a msav, you dont want to ignore failures.
            let m = match Map::deserialize(&mut mindus::data::DataRead::new(&s)) {
                Ok(m) => m,
                Err(ReadError::Decompress(_) | ReadError::Header(_)) => {
                    dang!("`{}` is not a map.", a.filename)
                }
                Err(ReadError::NoSuchBlock(b)) => dang!(
                    "couldnt find block `{b}`. error originates from `{}`",
                    a.filename
                ),
                Err(ReadError::Version(v)) => {
                    dang!(
                        "unsupported version: `{v}`. supported versions: `7`. error originates from `{}`",
                        a.filename
                    )
                }
                Err(ReadError::Read(r)) => {
                    dang!(
                        "failed to read map. error: `{r}`. originates from `{}`",
                        a.filename
                    )
                }
                Err(ReadError::ReadState(r)) => {
                    dang!(
                        "failed to read dyn data in map. error: `{r}`. originates from `{}`",
                        a.filename
                    )
                }
            };
            let t = msg.channel_id.start_typing(&c.http);
            let deser_took = then.elapsed();
            let name = strip_colors(m.tags.get("name").or(m.tags.get("mapname")).unwrap());
            let (render_took, compression_took, total, png) =
                tokio::task::spawn_blocking(move || {
                    let render_took = Instant::now();
                    let i = m.render();
                    let render_took = render_took.elapsed();
                    let compression_took = Instant::now();
                    let png = super::png(i);
                    let compression_took = compression_took.elapsed();
                    let total = then.elapsed();
                    (render_took, compression_took, total, png)
                })
                .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?;
            return Ok(());
        }
    }

    Ok(())
}