html terminal
lemu
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | src/bot/logic.rs | 102 | ||||
| -rw-r--r-- | src/bot/maps.rs | 2 | ||||
| -rw-r--r-- | src/bot/mod.rs | 2 | ||||
| -rw-r--r-- | src/bot/schematic.rs | 2 | ||||
| -rw-r--r-- | src/bot/usage.md | 10 |
6 files changed, 117 insertions, 4 deletions
@@ -34,7 +34,7 @@ poise = "0.5.5" anyhow = "1.0.75" regex = { version = "1.8.4", features = ["std"], default-features = false } minify-js = "0.5.6" -itertools = "0.10.5" +itertools = "0.11" convert_case = "0.6.0" parse_duration = "2.1.1" serde = "1.0" @@ -44,6 +44,7 @@ mindus = { version = "4", features = [], default-features = false } oxipng = { git = "https://github.com/shssoichiro/oxipng", branch = "master", features = [], default-features = false } strip-ansi-escapes = "0.2.0" dashmap = "5.5.1" +lemu = { features = ["diagnose", "__send__"], default-features = false, version = "0.2.0" } [profile.release] strip = true diff --git a/src/bot/logic.rs b/src/bot/logic.rs new file mode 100644 index 0000000..0aba81b --- /dev/null +++ b/src/bot/logic.rs @@ -0,0 +1,102 @@ +use super::{Context, Result}; +use lemu::Executor; +use poise::{serenity_prelude::AttachmentType, KeyValueArgs}; +use regex::Regex; +use std::{borrow::Cow, sync::LazyLock}; + +#[poise::command(prefix_command, category = "Misc", track_edits, rename = "eval")] +pub async fn run( + ctx: Context<'_>, + #[description = "number of iterations"] kv: KeyValueArgs, + #[rest] + #[description = "Script"] + from: String, +) -> Result<()> { + let _ = ctx.channel_id().start_typing(&ctx.serenity_context().http); + + static RE: LazyLock<Regex> = + LazyLock::new(|| Regex::new(r#"```(arm|x86asm)?([^`]+)```"#).unwrap()); + + let lemu::Output { + output: Some(output), + displays, + .. + } = ({ + let mat = RE + .captures(&from) + .ok_or(anyhow::anyhow!(r#"no code found (use \`\`\`arm...\`\`\`."#))?; + let script = mat.get(2).unwrap().as_str(); + match Executor::with_output(vec![]) + .display() + .limit_iterations( + kv.get("iters") + .map_or(1, |v| v.parse::<usize>().unwrap_or(1).clamp(1, 50)), + ) + .limit_instructions(30000) + .program(&script) + { + Ok(mut v) => { + v.run(); + v.output() + } + Err(e) => { + let s = format!("{}", e.diagnose(script)).replace("`", "\u{200b}`"); + ctx.send(|c| { + c.allowed_mentions(|a| a.empty_parse()) + .content(format!("```ansi\n{s}\n```")) + }) + .await?; + return Ok(()); + } + } + }) + else { + unreachable!() + }; + let displays: Box<[_; 1]> = displays.try_into().unwrap(); + let [display] = *displays; + + ctx.send(|c| { + let mut empty = true; + if !output.is_empty() { + c.content(format!( + "```\n{}\n```", + String::from_utf8_lossy(&output).replace('`', "\u{200b}`") + )); + empty = false; + } + if display.buffer().iter().any(|&n| n != 0) { + let p = oxipng::RawImage::new( + display.width(), + display.height(), + oxipng::ColorType::RGBA, + oxipng::BitDepth::Eight, + display.take_buffer(), + ) + .unwrap(); + let p = p + .create_optimized_png(&oxipng::Options { + filter: oxipng::indexset! { oxipng::RowFilter::None }, + bit_depth_reduction: false, + color_type_reduction: false, + palette_reduction: false, + grayscale_reduction: false, + ..oxipng::Options::from_preset(0) + }) + .unwrap(); + c.attachment(AttachmentType::Bytes { + data: Cow::from(p), + filename: "display1.png".to_string(), + }); + c.embed(|e| e.attachment("display1.png")); + empty = false; + } + if empty { + c.content("no output"); + } + c.allowed_mentions(|a| a.empty_parse()) + }) + .await?; + + Ok(()) +} diff --git a/src/bot/maps.rs b/src/bot/maps.rs index 55b32da..fa00f58 100644 --- a/src/bot/maps.rs +++ b/src/bot/maps.rs @@ -112,7 +112,7 @@ impl MapImage { transparent_color: None, }, BitDepth::Eight, - i.buffer, + i.take_buffer(), ) .unwrap(); *lock = i diff --git a/src/bot/mod.rs b/src/bot/mod.rs index 81d259d..1a79f2e 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -2,6 +2,7 @@ mod admin; mod bans; mod config; mod js; +mod logic; pub mod maps; mod player; mod schematic; @@ -234,6 +235,7 @@ impl Bot { voting::list(), start(), end(), + logic::run(), help(), ], event_handler: |c, e, _, d| { diff --git a/src/bot/schematic.rs b/src/bot/schematic.rs index 2e1856c..2172927 100644 --- a/src/bot/schematic.rs +++ b/src/bot/schematic.rs @@ -89,7 +89,7 @@ pub fn to_png(s: &Schematic<'_>) -> Vec<u8> { transparent_color: None, }, BitDepth::Eight, - p.buffer, + p.take_buffer(), ) .unwrap(); p.create_optimized_png(&oxipng::Options { diff --git a/src/bot/usage.md b/src/bot/usage.md index 625ec42..a036e7e 100644 --- a/src/bot/usage.md +++ b/src/bot/usage.md @@ -1,4 +1,12 @@ ## Usage 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.
\ No newline at end of file +you may instead upload a message containing a base64 encoded schematic. + +## Eval + +type``` +>eval ```arm +print "xd" +``` +```for the bot to evaluate your MLOG
\ No newline at end of file |