smol bot
| -rw-r--r-- | Cargo.toml | 6 | ||||
| -rw-r--r-- | src/bot/map.rs | 5 | ||||
| -rw-r--r-- | src/bot/mod.rs | 121 | ||||
| -rw-r--r-- | src/bot/repos.rs | 111 | ||||
| -rw-r--r-- | src/bot/schematic.rs | 115 | ||||
| -rw-r--r-- | src/bot/search.rs | 2 |
6 files changed, 208 insertions, 152 deletions
@@ -63,7 +63,11 @@ sled = { version = "0.34.7", features = ["compression"] } remapper = { version = "0.1.0", path = "../remapper" } implicit-fn = "0.1.0" sql = "0.4.3" -charts-rs = { version = "0.3.24", features = ["image", "image-encoder", "resvg"] } +charts-rs = { version = "0.3.24", features = [ + "image", + "image-encoder", + "resvg", +] } [features] server = ["axum"] diff --git a/src/bot/map.rs b/src/bot/map.rs index 99e6906..2ae4450 100644 --- a/src/bot/map.rs +++ b/src/bot/map.rs @@ -21,7 +21,7 @@ fn string((x, f): (ReadError, &str)) -> String { format!("couldnt find block at index `{b}`. mods are not supported") } ReadError::Version(v) => { - format!("unsupported version: `{v}`. supported versions: `7, 8`.",) + format!("unsupported version: `{v}`. supported versions: `7-11`.",) } ReadError::Read(r) => { format!("failed to read map. error: `{r}`. originates from `{f}`") @@ -29,6 +29,9 @@ fn string((x, f): (ReadError, &str)) -> String { ReadError::ReadState(r) => { format!("failed to read dyn data in map. error: `{r}`. originates from `{f}`") } + ReadError::NoBlockWithData => { + format!("no block with data") + } } } diff --git a/src/bot/mod.rs b/src/bot/mod.rs index 548b674..01d0074 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -18,6 +18,7 @@ use mindus::data::DataWrite; use poise::{CreateReply, serenity_prelude::*}; use repos::{FORUMS, Repo, SPECIAL, THREADED}; use serenity::futures::StreamExt; +use core::panic; use std::collections::{HashMap, HashSet}; use std::fmt::Write; use std::fs::read_to_string; @@ -55,7 +56,7 @@ pub struct Data { // message -> resp tracker: Arc<DashMap<MessageId, Message>>, } - +#[derive(Clone)] pub struct Msg { avatar: String, author: String, @@ -100,18 +101,24 @@ pub struct Ch { #[derive(Clone, Debug)] enum Type { Basic(&'static [&'static str]), - Assembled(String), + Owned(Vec<String>), Forum(()), // &'static phf::Map<&'static str, &'static [&'static str]> } +impl Type { + fn r(&self) -> Option<String> { + match self { + Type::Basic(x) => Some(tags(x)), + Type::Forum(_) => None, + Type::Owned(x) => Some(tags(x)), + } + + } +} -fn sep(x: Option<&Ch>) -> (Option<&'static str>, Option<String>, Option<&Repo>) { +fn sep(x: Option<&Ch>) -> (Option<&'static str>, Option<Type>, Option<&Repo>) { ( x.map(|x| x.d), - x.and_then(|x| match x.ty.clone() { - Type::Basic(x) => Some(tags(x)), - Type::Forum(_) => None, - Type::Assembled(x) => Some(x), - }), + x.map(|x| x.ty.clone()), x.map(|x| x.repo), ) } @@ -153,7 +160,7 @@ pub async fn scour( .await .insert(msg.id.get(), (msg.author.name.clone(), msg.author.id.get())); repo.write(d, msg.id, x); - repo.commit(&who, &format!("add {:x}.msch", msg.id.get())); + repo.commit(&who, msg.author.id, &format!("add {:x}.msch", msg.id.get())); msg.react(c, emojis::get!(MERGE)).await?; n += 1; } @@ -185,7 +192,7 @@ async fn del( if let Ok(s) = git.schem(dir, deleted_message_id.into()) { let own = git.own().await.erase(deleted_message_id).unwrap(); git.remove(dir, deleted_message_id.into()); - git.commit("plent", &format!("remove {deleted_message_id:x}")); + git.commit("plent", 0u64, &format!("remove {deleted_message_id:x}")); git.push(); if git == &repos::DESIGN_IT && !cfg!(debug_assertions) { send(c, |x| { @@ -264,7 +271,20 @@ async fn handle_message( content: new_message.content.clone(), channel: new_message.channel_id, }; - let x = schematic::with(m, c, l).await?; + let mut x = ControlFlow::Continue(()); + for m_ in &new_message.message_snapshots { + let m = Msg { + content: m_.content.clone(), + attachments: m_.attachments.clone(), + ..m.clone() + }; + if x.is_continue() { + x = schematic::with(m, c, l.clone()).await?; + }; + } + if x.is_continue() { + x = schematic::with(m, c, l).await?; + } match x { ControlFlow::Continue(()) if THREADED.contains(&new_message.channel_id.get()) @@ -310,7 +330,7 @@ async fn handle_message( } repo.write(dir, new_message.id, s); repo.add(); - repo.commit(&who, &format!("add {:x}.msch", new_message.id.get())); + repo.commit(&who, new_message.author.id, &format!("add {:x}.msch", new_message.id.get())); repo.push(); new_message.react(c, emojis::get!(MERGE)).await?; } @@ -336,7 +356,28 @@ impl Bot { std::env::var("TOKEN").unwrap_or_else(|_| read_to_string("token").expect("wher token")); let f = poise::Framework::builder() .options(poise::FrameworkOptions { - commands: vec![logic::run(), lb(), logic::run_file(), sorter::sorter(), sorter::mapper(), schembrowser_instructions(), lb_no_vds(), ping(), help(), scour(), search::search(), search::file(), rename(), rename_file(), render(), render_file(), render_message(), map::render_message(), stats()], + commands: vec![ + logic::run(), + lb(), + logic::run_file(), + sorter::sorter(), + sorter::mapper(), + schembrowser_instructions(), + lb_no_vds(), + ping(), + help(), + scour(), + search::search(), + search::file(), + rename(), + rename_file(), + render(), + render_file(), + render_message(), + map::render_message(), + stats(), + retag() + ], event_handler: |c, e, _, d| { Box::pin(async move { match e { @@ -394,7 +435,7 @@ impl Bot { let who = nick.as_deref().unwrap_or(&user.name); let own = ownership::get(git).await.erase(*message_id).unwrap(); git.remove(dir, *message_id); - git.commit(who, &format!("remove {:x}.msch", message_id.get())); + git.commit(who, m.author.id, &format!("remove {:x}.msch", message_id.get())); git.push(); _ = m.delete_reaction(c,Some(1174262682573082644.into()), emojis::get!(MERGE)).await; m.delete_reaction(c,Some(1174262682573082644.into()), ReactionType::Custom { animated: false, id: 1192316518395039864.into(), name: Some("merge".into()) }).await.unwrap(); @@ -424,7 +465,7 @@ impl Bot { .filter(|x| { thread.applied_tags.contains(&x.id) }).map(|x| x.name.clone()).collect::<Vec<_>>(); - EXTRA.insert(thread.id.get(), Ch { repo, d, ty: Type::Assembled(tags(&*tg)) }); + EXTRA.insert(thread.id.get(), Ch { repo, d, ty: Type::Owned(tg) }); } FullEvent::MessageUpdate {event: MessageUpdateEvent { author: Some(author), @@ -470,7 +511,7 @@ impl Bot { ).await; } git.write(dir, *id, s); - git.commit(&who,&format!("update {:x}.msch", id.get())); + git.commit(&who, author.id, &format!("update {:x}.msch", id.get())); git.push(); } } @@ -532,7 +573,7 @@ impl Bot { .await?; poise::builtins::register_in_guild( ctx, - &[search::search(), lb(), lb_no_vds(), search::file()], + &[search::search(), lb(), lb_no_vds(), search::file(), retag()], 925674713429184564.into(), ) .await?; @@ -602,24 +643,28 @@ impl Bot { // Ok(()) // } -// #[poise::command(slash_command)] -// pub async fn retag(c: Context<'_>, channel: ChannelId) -> Result<()> { -// if c.author().id != OWNER { -// poise::say_reply(c, "access denied. this incident will be reported").await?; -// return Ok(()); -// } -// c.defer().await?; -// let tags = tags(SPECIAL[&channel.get()].labels); -// for schem in search::dir(channel.get()).unwrap() { -// let mut s = search::load(&schem); -// let mut v = DataWrite::default(); -// s.tags.insert("labels".into(), tags.clone()); -// s.serialize(&mut v)?; -// std::fs::write(schem, v.consume())?; -// } -// c.reply(emoji::named::OK).await?; -// Ok(()) -// } +#[poise::command(slash_command)] +pub async fn retag(c: Context<'_>) -> Result<()> { + if c.author().id != OWNER { + poise::say_reply(c, "access denied. this incident will be reported").await?; + return Ok(()); + } + c.defer().await?; + for (&channel, x) in repos::SPECIAL.into_iter().filter(|x| { + x.1.repo == &repos::DESIGN_IT + }) { + let (_, Some(tags), _) = sep(Some(x)) else { panic!() }; + let Some(tags) = tags.r() else { panic!() }; + for schem in search::dir(channel).into_iter().flatten() { + let mut s = search::load(&schem); + let mut v = DataWrite::default(); + s.tags.insert("labels".into(), tags.clone()); + s.serialize(&mut v)?; + std::fs::write(schem, v.consume())?; + }} + c.reply(emoji::named::OK).await?; + Ok(()) +} // dbg!(m // .iter() @@ -927,7 +972,7 @@ pub async fn ping(c: Context<'_>) -> Result<()> { #[poise::command( slash_command, - install_context = "User", + install_context = "User|Guild", interaction_context = "Guild|BotDm|PrivateChannel" )] /// Renders base64 schematic. @@ -946,7 +991,7 @@ pub async fn render(c: Context<'_>, #[description = "schematic, base64"] s: Stri #[poise::command( slash_command, - install_context = "User", + install_context = "User|Guild", interaction_context = "Guild|BotDm|PrivateChannel" )] /// Renders map/msch schematic. @@ -1032,7 +1077,7 @@ async fn rename( #[poise::command( context_menu_command = "Render schematic", - install_context = "User", + install_context = "User|Guild", interaction_context = "Guild|PrivateChannel" )] /// Renders schematic inside a message. diff --git a/src/bot/repos.rs b/src/bot/repos.rs index cb4d595..d3a87b6 100644 --- a/src/bot/repos.rs +++ b/src/bot/repos.rs @@ -21,6 +21,10 @@ pub struct Repo { // possibly posters? } +// const EMAILMAP: phf::Map<u64, &str> = phf::phf_map! { +// 332054403160735765u64 => "[email protected]", +// }; + impl std::cmp::PartialEq for Repo { fn eq(&self, other: &Self) -> bool { self.name == other.name @@ -92,7 +96,7 @@ impl Repo { ); } - pub fn commit(&self, by: &str, msg: &str) { + pub fn commit(&self, by: &str, user_id: impl Into<u64>, msg: &str) { assert!( std::process::Command::new("git") .current_dir(self.repopath()) @@ -213,61 +217,62 @@ repos! { deny_emoji: 1395478597451518085u64, } } - +pub const ERE: &str = "[#ff9266][]"; +pub const SRP: &str = "[#854aff][]"; +pub const L: &str = "check for launch pad"; decl! { [1129391545418797147u64]; DESIGN_IT => [ -925721957209636914u64 => "cryofluid" : [CRYOFLUID, CRYOFLUID_MIXER], -925721791475904533u64 => "graphite" : [GRAPHITE, GRAPHITE_PRESS], -925721824556359720u64 => "metaglass" : [METAGLASS, KILN], -925721863525646356u64 => "phase-fabric" : [PHASEFABRIC, PHASE_WEAVER], -927036346869104693u64 => "plastanium" : [PLASTANIUM, PLASTANIUM_COMPRESSOR], -925736419983515688u64 => "pyratite" : [PYRATITE, PYRATITE_MIXER], -925736573037838397u64 => "blast-compound" : [BLASTCOMPOUND, BLAST_MIXER], -927793648417009676u64 => "scrap" : [DISASSEMBLER, SCRAP], -1198556531281637506u64 => "spore-press" : [OIL, SPORE_PRESS], -1200308146460180520u64 => "oil-extractor" : [OIL, OIL_EXTRACTOR], -1200301847387316317u64 => "rtg-gen" : [POWER, RTG_GENERATOR], -1200308292744921088u64 => "cultivator" : [SPOREPOD, CULTIVATOR], -1200305956689547324u64 => "graphite-multipress" : [GRAPHITE, MULTI_PRESS], -1200306409036857384u64 => "silicon-crucible" : [SILICON, SILICON_CRUCIBLE], -1198555991667646464u64 => "coal" : [COAL, COAL_CENTRIFUGE], -925721763856404520u64 => "silicon" : [SILICON, SILICON_SMELTER], -925721930814869524u64 => "surge-alloy" : [SURGEALLOY, SURGE_SMELTER], -1141034314163826879u64 => "defensive-outpost" : [""], -949529149800865862u64 => "drills" : [PRODUCTION], -925729855574794311u64 => "logic-schems" : [MICRO_PROCESSOR], -1185702384194818048u64 => "miscellaneous" : ["…"], -1018541701431836803u64 => "combustion-gen" : [POWER, COMBUSTION_GENERATOR], -927480650859184171u64 => "differential-gen" : [POWER, DIFFERENTIAL_GENERATOR], -925719985987403776u64 => "impact-reactor" : [POWER, IMPACT_REACTOR], -949740875817287771u64 => "steam-gen" : [POWER, STEAM_GENERATOR], -926163105694752811u64 => "thorium-reactor" : [POWER, THORIUM_REACTOR], -973234467357458463u64 => "carbide" : [CARBIDE, ""], -1198527267933007893u64 => "erekir-defensive-outpost" : [""], -973236445567410186u64 => "fissile-matter" : [FISSILEMATTER, ""], -1147887958351945738u64 => "electrolyzer" : [HYDROGEN, OZONE, ""], -1202001032503365673u64 => "nitrogen" : [NITROGEN, ""], -1202001055349477426u64 => "cyanogen" : [CYANOGEN, ""], -1096157669112418454u64 => "mass-driver" : ["…", PLANET], -973234248054104115u64 => "oxide" : [OXIDE, ""], -973422874734002216u64 => "erekir-phase" : [PHASEFABRIC, ""], -973369188800413787u64 => "ccc" : ["", POWER], -1218453338396430406u64 => "neoplasia-reactor": ["", POWER], -1218453292045172817u64 => "flux-reactor": ["", POWER], -1218452986788053012u64 => "pyrolisis-gen": ["", POWER], -1147722735305367572u64 => "silicon-arc" : [SILICON, ""], -974450769967341568u64 => "erekir-surge" : [SURGEALLOY, ""], -973241041685737532u64 => "erekir-units" : ["[#ff9266][]"], -1158818171139133490u64 => "unit-core" : [UNITS, CORE_NUCLEUS], -1158818324210274365u64 => "unit-delivery" : [UNITS, FLARE], -1158818598568075365u64 => "unit-raw" : [UNITS, PRODUCTION], -1142181013779398676u64 => "unit-sand" : [UNITS, SAND], -1222270513045438464u64 => "bore": [PRODUCTION], -1226407271978766356u64 => "pulveriser": [PULVERIZER, SAND], -1277138620863742003u64 => "melter": [MELTER, SLAG], -1277138532355543070u64 => "separator": [SEPARATOR, SCRAP], -1365819562259386533u64 => "launch-pad": [ADVANCED_LAUNCH_PAD] +925721957209636914u64 => "cryofluid" : [CRYOFLUID, CRYOFLUID_MIXER, SRP, L], +925721791475904533u64 => "graphite" : [GRAPHITE, GRAPHITE_PRESS, SRP, L], +925721824556359720u64 => "metaglass" : [METAGLASS, KILN, SRP, L], +925721863525646356u64 => "phase-fabric" : [PHASEFABRIC, PHASE_WEAVER, SRP, L], +927036346869104693u64 => "plastanium" : [PLASTANIUM, PLASTANIUM_COMPRESSOR, SRP, L], +925736419983515688u64 => "pyratite" : [PYRATITE, PYRATITE_MIXER, SRP, L], +925736573037838397u64 => "blast-compound" : [BLASTCOMPOUND, BLAST_MIXER, SRP, L], +927793648417009676u64 => "scrap" : [DISASSEMBLER, SCRAP, SRP, L], +1198556531281637506u64 => "spore-press" : [OIL, SPORE_PRESS, SRP, L], +1200308146460180520u64 => "oil-extractor" : [OIL, OIL_EXTRACTOR, SRP, L], +1200301847387316317u64 => "rtg-gen" : [POWER, RTG_GENERATOR, SRP, L], +1200308292744921088u64 => "cultivator" : [SPOREPOD, CULTIVATOR, SRP, L], +1200305956689547324u64 => "graphite-multipress" : [GRAPHITE, MULTI_PRESS, SRP, L], +1200306409036857384u64 => "silicon-crucible" : [SILICON, SILICON_CRUCIBLE, SRP, L], +1198555991667646464u64 => "coal" : [COAL, COAL_CENTRIFUGE, SRP, L], +925721763856404520u64 => "silicon" : [SILICON, SILICON_SMELTER, SRP, L], +925721930814869524u64 => "surge-alloy" : [SURGEALLOY, SURGE_SMELTER, SRP, L], +1141034314163826879u64 => "defensive-outpost" : ["", SRP, L], +949529149800865862u64 => "drills" : [PRODUCTION, SRP, L], +925729855574794311u64 => "logic-schems" : [MICRO_PROCESSOR, SRP, L], +1185702384194818048u64 => "miscellaneous" : ["…", SRP, L], +1018541701431836803u64 => "combustion-gen" : [POWER, COMBUSTION_GENERATOR, SRP, L], +927480650859184171u64 => "differential-gen" : [POWER, DIFFERENTIAL_GENERATOR, SRP, L], +925719985987403776u64 => "impact-reactor" : [POWER, IMPACT_REACTOR, SRP, L], +949740875817287771u64 => "steam-gen" : [POWER, STEAM_GENERATOR, SRP, L], +926163105694752811u64 => "thorium-reactor" : [POWER, THORIUM_REACTOR, SRP, L], +973234467357458463u64 => "carbide" : [CARBIDE, "", ERE, L], +1198527267933007893u64 => "erekir-defensive-outpost" : ["", ERE, L], +973236445567410186u64 => "fissile-matter" : [FISSILEMATTER, "", ERE, L], +1147887958351945738u64 => "electrolyzer" : [HYDROGEN, OZONE, "", ERE, L], +1202001032503365673u64 => "nitrogen" : [NITROGEN, "", ERE, L], +1202001055349477426u64 => "cyanogen" : [CYANOGEN, "", ERE, L], +1096157669112418454u64 => "mass-driver" : ["…", PLANET, ERE, L], +973234248054104115u64 => "oxide" : [OXIDE, "", ERE, L], +973422874734002216u64 => "erekir-phase" : [PHASEFABRIC, "", ERE, L], +973369188800413787u64 => "ccc" : ["", POWER, ERE, L], +1218453338396430406u64 => "neoplasia-reactor": ["", POWER, ERE, L], +1218453292045172817u64 => "flux-reactor": ["", POWER, ERE, L], +1218452986788053012u64 => "pyrolisis-gen": ["", POWER, ERE, L], +1147722735305367572u64 => "silicon-arc" : [SILICON, SILICON_ARCFURNACE, ERE, L], +974450769967341568u64 => "erekir-surge" : [SURGEALLOY, SURGE_CRUCIBLE, ERE, L], +973241041685737532u64 => "erekir-units" : [UNITS, ERE, L], +1158818171139133490u64 => "unit-core" : [UNITS, CORE_NUCLEUS, SRP, L], +1158818324210274365u64 => "unit-delivery" : [UNITS, FLARE, SRP, L], +1158818598568075365u64 => "unit-raw" : [UNITS, PRODUCTION, SRP, L], +1142181013779398676u64 => "unit-sand" : [UNITS, SAND, SRP, L], +1222270513045438464u64 => "bore": [PRODUCTION, ERE, L], +1226407271978766356u64 => "pulveriser": [PULVERIZER, SAND, SRP, L], +1277138620863742003u64 => "melter": [MELTER, SLAG, SRP, L], +1277138532355543070u64 => "separator": [SEPARATOR, SCRAP, SRP, L] ]; MISC => [ forum 1297452357549821972u64 => "s-defensive-outpost", 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); diff --git a/src/bot/search.rs b/src/bot/search.rs index 5fdcfb4..bab6494 100644 --- a/src/bot/search.rs +++ b/src/bot/search.rs @@ -123,7 +123,7 @@ pub struct Data { pub fn dir(x: u64) -> Option<impl Iterator<Item = PathBuf>> { std::fs::read_dir( Path::new("repos") - .join("cd8a83f57821034") + .join("DESIGN_IT") .join(super::SPECIAL[&x].d), ) .ok() |