diff --git a/Cargo.lock b/Cargo.lock index 2c6a8ad..3753ff9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -371,15 +371,6 @@ dependencies = [ "serde", ] -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -582,31 +573,6 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" -[[package]] -name = "h2" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 1.9.3", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[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.0" @@ -623,7 +589,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" dependencies = [ - "hashbrown 0.14.0", + "hashbrown", ] [[package]] @@ -685,17 +651,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.0-rc.2" @@ -715,7 +670,7 @@ dependencies = [ "bytes", "futures-util", "http", - "http-body 1.0.0-rc.2", + "http-body", "pin-project-lite", ] @@ -731,30 +686,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hyper" -version = "0.14.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body 0.4.5", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.4.9", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.0.0-rc.3" @@ -766,7 +697,7 @@ dependencies = [ "futures-core", "futures-util", "http", - "http-body 1.0.0-rc.2", + "http-body", "httparse", "httpdate", "itoa", @@ -786,16 +717,6 @@ dependencies = [ "unicode-normalization", ] -[[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.0.0" @@ -803,7 +724,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown", ] [[package]] @@ -812,12 +733,6 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" -[[package]] -name = "ipnet" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" - [[package]] name = "itertools" version = "0.10.5" @@ -853,7 +768,7 @@ dependencies = [ "figment", "futures-util", "http-body-util", - "hyper 1.0.0-rc.3", + "hyper", "lazy_static", "mgmt-api", "nom", @@ -862,7 +777,6 @@ dependencies = [ "proto-irc", "quick-xml", "regex", - "reqwest", "rustls-pemfile", "serde", "serde_json", @@ -950,12 +864,6 @@ dependencies = [ "serde", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1354,40 +1262,6 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" -[[package]] -name = "reqwest" -version = "0.11.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body 0.4.5", - "hyper 0.14.27", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - [[package]] name = "ring" version = "0.16.20" @@ -1552,18 +1426,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "sha1" version = "0.10.5" @@ -1618,7 +1480,18 @@ dependencies = [ name = "sim-irc" version = "0.0.1-dev" dependencies = [ + "anyhow", + "clap", + "http-body-util", + "hyper", + "mgmt-api", "proto-irc", + "rand", + "serde", + "serde_json", + "tokio", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1636,16 +1509,6 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.3" @@ -1727,7 +1590,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.0.0", + "indexmap", "log", "memchr", "once_cell", @@ -1999,7 +1862,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.3", + "socket2", "tokio-macros", "windows-sys", ] @@ -2025,20 +1888,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - [[package]] name = "toml" version = "0.7.6" @@ -2066,19 +1915,13 @@ version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap 2.0.0", + "indexmap", "serde", "serde_spanned", "toml_datetime", "winnow", ] -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - [[package]] name = "tracing" version = "0.1.37" @@ -2282,18 +2125,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.87" @@ -2436,16 +2267,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys", -] - [[package]] name = "yansi" version = "1.0.0-rc.1" diff --git a/Cargo.toml b/Cargo.toml index 702da58..bf1679d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,10 @@ anyhow = "1.0.68" # error utils nonempty = "0.8.1" clap = { version = "4.4.4", features = ["derive"] } serde = { version = "1.0.152", features = ["rc", "serde_derive"] } +tracing = "0.1.37" # logging & tracing api +tracing-subscriber = "0.3.16" +http-body-util = "0.1.0-rc.3" +serde_json = "1.0.93" [package] name = "lavina" @@ -29,12 +33,12 @@ publish = false anyhow.workspace = true figment = { version = "0.10.8", features = ["env", "toml"] } # configuration files hyper = { version = "1.0.0-rc.3,<1.0.0-rc.4", features = ["server", "http1"] } # http server -http-body-util = "0.1.0-rc.3" +http-body-util.workspace = true serde.workspace = true -serde_json = "1.0.93" +serde_json.workspace = true tokio.workspace = true -tracing = "0.1.37" # logging & tracing api -tracing-subscriber = "0.3.16" +tracing.workspace = true +tracing-subscriber.workspace = true futures-util.workspace = true prometheus = { version = "0.13.3", default-features = false } regex = "1.7.1" @@ -54,4 +58,3 @@ clap.workspace = true [dev-dependencies] assert_matches.workspace = true regex = "1.7.1" -reqwest = { version = "0.11", default-features = false } diff --git a/crates/sim-irc/Cargo.toml b/crates/sim-irc/Cargo.toml index bf777d1..c465d11 100644 --- a/crates/sim-irc/Cargo.toml +++ b/crates/sim-irc/Cargo.toml @@ -5,3 +5,14 @@ version.workspace = true [dependencies] proto-irc = { path = "../proto-irc" } +mgmt-api = { path = "../mgmt-api" } +clap.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true +rand = "0.8.5" +tokio.workspace = true +anyhow.workspace = true +hyper = { version = "1.0.0-rc.3,<1.0.0-rc.4", features = ["client", "http1"] } +http-body-util.workspace = true +serde.workspace = true +serde_json = "1.0.93" diff --git a/crates/sim-irc/src/main.rs b/crates/sim-irc/src/main.rs index e7a11a9..1c1ea44 100644 --- a/crates/sim-irc/src/main.rs +++ b/crates/sim-irc/src/main.rs @@ -1,3 +1,126 @@ -fn main() { - println!("Hello, world!"); +use anyhow::Result; +use clap::Parser; +use http_body_util::Full; +use hyper::body::{Bytes, Incoming}; +use hyper::client::conn::http1::SendRequest; +use hyper::{Request, Response}; +use rand::prelude::Distribution; +use rand::{distributions::Uniform, Rng}; +use serde::Serialize; +use std::net::SocketAddr; +use std::sync::Arc; +use tokio::io::{AsyncWriteExt, BufReader}; +use tokio::net::tcp::{ReadHalf, WriteHalf}; +use tokio::net::TcpStream; +use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; + +#[derive(Parser)] +struct CliArgs { + /// Management API address + #[arg(long)] + mgmt: SocketAddr, + /// IRC server address + #[arg(long)] + irc: SocketAddr, +} + +#[tokio::main] +async fn main() -> Result<()> { + tracing_subscriber::fmt::init(); + let args = CliArgs::parse(); + let mut gen = rand::thread_rng(); + + tracing::info!("Starting"); + let stream = TcpStream::connect(args.mgmt).await?; + let (mut request_sender, connection) = hyper::client::conn::http1::handshake(stream).await?; + tracing::info!("Mgmt connected"); + + let fiber = tokio::spawn(async move { + if let Err(e) = connection.await { + eprintln!("Error in connection: {}", e); + } + }); + + let name = generate_player_name(&mut gen); + let pass = generate_password(&mut gen); + { + let v = mgmt_api::CreatePlayerRequest { name: &*name }; + let response = http_send(&mut request_sender, mgmt_api::paths::CREATE_PLAYER, &v).await?; + assert!(response.status().is_success()); + tracing::info!("Player {} created", name); + } + { + let v = mgmt_api::ChangePasswordRequest { + player_name: &*name, + password: &*pass, + }; + let response = http_send(&mut request_sender, mgmt_api::paths::SET_PASSWORD, &v).await?; + assert!(response.status().is_success()); + tracing::info!("Password set for {}", name); + } + drop(request_sender); + fiber.await?; + + let mut stream = TcpStream::connect(args.irc).await?; + tracing::info!("IRC connected"); + let (reader, writer) = stream.split(); + let reader = BufReader::new(reader); + let test_scope = TestScope { reader, writer, buffer: vec![] }; + + test_scope.send(&format!("PASS {pass}")).await?; + test_scope.send(&format!("NICK {name}")).await?; + test_scope.send(&format!("USER UserName 0 * :Real Name")).await?; + + stream.shutdown().await?; + Ok(()) +} + +struct TestScope<'a> { + reader: BufReader>, + writer: WriteHalf<'a>, + buffer: Vec, +} +impl<'a> TestScope<'a> { + async fn send(&mut self, str: &(impl AsRef + ?Sized)) -> Result<()> { + self.writer.write_all(str.as_ref().as_bytes()).await?; + self.writer.write_all(b"\r\n").await?; + self.writer.flush().await?; + Ok(()) + } + + async fn assert(&mut self, f: impl FnOnce(&str) -> Result<()>) -> Result<()> { + let len = self.reader.read_until(b'\n', &mut self.buffer).await?; + let res = f(std::str::from_utf8(&self.buffer[0..len])?); + self.buffer.clear(); + res + } +} + +async fn http_send( + client: &mut SendRequest>, + path: &str, + payload: &impl Serialize, +) -> Result> { + let mut buffer = vec![]; + serde_json::to_writer(&mut buffer, payload).expect("unexpected fail when writing to vec"); + let body = Full::new(Bytes::from(buffer)); + let request = Request::builder().method("POST").uri(path).body(body)?; + let response = client.send_request(request).await?; + Ok(response) +} + +fn generate_player_name(gen: &mut impl Rng) -> Arc { + let len = Uniform::from(7..14).sample(gen); + gen.sample_iter(Uniform::from('a'..'z')) + .take(len) + .collect::() + .into() +} + +fn generate_password(gen: &mut impl Rng) -> Arc { + let len = Uniform::from(8..32).sample(gen); + gen.sample_iter(Uniform::from('0'..'z')) + .take(len) + .collect::() + .into() }