smol bot
Diffstat (limited to 'src/bot/schematic.rs')
| -rw-r--r-- | src/bot/schematic.rs | 115 |
1 files changed, 57 insertions, 58 deletions
diff --git a/src/bot/schematic.rs b/src/bot/schematic.rs index 736af7e..ea863c1 100644 --- a/src/bot/schematic.rs +++ b/src/bot/schematic.rs @@ -1,3 +1,4 @@ +use crate::bot::repos; use crate::emoji; use anyhow::Result; use base64::Engine; @@ -58,24 +59,7 @@ pub async fn reply(v: Schem, author: &str, avatar: &str) -> Result<CreateReply> println!("rend {name}"); Ok(CreateReply::default() .attachment(CreateAttachment::bytes(p, "image.png")) - .embed({ - let mut e = CreateEmbed::new() - .attachment("image.png") - .author(CreateEmbedAuthor::new(author).icon_url(avatar)); - if let Some(tags) = tags(&v) { - e = e.field("tags", tags, true); - } - if let Some(v) = v - .tags - .get("description") - .map(|t| emoji::mindustry::to_discord(&strip_colors(t))) - { - e = e.description(v); - } - e.field("req", cost(&v), true) - .title(name.clone()) - .color(SUCCESS) - })) + .embed(e(author, avatar, &v).title(name))) } fn tags(v: &Schem) -> Option<String> { @@ -99,6 +83,30 @@ fn cost(v: &Schem) -> String { s } +fn e(author: &str, avatar: &str, v: &Schem) -> CreateEmbed { + let mut e = CreateEmbed::new() + .attachment("image.png") + .author(CreateEmbedAuthor::new(author).icon_url(avatar)); + if let Some(tags) = tags(&v) { + e = e.field("tags", tags, true); + } + if let Some(v) = v + .tags + .get("description") + .map(|t| emoji::mindustry::to_discord(&strip_colors(t))) + { + e = e.description(v); + } + let f = if v.width == v.height { + format!("{}²={}", v.width, v.width * v.height) + } else { + format!("{}×{}={}", v.height, v.width, v.width * v.height) + }; + e.field("req", cost(&v), true) + .footer(CreateEmbedFooter::new(f)) + .color(SUCCESS) +} + pub async fn send( m: Msg, c: &serenity::client::Context, @@ -111,30 +119,7 @@ pub async fn send( println!("rend {name}"); let msg = CreateMessage::new() .add_file(CreateAttachment::bytes(p, "image.png")) - .embed({ - let mut e = CreateEmbed::new() - .attachment("image.png") - .author(CreateEmbedAuthor::new(m.author).icon_url(m.avatar)); - if let Some(tags) = tags(&v) { - e = e.field("tags", tags, true); - } - if let Some(v) = v - .tags - .get("description") - .map(|t| emoji::mindustry::to_discord(&strip_colors(t))) - { - e = e.description(v); - } - let f = if v.width == v.height { - format!("{}²={}", v.width, v.width * v.height) - } else { - format!("{}×{}={}", v.height, v.width, v.width * v.height) - }; - e.field("req", cost(&v), true) - .title(name.clone()) - .footer(CreateEmbedFooter::new(f)) - .color(SUCCESS) - }); + .embed(e(&m.author, &m.avatar, &v).title(name.clone())); let h = m.channel.send_message(c, msg).await?; Ok((h, name, v)) } @@ -142,7 +127,7 @@ pub async fn send( pub async fn with( m: Msg, c: &serenity::client::Context, - labels: Option<String>, + labels: Option<super::Type>, ) -> Result<ControlFlow<(Message, String, Schem), ()>> { if let Ok(Some(mut v)) = from((&m.content, &m.attachments)).await { super::data::push_j(serde_json::json! {{ @@ -153,10 +138,21 @@ pub async fn with( "guild": m.guild, "channel": m.channel.get(), }}); - if let Some(mut x) = labels { - if x.contains("find unit factory") { - use emoji::to_mindustry::named::*; - x = super::tags(&[v + if let Some(super::Type::Basic(x)) = labels { + use emoji::to_mindustry::named::*; + let x = if let Some(i) = x.iter().position(|x| x == &repos::L) { + let mut x = x.to_vec(); + if v.block_iter().any(|x| { + x.1.block == &mindus::block::ADVANCED_LAUNCH_PAD + || x.1.block == &mindus::block::LAUNCH_PAD + }) { + x[i] = ADVANCED_LAUNCH_PAD; + } else { + x.remove(i); + } + super::tags(&x) + } else if x.contains(&"find unit factory") { + super::tags(&[v .block_iter() .find_map(|x| match x.1.block.name() { "air-factory" => Some(AIR_FACTORY), @@ -164,8 +160,10 @@ pub async fn with( "naval-factory" => Some(NAVAL_FACTORY), _ => None, }) - .unwrap_or(AIR_FACTORY)]); - } + .unwrap_or(AIR_FACTORY)]) + } else { + super::tags(x) + }; v.schem.tags.insert("labels".into(), x); }; return Ok(ControlFlow::Break(send(m, c, v).await?)); @@ -180,22 +178,18 @@ pub fn to_png(s: &Schematic) -> Vec<u8> { pub async fn from(m: (&str, &[Attachment])) -> Result<Option<Schem>> { match from_msg(m.0) { - x @ Ok(Some(_)) => x, + x @ Ok(Some(_)) => Ok(x?), // .or _ => from_attachments(m.1).await, } } -pub fn from_msg(msg: &str) -> Result<Option<Schem>> { - let schem_text = match RE - .captures_iter(msg) +pub fn from_msg(msg: &str) -> Result<Option<Schem>, R64Error> { + RE.captures_iter(msg) .map(|x| x.get(0).unwrap().as_str()) .find(|x| x.starts_with("bXNjaA")) - { - None => return Ok(None), - Some(x) => x, - }; - Ok(Some(from_b64(schem_text)?)) + .map(from_b64) + .transpose() } pub fn from_b64(schem_text: &str) -> std::result::Result<Schem, R64Error> { @@ -219,6 +213,11 @@ fn decode_tags(tags: &str) -> Vec<String> { let mut next = || lexer.find_map(|x| x.ok()); assert_eq!(next().unwrap(), Tokens::Open); while let Some(Tokens::String(x)) = next() { + let x = match x.trim() { + super::repos::SRP => "<:serpulo:1395767515950612593>", + super::repos::ERE => "<:erekir:1395767762957369484>", + _ => x, + }; t.push(emoji::mindustry::to_discord(x)); } assert_eq!(lexer.next(), None); |