smol bot
| -rw-r--r-- | Cargo.lock | 32 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/bot/logic.rs | 2 | ||||
| -rw-r--r-- | src/bot/map.rs | 73 | ||||
| -rw-r--r-- | src/bot/mod.rs | 28 | ||||
| -rw-r--r-- | src/bot/usage.md | 2 |
6 files changed, 99 insertions, 40 deletions
@@ -330,7 +330,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.2", + "hashbrown", "lock_api", "once_cell", "parking_lot_core", @@ -562,9 +562,9 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "h2" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -572,7 +572,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", @@ -581,12 +581,6 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" @@ -696,22 +690,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown", ] [[package]] @@ -865,9 +849,9 @@ dependencies = [ [[package]] name = "mindus" -version = "5.0.9" +version = "5.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1fa02a69a433e46bb555bfeef159157c62f9142d9367a1bf7db4dba8d47b8" +checksum = "a4c7d314106dc8eb8f3d3ca42cf2204787fc49835cdce3be4675e2fe413f8510" dependencies = [ "amap", "base64 0.21.5", @@ -944,7 +928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28e5c341ef78a228e47a551bfd15ff885d8c501af49f953358763a538c01f14d" dependencies = [ "bitvec", - "indexmap 2.1.0", + "indexmap", "libdeflater", "log", "rgb", @@ -39,6 +39,8 @@ lto = "thin" [profile.dev.package.mindus] opt-level = 3 +debug-assertions = false [profile.dev.package.fimg] opt-level = 3 +debug-assertions = false diff --git a/src/bot/logic.rs b/src/bot/logic.rs index 30631fb..3175e7e 100644 --- a/src/bot/logic.rs +++ b/src/bot/logic.rs @@ -27,7 +27,7 @@ pub async fn run( v.run(); v.output() }) - .map_err(|e| format!("{}", e.diagnose(&block.code)).replace("`", "\u{200b}`")) + .map_err(|e| format!("{}", e.diagnose(&block.code)).replace('`', "\u{200b}`")) }) .await? { diff --git a/src/bot/map.rs b/src/bot/map.rs new file mode 100644 index 0000000..43165f4 --- /dev/null +++ b/src/bot/map.rs @@ -0,0 +1,73 @@ +use anyhow::Result; +use mindus::{data::map::ReadError, *}; +use poise::serenity_prelude::*; +use std::borrow::Cow; +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("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, |m| { m.add_file(AttachmentType::Bytes { data: Cow::from(png), filename: "map.png".to_string() }).embed(|e| e.title(&name).footer(|f| f.text(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(()) +} diff --git a/src/bot/mod.rs b/src/bot/mod.rs index 656d806..79b44d6 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -1,4 +1,5 @@ mod logic; +mod map; mod schematic; use anyhow::Result; @@ -57,23 +58,21 @@ impl Bot { { return Ok(()); } - if let ControlFlow::Break(m) = schematic::with( - Msg { - author: new_message - .author_nick(c) - .await - .unwrap_or(new_message.author.name.clone()), - attachments: new_message.attachments.clone(), - content: new_message.content.clone(), - channel: new_message.channel_id, - }, - c, - ) - .await? - { + let m = Msg { + author: new_message + .author_nick(c) + .await + .unwrap_or(new_message.author.name.clone()), + attachments: new_message.attachments.clone(), + content: new_message.content.clone(), + channel: new_message.channel_id, + }; + if let ControlFlow::Break(m) = schematic::with(m, c).await? { d.tracker.insert(new_message.id, m); return Ok(()); } + // not tracked, as you cant add a attachment afterwwards. + map::with(new_message, c).await?; } poise::Event::MessageUpdate { event, .. } => { let MessageUpdateEvent { @@ -148,7 +147,6 @@ impl Bot { } }); Ok(Data { tracker }) - // todo: voting::fixall() auto }) }); f.run().await.unwrap(); diff --git a/src/bot/usage.md b/src/bot/usage.md index 51b55aa..edf534e 100644 --- a/src/bot/usage.md +++ b/src/bot/usage.md @@ -3,6 +3,8 @@ upload a file, with a msch extension (eg `24tpi_imp.msch`) and a schematic preview will be generated. you may instead upload a message containing a base64 encoded schematic. +you can also upload maps, eg `salt_flats.msav`. + commands: - `eval`: executes mlog. see `/help eval` for more info. |