diff options
-rw-r--r-- | Cargo.lock | 36 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 142 |
3 files changed, 118 insertions, 61 deletions
@@ -367,9 +367,30 @@ dependencies = [ [[package]] name = "enumset" version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" +dependencies = [ + "enumset_derive 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "enumset" +version = "1.1.2" source = "git+https://github.com/Lymia/enumset#4a0c8e126896bc430f225d5e22fab61a1cc96fc0" dependencies = [ - "enumset_derive", + "enumset_derive 0.8.1 (git+https://github.com/Lymia/enumset)", +] + +[[package]] +name = "enumset_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +dependencies = [ + "darling 0.20.1", + "proc-macro2", + "quote", + "syn 2.0.18", ] [[package]] @@ -705,7 +726,7 @@ dependencies = [ "cgmath", "collision", "delegate", - "enumset", + "enumset 1.1.2 (git+https://github.com/Lymia/enumset)", "mt_rudp", "mt_ser", "thiserror", @@ -727,12 +748,12 @@ dependencies = [ [[package]] name = "mt_ser" version = "0.1.0" -source = "git+https://github.com/minetest-rust/mt_ser#87dbe32644a66dc4be2c3cf82d47d62f2907405f" +source = "git+https://github.com/minetest-rust/mt_ser#a6d41bb35d76f0533dc1e273d8ab8094c0dc4869" dependencies = [ "byteorder", "cgmath", "collision", - "enumset", + "enumset 1.1.2 (git+https://github.com/Lymia/enumset)", "flate2", "mt_ser_derive", "paste", @@ -743,7 +764,7 @@ dependencies = [ [[package]] name = "mt_ser_derive" version = "0.1.0" -source = "git+https://github.com/minetest-rust/mt_ser#87dbe32644a66dc4be2c3cf82d47d62f2907405f" +source = "git+https://github.com/minetest-rust/mt_ser#a6d41bb35d76f0533dc1e273d8ab8094c0dc4869" dependencies = [ "convert_case", "darling 0.14.4", @@ -1216,6 +1237,7 @@ name = "texmodbot" version = "0.1.0" dependencies = [ "clap", + "enumset 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util", "mt_auth", "mt_net", @@ -1244,9 +1266,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.28.1" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg 1.1.0", "libc", @@ -10,3 +10,4 @@ tokio = { version = "1.25.0", features = ["rt", "rt-multi-thread", "signal"] } mt_auth = { git = "https://github.com/minetest-rust/mt_auth" } clap = { version = "4.3.0", features = ["derive"] } futures-util = "0.3.28" +enumset = "1.1.2" diff --git a/src/main.rs b/src/main.rs index ec73e73..d5741f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ use clap::Parser; +use enumset::{EnumSet, EnumSetType}; use futures_util::future::OptionFuture; -use mt_net::{ReceiverExt, SenderExt, ToCltPkt, ToSrvPkt}; +use mt_auth::Auth; +use mt_net::{CltSender, ReceiverExt, SenderExt, ToCltPkt, ToSrvPkt}; use std::pin::Pin; use std::time::Duration; use tokio::time::{sleep, Sleep}; @@ -16,9 +18,9 @@ struct Args { #[clap(short, long, value_parser)] quit_after_seconds: Option<f32>, - /// Quit after having received node definitions + /// Quit after having received item and node definitions #[clap(short = 'Q', long, value_parser, default_value_t = false)] - quit_after_nodes: bool, + quit_after_defs: bool, /// Player name #[clap(short, long, value_parser, default_value = "texmodbot")] @@ -29,19 +31,94 @@ struct Args { password: String, } +#[derive(EnumSetType)] +enum DefType { + NodeDef, + ItemDef, +} + +struct Bot { + conn: CltSender, + quit_after_defs: bool, + auth: Auth, + pending: EnumSet<DefType>, +} + +impl Bot { + fn got_def(&mut self, def: DefType) { + self.pending.remove(def); + if self.quit_after_defs && self.pending.is_empty() { + self.conn.close() + } + } + + async fn handle_pkt(&mut self, pkt: ToCltPkt) { + use ToCltPkt::*; + + self.auth.handle_pkt(&pkt).await; + + let print_texture = |tex: &String| { + if !tex.is_empty() { + println!("{tex}"); + } + }; + + match pkt { + NodeDefs(defs) => { + defs.0 + .values() + .flat_map(|def| { + std::iter::empty() + .chain(&def.tiles) + .chain(&def.special_tiles) + .chain(&def.overlay_tiles) + }) + .map(|tile| &tile.texture.name) + .for_each(print_texture); + + self.got_def(DefType::NodeDef); + } + ItemDefs { defs, .. } => { + defs.iter() + .flat_map(|def| { + [ + &def.inventory_image, + &def.wield_image, + &def.inventory_overlay, + &def.wield_overlay, + ] + }) + .for_each(print_texture); + + self.got_def(DefType::ItemDef); + } + Kick(reason) => { + eprintln!("kicked: {reason}"); + } + _ => {} + } + } +} + #[tokio::main] async fn main() { let Args { address, quit_after_seconds, - quit_after_nodes, + quit_after_defs, username, password, } = Args::parse(); let (tx, mut rx, worker) = mt_net::connect(&address).await.unwrap(); - let mut auth = mt_auth::Auth::new(tx.clone(), username, password, "en_US"); + let mut bot = Bot { + auth: Auth::new(tx.clone(), username, password, "en_US"), + conn: tx, + quit_after_defs, + pending: EnumSet::all(), + }; + let worker = tokio::spawn(worker.run()); let mut quit_sleep: Option<Pin<Box<Sleep>>> = quit_after_seconds.and_then(|x| { @@ -57,53 +134,10 @@ async fn main() { pkt = rx.recv() => match pkt { None => break, Some(Err(e)) => eprintln!("{e}"), - Some(Ok(pkt)) => { - use ToCltPkt::*; - - auth.handle_pkt(&pkt).await; - - match pkt { - NodeDefs(defs) => { - defs.0 - .values() - .flat_map(|def| { - std::iter::empty() - .chain(&def.tiles) - .chain(&def.special_tiles) - .chain(&def.overlay_tiles) - }) - .map(|tile| &tile.texture.name) - .for_each(|texture| { - if !texture.is_empty() { - println!("{texture}"); - } - }); - - if quit_after_nodes { - tx.close(); - } - } - ItemDefs{defs, aliases: _} => { - defs.into_iter() - .for_each(|itemdef| { - [itemdef.inventory_image, itemdef.wield_image, itemdef.inventory_overlay, itemdef.wield_overlay] - .into_iter() - .for_each(|texture| - if !texture.is_empty() { - println!("{texture}"); - } - ); - }); - } - Kick(reason) => { - eprintln!("kicked: {reason}"); - } - _ => {} - } - } + Some(Ok(pkt)) => bot.handle_pkt(pkt).await, }, - _ = auth.poll() => { - tx + _ = bot.auth.poll() => { + bot.conn .send(&ToSrvPkt::CltReady { major: 0, minor: 0, @@ -114,12 +148,12 @@ async fn main() { }) .await .unwrap(); - }, + } Some(_) = OptionFuture::from(quit_sleep.as_mut()) => { - tx.close(); + bot.conn.close(); } _ = tokio::signal::ctrl_c() => { - tx.close(); + bot.conn.close(); } } } |