diff --git a/Cargo.lock b/Cargo.lock index 5d412d3..597b51d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,12 +66,59 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "any_vec" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6ac04794a7749710e3c7f3c93222e3d04692993b69876d69393efd2565401a" + [[package]] name = "anyhow" version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +[[package]] +name = "apecs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6df7760d4baebb17003dcf99134d8e3a63f487e146d58911f0bcd27afb185d1c" +dependencies = [ + "any_vec", + "apecs-derive", + "async-channel", + "itertools", + "log", + "moongraph", + "parking_lot", + "rayon", + "smallvec", + "snafu 0.8.5", +] + +[[package]] +name = "apecs-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0f3ddfd31fd5276fb8039b75dc4d284c21213757a969e480c6ef8fde494f3b" +dependencies = [ + "moongraph-macros-syntax", + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "async-trait" version = "0.1.83" @@ -80,7 +127,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.90", ] [[package]] @@ -116,6 +163,17 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "broomdog" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ec65645d8167b03c07e049f114a878a11ab889f20c071d6f7b30bf88fbe5af" +dependencies = [ + "log", + "rustc-hash", + "snafu 0.8.5", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -162,10 +220,10 @@ version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn", + "syn 2.0.90", ] [[package]] @@ -181,13 +239,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] -name = "composition-core" +name = "composition" version = "0.1.0" dependencies = [ + "anyhow", + "apecs", + "async-trait", "base64", + "byteorder", "clap", - "composition-parsing", - "composition-protocol", "once_cell", "serde", "serde_json", @@ -201,35 +261,12 @@ dependencies = [ ] [[package]] -name = "composition-parsing" -version = "0.1.0" +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "byteorder", - "serde_json", - "thiserror 2.0.3", - "tracing", -] - -[[package]] -name = "composition-protocol" -version = "0.1.0" -dependencies = [ - "anyhow", - "byteorder", - "composition-parsing", - "serde", - "thiserror 2.0.3", - "tracing", -] - -[[package]] -name = "composition-world" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "composition-protocol", - "thiserror 2.0.3", + "crossbeam-utils", ] [[package]] @@ -241,12 +278,42 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "dagga" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cf0d7dcd307c9c5d81277737c35d1faf08af9e2cb262966a01c91021686b68" +dependencies = [ + "log", + "rustc-hash", + "snafu 0.7.5", +] + [[package]] name = "deranged" version = "0.3.11" @@ -256,12 +323,30 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "futures-core" version = "0.3.31" @@ -286,6 +371,12 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -308,6 +399,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.14" @@ -368,6 +468,30 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "moongraph" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5a4b09eb96a84205062b48ec5469c8c35c128167e838aa73dc620c4411af598" +dependencies = [ + "broomdog", + "dagga", + "log", + "rayon", + "snafu 0.8.5", +] + +[[package]] +name = "moongraph-macros-syntax" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08112087acc92cc28fb5d8f7bda1307123ecc9a275ed4835f1c03f1a8dd02c1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -458,6 +582,26 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.7" @@ -473,6 +617,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "ryu" version = "1.0.18" @@ -502,7 +652,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.90", ] [[package]] @@ -550,6 +700,49 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "snafu" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" +dependencies = [ + "doc-comment", + "snafu-derive 0.7.5", +] + +[[package]] +name = "snafu" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" +dependencies = [ + "snafu-derive 0.8.5", +] + +[[package]] +name = "snafu-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "snafu-derive" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "socket2" version = "0.5.8" @@ -566,6 +759,17 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.90" @@ -603,7 +807,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.90", ] [[package]] @@ -614,7 +818,7 @@ checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.90", ] [[package]] @@ -684,7 +888,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.90", ] [[package]] @@ -766,7 +970,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.90", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a97d017..6641554 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,7 @@ -[workspace] -members = ["crates/*"] -resolver = "2" - -[workspace.package] +[package] +name = "composition" +description = "An extremely fast Minecraft server" +build = "build.rs" version = "0.1.0" authors = ["Garen Tyler "] repository = "https://github.com/garentyler/composition" @@ -10,31 +9,28 @@ readme = "README.md" license = "MIT" edition = "2024" -[workspace.dependencies] +[[bin]] +name = "composition" +path = "src/main.rs" + +[features] +default = [] +update_1_20 = [] + +[dependencies] anyhow = "1.0.71" apecs = "0.8.4" async-trait = "0.1.68" +base64 = "0.22.1" byteorder = "1.4.3" -composition-core.path = "./crates/composition-core" -composition-parsing.path = "./crates/composition-parsing" -composition-protocol.path = "./crates/composition-protocol" -composition-world.path = "./crates/composition-world" +clap = { version = "4.2.7", features = ["derive"] } +once_cell = "1.17.1" serde = { version = "1.0.160", features = ["serde_derive"] } serde_json = "1.0.96" thiserror = "2.0.3" tokio = { version = "1.28.0", features = ["full"] } +tokio-util = "0.7.8" +toml = "0.8.19" tracing = { version = "0.1.37", features = ["log"] } - -# Unused but possibly useful dependencies: -# async-trait = "0.1.48" -# backtrace = "0.3.50" -# colorful = "0.2.1" -# ctrlc = "3.1.8" -# fastnbt = "*" -# futures = "0.3.28" -# mojang-api = "0.6.1" -# ozelot = "0.9.0" # Ozelot 0.9.0 supports protocol version 578 (1.15.2) -# quartz_nbt = { version = "0.2.6", features = ["serde"] } -# radix64 = "0.6.2" -# toml = "0.5.6" -# uuid = "0.8.2" +tracing-subscriber = { version = "0.3.17", features = ["tracing-log"] } +tracing-appender = "0.2.2" diff --git a/crates/composition-core/build.rs b/build.rs similarity index 100% rename from crates/composition-core/build.rs rename to build.rs diff --git a/crates/composition-core/Cargo.toml b/crates/composition-core/Cargo.toml deleted file mode 100644 index 7a6adf6..0000000 --- a/crates/composition-core/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "composition-core" -description = "An extremely fast Minecraft server" -build = "build.rs" -authors.workspace = true -edition.workspace = true -license.workspace = true -repository.workspace = true -version.workspace = true - -[[bin]] -name = "composition" -path = "src/main.rs" - -[features] -default = [] -update_1_20 = ["composition-protocol/update_1_20"] - -[dependencies] -base64 = "0.22.1" -clap = { version = "4.2.7", features = ["derive"] } -composition-parsing.workspace = true -composition-protocol.workspace = true -once_cell = "1.17.1" -serde.workspace = true -serde_json.workspace = true -thiserror.workspace = true -tokio.workspace = true -tokio-util = "0.7.8" -toml = "0.8.19" -tracing.workspace = true -tracing-subscriber = { version = "0.3.17", features = ["tracing-log"] } -tracing-appender = "0.2.2" diff --git a/crates/composition-parsing/Cargo.toml b/crates/composition-parsing/Cargo.toml deleted file mode 100644 index caab213..0000000 --- a/crates/composition-parsing/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "composition-parsing" -description = "Useful shared parsing functions" -authors.workspace = true -edition.workspace = true -license.workspace = true -repository.workspace = true -version.workspace = true - -[dependencies] -byteorder.workspace = true -serde_json.workspace = true -thiserror.workspace = true -tracing.workspace = true diff --git a/crates/composition-protocol/Cargo.toml b/crates/composition-protocol/Cargo.toml deleted file mode 100644 index e69b26b..0000000 --- a/crates/composition-protocol/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "composition-protocol" -description = "The Minecraft protocol implemented in a network-agnostic way" -authors.workspace = true -edition.workspace = true -license.workspace = true -repository.workspace = true -version.workspace = true - -[features] -default = [] -update_1_20 = [] - -[dependencies] -anyhow.workspace = true -byteorder.workspace = true -composition-parsing.workspace = true -serde.workspace = true -thiserror.workspace = true -tracing.workspace = true diff --git a/crates/composition-world/Cargo.toml b/crates/composition-world/Cargo.toml deleted file mode 100644 index ea36ee5..0000000 --- a/crates/composition-world/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "composition-world" -description = "A Minecraft world generator implementation that allows for custom worlds" -authors.workspace = true -edition.workspace = true -license.workspace = true -repository.workspace = true -version.workspace = true - -[dependencies] -anyhow.workspace = true -async-trait.workspace = true -composition-protocol.workspace = true -thiserror.workspace = true diff --git a/crates/composition-core/src/config.rs b/src/config.rs similarity index 96% rename from crates/composition-core/src/config.rs rename to src/config.rs index 213330b..536fb92 100644 --- a/crates/composition-core/src/config.rs +++ b/src/config.rs @@ -122,7 +122,12 @@ impl Config { #[tracing::instrument] fn write(&self, path: &Path) { trace!("Config.write()"); - if let Ok(mut file) = File::options().write(true).create(true).truncate(true).open(path) { + if let Ok(mut file) = File::options() + .write(true) + .create(true) + .truncate(true) + .open(path) + { if file .write_all(toml::to_string(&self).unwrap().as_bytes()) .is_ok() @@ -136,7 +141,12 @@ impl Config { #[tracing::instrument] fn write_server_icon(&self, path: &Path) { trace!("Config.write_server_icon()"); - if let Ok(mut file) = File::options().write(true).create(true).truncate(true).open(path) { + if let Ok(mut file) = File::options() + .write(true) + .create(true) + .truncate(true) + .open(path) + { if file.write_all(&self.server_icon_bytes).is_ok() { return; } diff --git a/crates/composition-core/src/error.rs b/src/error.rs similarity index 100% rename from crates/composition-core/src/error.rs rename to src/error.rs diff --git a/crates/composition-core/src/lib.rs b/src/lib.rs similarity index 79% rename from crates/composition-core/src/lib.rs rename to src/lib.rs index 1f31c54..6e28ff9 100644 --- a/crates/composition-core/src/lib.rs +++ b/src/lib.rs @@ -4,8 +4,12 @@ pub mod config; pub(crate) mod error; /// Network operations. pub(crate) mod net; +/// The Minecraft protocol implemented in a network-agnostic way. +pub mod protocol; /// The core server implementation. pub(crate) mod server; +/// A Minecraft world generator implementation that allows for custom worlds. +pub mod world; use crate::config::Config; use once_cell::sync::OnceCell; diff --git a/crates/composition-core/src/main.rs b/src/main.rs similarity index 80% rename from crates/composition-core/src/main.rs rename to src/main.rs index 22333ef..05b0def 100644 --- a/crates/composition-core/src/main.rs +++ b/src/main.rs @@ -3,20 +3,18 @@ use tracing_subscriber::prelude::*; #[tracing::instrument] pub fn main() { - composition_core::START_TIME + composition::START_TIME .set(std::time::Instant::now()) - .expect("could not set composition_core::START_TIME"); + .expect("could not set composition::START_TIME"); // Set up logging. - let file_writer = tracing_appender::rolling::daily( - &composition_core::config::Args::instance().log_dir, - "log", - ); + let file_writer = + tracing_appender::rolling::daily(&composition::config::Args::instance().log_dir, "log"); let (file_writer, _guard) = tracing_appender::non_blocking(file_writer); tracing_subscriber::registry() .with(tracing_subscriber::filter::LevelFilter::from_level( - composition_core::config::Args::instance() + composition::config::Args::instance() .log_level .unwrap_or(if cfg!(debug_assertions) { tracing::Level::DEBUG @@ -38,7 +36,7 @@ pub fn main() { .init(); // Load the config. - let config = composition_core::config::Config::load(); + let config = composition::config::Config::load(); match config.server_threads { Some(1) => { @@ -61,10 +59,10 @@ pub fn main() { .unwrap() .block_on(async move { info!("Starting {} on port {}", config.server_version, config.port); - let (mut server, running) = composition_core::start_server().await; + let (mut server, running) = composition::start_server().await; info!( "Done! Start took {:?}", - composition_core::START_TIME.get().unwrap().elapsed() + composition::START_TIME.get().unwrap().elapsed() ); // The main server loop. diff --git a/crates/composition-core/src/net.rs b/src/net.rs similarity index 92% rename from crates/composition-core/src/net.rs rename to src/net.rs index ef06006..4a041f8 100644 --- a/crates/composition-core/src/net.rs +++ b/src/net.rs @@ -1,7 +1,7 @@ -use composition_parsing::parsable::Parsable; -use composition_protocol::{ - packets::{serverbound::SL00LoginStart, GenericPacket}, +use crate::protocol::{ ClientState, + packets::{GenericPacket, serverbound::SL00LoginStart}, + parsing::parsable::Parsable, }; use std::{collections::VecDeque, sync::Arc, time::Instant}; use tokio::io::AsyncWriteExt; @@ -126,12 +126,12 @@ impl NetworkClient { } // TODO: Stream compression/encryption. #[tracing::instrument] - pub async fn read_packets(&mut self) -> composition_protocol::Result<()> { + pub async fn read_packets(&mut self) -> crate::protocol::Result<()> { trace!("NetworkClient.read_packet() id {}", self.id); if self.read_data().await.is_err() { self.disconnect(None).await; - return Err(composition_protocol::Error::Disconnected); + return Err(crate::protocol::Error::Disconnected); } self.incoming_data.make_contiguous(); @@ -148,7 +148,7 @@ impl NetworkClient { data = d; self.incoming_packet_queue.push_back(packet); } - Err(composition_parsing::Error::Eof) => break, + Err(crate::protocol::parsing::Error::Eof) => break, Err(e) => { // Remove the valid bytes before this packet. self.incoming_data = self.incoming_data.split_off(bytes_consumed); @@ -185,12 +185,12 @@ impl NetworkClient { self.outgoing_packet_queue.push_back(packet.into()); } #[tracing::instrument] - pub async fn send_queued_packets(&mut self) -> composition_protocol::Result<()> { + pub async fn send_queued_packets(&mut self) -> crate::protocol::Result<()> { let packets: Vec<_> = self.outgoing_packet_queue.drain(..).collect(); for packet in packets { self.send_packet(packet) .await - .map_err(|_| composition_protocol::Error::Disconnected)?; + .map_err(|_| crate::protocol::Error::Disconnected)?; } Ok(()) } @@ -218,8 +218,8 @@ impl NetworkClient { Ok(()) } #[tracing::instrument] - pub async fn disconnect(&mut self, reason: Option) { - use composition_protocol::packets::clientbound::{CL00Disconnect, CP17Disconnect}; + pub async fn disconnect(&mut self, reason: Option) { + use crate::protocol::packets::clientbound::{CL00Disconnect, CP17Disconnect}; let reason = reason.unwrap_or(serde_json::json!({ "text": "You have been disconnected!" })); diff --git a/crates/composition-protocol/src/blocks/mod.rs b/src/protocol/blocks/mod.rs similarity index 100% rename from crates/composition-protocol/src/blocks/mod.rs rename to src/protocol/blocks/mod.rs diff --git a/crates/composition-protocol/src/entities/cat.rs b/src/protocol/entities/cat.rs similarity index 89% rename from crates/composition-protocol/src/entities/cat.rs rename to src/protocol/entities/cat.rs index f3b51a2..c52115e 100644 --- a/crates/composition-protocol/src/entities/cat.rs +++ b/src/protocol/entities/cat.rs @@ -1,4 +1,4 @@ -use crate::mctypes::VarInt; +use crate::protocol::mctypes::VarInt; #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct Cat { diff --git a/crates/composition-protocol/src/entities/frog.rs b/src/protocol/entities/frog.rs similarity index 100% rename from crates/composition-protocol/src/entities/frog.rs rename to src/protocol/entities/frog.rs diff --git a/crates/composition-protocol/src/entities/metadata.rs b/src/protocol/entities/metadata.rs similarity index 98% rename from crates/composition-protocol/src/entities/metadata.rs rename to src/protocol/entities/metadata.rs index 53894d8..89818e1 100644 --- a/crates/composition-protocol/src/entities/metadata.rs +++ b/src/protocol/entities/metadata.rs @@ -1,4 +1,4 @@ -use crate::{ +use crate::protocol::{ blocks::BlockFace, mctypes::{Chat, Position, Uuid, VarInt}, }; diff --git a/crates/composition-protocol/src/entities/mod.rs b/src/protocol/entities/mod.rs similarity index 97% rename from crates/composition-protocol/src/entities/mod.rs rename to src/protocol/entities/mod.rs index aa36a4d..9266a52 100644 --- a/crates/composition-protocol/src/entities/mod.rs +++ b/src/protocol/entities/mod.rs @@ -7,11 +7,11 @@ pub mod player; pub mod sniffer; pub mod villager; -use crate::{ +use crate::protocol::parsing::{ParseResult, parsable::Parsable}; +use crate::protocol::{ blocks::BlockPosition, mctypes::{Chat, Uuid, VarInt}, }; -use composition_parsing::{parsable::Parsable, ParseResult}; pub type EntityId = VarInt; pub type EntityUuid = Uuid; diff --git a/crates/composition-protocol/src/entities/particle.rs b/src/protocol/entities/particle.rs similarity index 98% rename from crates/composition-protocol/src/entities/particle.rs rename to src/protocol/entities/particle.rs index b6ad7dd..54773bb 100644 --- a/crates/composition-protocol/src/entities/particle.rs +++ b/src/protocol/entities/particle.rs @@ -1,5 +1,5 @@ use super::EntityId; -use crate::mctypes::{Position, VarInt}; +use crate::protocol::mctypes::{Position, VarInt}; #[derive(Debug, Copy, Clone, PartialEq)] pub struct Particle { diff --git a/crates/composition-protocol/src/entities/player.rs b/src/protocol/entities/player.rs similarity index 94% rename from crates/composition-protocol/src/entities/player.rs rename to src/protocol/entities/player.rs index 94ef485..022e962 100644 --- a/crates/composition-protocol/src/entities/player.rs +++ b/src/protocol/entities/player.rs @@ -1,4 +1,4 @@ -use crate::mctypes::VarInt; +use crate::protocol::mctypes::VarInt; #[derive(Clone, Debug, PartialEq, Default)] pub struct Player { diff --git a/crates/composition-protocol/src/entities/sniffer.rs b/src/protocol/entities/sniffer.rs similarity index 90% rename from crates/composition-protocol/src/entities/sniffer.rs rename to src/protocol/entities/sniffer.rs index 6be27b2..b93d3af 100644 --- a/crates/composition-protocol/src/entities/sniffer.rs +++ b/src/protocol/entities/sniffer.rs @@ -1,4 +1,4 @@ -use crate::mctypes::VarInt; +use crate::protocol::mctypes::VarInt; #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct Sniffer { diff --git a/crates/composition-protocol/src/entities/villager.rs b/src/protocol/entities/villager.rs similarity index 95% rename from crates/composition-protocol/src/entities/villager.rs rename to src/protocol/entities/villager.rs index ff0826c..b8fa958 100644 --- a/crates/composition-protocol/src/entities/villager.rs +++ b/src/protocol/entities/villager.rs @@ -1,4 +1,4 @@ -use crate::mctypes::VarInt; +use crate::protocol::mctypes::VarInt; #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct Villager { diff --git a/crates/composition-protocol/src/error.rs b/src/protocol/error.rs similarity index 89% rename from crates/composition-protocol/src/error.rs rename to src/protocol/error.rs index 6288464..ef80e9a 100644 --- a/crates/composition-protocol/src/error.rs +++ b/src/protocol/error.rs @@ -13,9 +13,9 @@ pub enum Error { /// This error was caused by attempting to send or receive data from a disconnected client. #[error("communicating to disconnected client")] Disconnected, - /// This error is a wrapper for `composition_parsing::Error`. + /// This error is a wrapper for `crate::parsing::Error`. #[error(transparent)] - ParseError(#[from] composition_parsing::Error), + ParseError(#[from] crate::protocol::parsing::Error), /// This error is general purpose. /// When possible, other error variants should be used. #[error(transparent)] diff --git a/crates/composition-protocol/src/inventory/mod.rs b/src/protocol/inventory/mod.rs similarity index 100% rename from crates/composition-protocol/src/inventory/mod.rs rename to src/protocol/inventory/mod.rs diff --git a/crates/composition-protocol/src/inventory/slot.rs b/src/protocol/inventory/slot.rs similarity index 100% rename from crates/composition-protocol/src/inventory/slot.rs rename to src/protocol/inventory/slot.rs diff --git a/crates/composition-protocol/src/mctypes.rs b/src/protocol/mctypes.rs similarity index 82% rename from crates/composition-protocol/src/mctypes.rs rename to src/protocol/mctypes.rs index 87a111c..a7d34c5 100644 --- a/crates/composition-protocol/src/mctypes.rs +++ b/src/protocol/mctypes.rs @@ -1,10 +1,10 @@ -use composition_parsing::parsable::Parsable; +use crate::protocol::parsing::parsable::Parsable; /// Alias for a u128. pub type Uuid = u128; -pub use composition_parsing::VarInt; +pub use crate::protocol::parsing::VarInt; /// Alias for a `serde_json::Value`. -pub type Json = composition_parsing::serde_json::Value; +pub type Json = crate::protocol::parsing::serde_json::Value; /// Alias for a `Json`. pub type Chat = Json; @@ -23,7 +23,7 @@ impl Position { } impl Parsable for Position { #[tracing::instrument] - fn parse(data: &[u8]) -> composition_parsing::ParseResult<'_, Self> { + fn parse(data: &[u8]) -> crate::protocol::parsing::ParseResult<'_, Self> { let (data, i) = i64::parse(data)?; // x: i26, z: i26, y: i12 @@ -67,7 +67,7 @@ impl TryFrom for Difficulty { } impl Parsable for Difficulty { #[tracing::instrument] - fn parse(data: &[u8]) -> composition_parsing::ParseResult<'_, Self> { + fn parse(data: &[u8]) -> crate::protocol::parsing::ParseResult<'_, Self> { let (data, difficulty) = u8::parse(data)?; let difficulty: Difficulty = difficulty .try_into() @@ -87,13 +87,10 @@ mod tests { fn get_positions() -> Vec<(Position, Vec)> { vec![ // x: 01000110000001110110001100 z: 10110000010101101101001000 y: 001100111111 - ( - Position::new(18357644, 831, -20882616), - vec![ - 0b01000110, 0b00000111, 0b01100011, 0b00101100, 0b00010101, 0b10110100, - 0b10000011, 0b00111111, - ], - ), + (Position::new(18357644, 831, -20882616), vec![ + 0b01000110, 0b00000111, 0b01100011, 0b00101100, 0b00010101, 0b10110100, 0b10000011, + 0b00111111, + ]), ] } #[test] diff --git a/crates/composition-protocol/src/lib.rs b/src/protocol/mod.rs similarity index 97% rename from crates/composition-protocol/src/lib.rs rename to src/protocol/mod.rs index e08d0ed..31439cd 100644 --- a/crates/composition-protocol/src/lib.rs +++ b/src/protocol/mod.rs @@ -17,6 +17,8 @@ pub mod mctypes; /// and "Name" is the packet's name as found on [wiki.vg](https://wiki.vg/Protocol) in PascalCase. /// Examples include "SH00Handshake", "CP00SpawnEntity", and "SP11KeepAlive". pub mod packets; +/// Useful shared parsing functions. +pub mod parsing; pub use error::{Error, Result}; diff --git a/crates/composition-protocol/src/packets/clientbound/login.rs b/src/protocol/packets/clientbound/login.rs similarity index 66% rename from crates/composition-protocol/src/packets/clientbound/login.rs rename to src/protocol/packets/clientbound/login.rs index e2a0c5c..ea514b0 100644 --- a/crates/composition-protocol/src/packets/clientbound/login.rs +++ b/src/protocol/packets/clientbound/login.rs @@ -1,16 +1,16 @@ -use crate::mctypes::{Chat, Json, Uuid, VarInt}; -use composition_parsing::parsable::Parsable; +use crate::protocol::mctypes::{Chat, Json, Uuid, VarInt}; +use crate::protocol::parsing::parsable::Parsable; #[derive(Clone, Debug, PartialEq)] pub struct CL00Disconnect { pub reason: Chat, } -crate::packets::packet!( +crate::protocol::packets::packet!( CL00Disconnect, 0x00, - crate::ClientState::Login, + crate::protocol::ClientState::Login, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CL00Disconnect> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CL00Disconnect> { let (data, reason) = Json::parse(data)?; Ok((data, CL00Disconnect { reason })) }, @@ -23,24 +23,21 @@ pub struct CL01EncryptionRequest { pub public_key: Vec, pub verify_token: Vec, } -crate::packets::packet!( +crate::protocol::packets::packet!( CL01EncryptionRequest, 0x01, - crate::ClientState::Login, + crate::protocol::ClientState::Login, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CL01EncryptionRequest> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CL01EncryptionRequest> { let (data, server_id) = String::parse(data)?; let (data, public_key) = u8::parse_vec(data)?; let (data, verify_token) = u8::parse_vec(data)?; - Ok(( - data, - CL01EncryptionRequest { - server_id, - public_key, - verify_token, - }, - )) + Ok((data, CL01EncryptionRequest { + server_id, + public_key, + verify_token, + })) }, |packet: &CL01EncryptionRequest| -> Vec { let mut output = vec![]; @@ -65,18 +62,15 @@ pub struct CL02LoginSuccessProperty { } impl Parsable for CL02LoginSuccessProperty { #[tracing::instrument] - fn parse(data: &[u8]) -> composition_parsing::ParseResult<'_, Self> { + fn parse(data: &[u8]) -> crate::protocol::parsing::ParseResult<'_, Self> { let (data, name) = String::parse(data)?; let (data, value) = String::parse(data)?; let (data, signature) = String::parse_optional(data)?; - Ok(( - data, - CL02LoginSuccessProperty { - name, - value, - signature, - }, - )) + Ok((data, CL02LoginSuccessProperty { + name, + value, + signature, + })) } #[tracing::instrument] fn serialize(&self) -> Vec { @@ -87,24 +81,21 @@ impl Parsable for CL02LoginSuccessProperty { output } } -crate::packets::packet!( +crate::protocol::packets::packet!( CL02LoginSuccess, 0x02, - crate::ClientState::Login, + crate::protocol::ClientState::Login, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CL02LoginSuccess> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CL02LoginSuccess> { let (data, uuid) = Uuid::parse(data)?; let (data, username) = String::parse(data)?; let (data, properties) = CL02LoginSuccessProperty::parse_vec(data)?; - Ok(( - data, - CL02LoginSuccess { - uuid, - username, - properties, - }, - )) + Ok((data, CL02LoginSuccess { + uuid, + username, + properties, + })) }, |packet: &CL02LoginSuccess| -> Vec { let mut output = vec![]; @@ -119,12 +110,12 @@ crate::packets::packet!( pub struct CL03SetCompression { pub threshold: VarInt, } -crate::packets::packet!( +crate::protocol::packets::packet!( CL03SetCompression, 0x03, - crate::ClientState::Login, + crate::protocol::ClientState::Login, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CL03SetCompression> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CL03SetCompression> { let (data, threshold) = VarInt::parse(data)?; Ok((data, CL03SetCompression { threshold })) }, @@ -137,22 +128,19 @@ pub struct CL04LoginPluginRequest { pub channel: String, pub data: Vec, } -crate::packets::packet!( +crate::protocol::packets::packet!( CL04LoginPluginRequest, 0x04, - crate::ClientState::Login, + crate::protocol::ClientState::Login, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CL04LoginPluginRequest> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CL04LoginPluginRequest> { let (data, message_id) = VarInt::parse(data)?; let (data, channel) = String::parse(data)?; - Ok(( - data, - CL04LoginPluginRequest { - message_id, - channel, - data: data.to_vec(), - }, - )) + Ok((data, CL04LoginPluginRequest { + message_id, + channel, + data: data.to_vec(), + })) }, |packet: &CL04LoginPluginRequest| -> Vec { let mut output = vec![]; diff --git a/crates/composition-protocol/src/packets/clientbound/mod.rs b/src/protocol/packets/clientbound/mod.rs similarity index 100% rename from crates/composition-protocol/src/packets/clientbound/mod.rs rename to src/protocol/packets/clientbound/mod.rs diff --git a/crates/composition-protocol/src/packets/clientbound/play.rs b/src/protocol/packets/clientbound/play.rs similarity index 70% rename from crates/composition-protocol/src/packets/clientbound/play.rs rename to src/protocol/packets/clientbound/play.rs index 8ba993b..e4e9b1e 100644 --- a/crates/composition-protocol/src/packets/clientbound/play.rs +++ b/src/protocol/packets/clientbound/play.rs @@ -1,4 +1,4 @@ -use crate::{ +use crate::protocol::{ entities::{EntityPosition, EntityRotation, EntityVelocity}, mctypes::{Chat, Difficulty, Position, Uuid, VarInt}, }; @@ -14,12 +14,12 @@ pub struct CP00SpawnEntity { pub data: VarInt, pub velocity: EntityVelocity, } -crate::packets::packet!( +crate::protocol::packets::packet!( CP00SpawnEntity, 0x00, - crate::ClientState::Play, + crate::protocol::ClientState::Play, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CP00SpawnEntity> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CP00SpawnEntity> { let (data, id) = VarInt::parse(data)?; let (data, uuid) = Uuid::parse(data)?; let (data, kind) = VarInt::parse(data)?; @@ -29,19 +29,16 @@ crate::packets::packet!( let (data, d) = VarInt::parse(data)?; let (data, velocity) = EntityVelocity::parse(data)?; - Ok(( - data, - CP00SpawnEntity { - id, - uuid, - kind, - position, - rotation, - head_yaw, - data: d, - velocity, - }, - )) + Ok((data, CP00SpawnEntity { + id, + uuid, + kind, + position, + rotation, + head_yaw, + data: d, + velocity, + })) }, |packet: &CP00SpawnEntity| -> Vec { let mut output = vec![]; @@ -62,21 +59,18 @@ pub struct CP0BChangeDifficulty { pub difficulty: Difficulty, pub is_locked: bool, } -crate::packets::packet!( +crate::protocol::packets::packet!( CP0BChangeDifficulty, 0x0b, - crate::ClientState::Play, + crate::protocol::ClientState::Play, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CP0BChangeDifficulty> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CP0BChangeDifficulty> { let (data, difficulty) = Difficulty::parse(data)?; let (data, is_locked) = bool::parse(data)?; - Ok(( - data, - CP0BChangeDifficulty { - difficulty, - is_locked, - }, - )) + Ok((data, CP0BChangeDifficulty { + difficulty, + is_locked, + })) }, |packet: &CP0BChangeDifficulty| -> Vec { let mut output = vec![]; @@ -90,12 +84,12 @@ crate::packets::packet!( pub struct CP17Disconnect { pub reason: Chat, } -crate::packets::packet!( +crate::protocol::packets::packet!( CP17Disconnect, 0x17, - crate::ClientState::Play, + crate::protocol::ClientState::Play, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CP17Disconnect> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CP17Disconnect> { let (data, reason) = Chat::parse(data)?; Ok((data, CP17Disconnect { reason })) }, @@ -106,12 +100,12 @@ crate::packets::packet!( pub struct CP1FKeepAlive { pub payload: i64, } -crate::packets::packet!( +crate::protocol::packets::packet!( CP1FKeepAlive, 0x1f, - crate::ClientState::Play, + crate::protocol::ClientState::Play, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CP1FKeepAlive> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CP1FKeepAlive> { let (data, payload) = i64::parse(data)?; Ok((data, CP1FKeepAlive { payload })) }, @@ -125,25 +119,22 @@ pub struct CP21WorldEvent { pub data: i32, pub disable_relative_volume: bool, } -crate::packets::packet!( +crate::protocol::packets::packet!( CP21WorldEvent, 0x21, - crate::ClientState::Play, + crate::protocol::ClientState::Play, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CP21WorldEvent> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CP21WorldEvent> { let (data, event) = i32::parse(data)?; let (data, location) = Position::parse(data)?; let (data, d) = i32::parse(data)?; let (data, disable_relative_volume) = bool::parse(data)?; - Ok(( - data, - CP21WorldEvent { - event, - location, - data: d, - disable_relative_volume, - }, - )) + Ok((data, CP21WorldEvent { + event, + location, + data: d, + disable_relative_volume, + })) }, |packet: &CP21WorldEvent| -> Vec { let mut output = vec![]; @@ -160,21 +151,18 @@ pub struct CP50SetEntityVelocity { pub entity_id: VarInt, pub entity_velocity: EntityVelocity, } -crate::packets::packet!( +crate::protocol::packets::packet!( CP50SetEntityVelocity, 0x50, - crate::ClientState::Play, + crate::protocol::ClientState::Play, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CP50SetEntityVelocity> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CP50SetEntityVelocity> { let (data, entity_id) = VarInt::parse(data)?; let (data, entity_velocity) = EntityVelocity::parse(data)?; - Ok(( - data, - CP50SetEntityVelocity { - entity_id, - entity_velocity, - }, - )) + Ok((data, CP50SetEntityVelocity { + entity_id, + entity_velocity, + })) }, |packet: &CP50SetEntityVelocity| -> Vec { let mut output = vec![]; @@ -190,23 +178,20 @@ pub struct CP52SetExperience { pub total_experience: VarInt, pub level: VarInt, } -crate::packets::packet!( +crate::protocol::packets::packet!( CP52SetExperience, 0x52, - crate::ClientState::Play, + crate::protocol::ClientState::Play, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CP52SetExperience> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CP52SetExperience> { let (data, experience_bar) = f32::parse(data)?; let (data, total_experience) = VarInt::parse(data)?; let (data, level) = VarInt::parse(data)?; - Ok(( - data, - CP52SetExperience { - experience_bar, - total_experience, - level, - }, - )) + Ok((data, CP52SetExperience { + experience_bar, + total_experience, + level, + })) }, |packet: &CP52SetExperience| -> Vec { let mut output = vec![]; @@ -229,12 +214,12 @@ pub struct CP68EntityEffect { pub has_factor_data: bool, // TODO: pub factor_codec: NBT } -crate::packets::packet!( +crate::protocol::packets::packet!( CP68EntityEffect, 0x68, - crate::ClientState::Play, + crate::protocol::ClientState::Play, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CP68EntityEffect> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CP68EntityEffect> { let (data, entity_id) = VarInt::parse(data)?; let (data, effect_id) = VarInt::parse(data)?; let (data, amplifier) = i8::parse(data)?; @@ -246,19 +231,16 @@ crate::packets::packet!( let (data, has_factor_data) = bool::parse(data)?; // TODO: factor_codec - Ok(( - data, - CP68EntityEffect { - entity_id, - effect_id, - amplifier, - duration, - is_ambient, - show_particles, - show_icon, - has_factor_data, - }, - )) + Ok((data, CP68EntityEffect { + entity_id, + effect_id, + amplifier, + duration, + is_ambient, + show_particles, + show_icon, + has_factor_data, + })) }, |packet: &CP68EntityEffect| -> Vec { let mut output = vec![]; diff --git a/crates/composition-protocol/src/packets/clientbound/status.rs b/src/protocol/packets/clientbound/status.rs similarity index 63% rename from crates/composition-protocol/src/packets/clientbound/status.rs rename to src/protocol/packets/clientbound/status.rs index beba263..2b2e934 100644 --- a/crates/composition-protocol/src/packets/clientbound/status.rs +++ b/src/protocol/packets/clientbound/status.rs @@ -1,15 +1,15 @@ -use crate::mctypes::Json; +use crate::protocol::mctypes::Json; #[derive(Clone, Debug, PartialEq)] pub struct CS00StatusResponse { pub response: Json, } -crate::packets::packet!( +crate::protocol::packets::packet!( CS00StatusResponse, 0x00, - crate::ClientState::Status, + crate::protocol::ClientState::Status, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CS00StatusResponse> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CS00StatusResponse> { let (data, response) = Json::parse(data)?; Ok((data, CS00StatusResponse { response })) }, @@ -20,12 +20,12 @@ crate::packets::packet!( pub struct CS01PingResponse { pub payload: i64, } -crate::packets::packet!( +crate::protocol::packets::packet!( CS01PingResponse, 0x01, - crate::ClientState::Status, + crate::protocol::ClientState::Status, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, CS01PingResponse> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, CS01PingResponse> { let (data, payload) = i64::parse(data)?; Ok((data, CS01PingResponse { payload })) }, diff --git a/crates/composition-protocol/src/packets/mod.rs b/src/protocol/packets/mod.rs similarity index 69% rename from crates/composition-protocol/src/packets/mod.rs rename to src/protocol/packets/mod.rs index ef7581c..385dc9d 100644 --- a/crates/composition-protocol/src/packets/mod.rs +++ b/src/protocol/packets/mod.rs @@ -3,8 +3,8 @@ pub mod clientbound; /// Packets that are heading to the server. pub mod serverbound; -use crate::mctypes::VarInt; -use composition_parsing::prelude::*; +use crate::protocol::mctypes::VarInt; +use crate::protocol::parsing::prelude::*; /// Alias for a `VarInt`. pub type PacketId = VarInt; @@ -13,7 +13,7 @@ pub trait Packet: std::fmt::Debug + Clone + TryFrom + Into + Parsable { const ID: i32; - const CLIENT_STATE: crate::ClientState; + const CLIENT_STATE: crate::protocol::ClientState; const IS_SERVERBOUND: bool; } @@ -28,19 +28,19 @@ macro_rules! generic_packet { impl GenericPacket { #[tracing::instrument] pub fn parse_uncompressed<'data>( - client_state: crate::ClientState, + client_state: crate::protocol::ClientState, is_serverbound: bool, data: &'data [u8] - ) -> composition_parsing::ParseResult<'data, Self> { - use composition_parsing::parsable::Parsable; + ) -> crate::protocol::parsing::ParseResult<'data, Self> { + use crate::protocol::parsing::parsable::Parsable; tracing::trace!( "GenericPacket::parse_uncompressed: {:?} {} {:?}", client_state, is_serverbound, data ); - let (data, packet_length) = crate::mctypes::VarInt::parse(data)?; - let (data, packet_data) = composition_parsing::take_bytes(*packet_length as usize)(data)?; + let (data, packet_length) = crate::protocol::mctypes::VarInt::parse(data)?; + let (data, packet_data) = crate::protocol::parsing::take_bytes(*packet_length as usize)(data)?; let (packet_data, packet_id) = PacketId::parse(packet_data)?; let (_packet_data, packet_body) = @@ -55,12 +55,12 @@ macro_rules! generic_packet { #[tracing::instrument] pub fn parse_body<'data>( - client_state: crate::ClientState, - packet_id: crate::packets::PacketId, + client_state: crate::protocol::ClientState, + packet_id: crate::protocol::packets::PacketId, is_serverbound: bool, data: &'data [u8], - ) -> composition_parsing::ParseResult<'data, Self> { - use composition_parsing::parsable::Parsable; + ) -> crate::protocol::parsing::ParseResult<'data, Self> { + use crate::protocol::parsing::parsable::Parsable; tracing::trace!( "GenericPacket::parse_body: {:?} {} {}", client_state, @@ -76,8 +76,8 @@ macro_rules! generic_packet { } #[tracing::instrument] - pub fn serialize(&self) -> (crate::packets::PacketId, Vec) { - use composition_parsing::parsable::Parsable; + pub fn serialize(&self) -> (crate::protocol::packets::PacketId, Vec) { + use crate::protocol::parsing::parsable::Parsable; tracing::trace!("GenericPacket::serialize: {:?}", self); match self { $( @@ -94,9 +94,9 @@ pub struct UnimplementedPacket(VarInt); packet!( UnimplementedPacket, 0x00, - crate::ClientState::Disconnected, + crate::protocol::ClientState::Disconnected, false, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, UnimplementedPacket> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, UnimplementedPacket> { Ok((data, UnimplementedPacket(0i32.into()))) }, |_packet: &UnimplementedPacket| -> Vec { vec![] } @@ -140,14 +140,16 @@ generic_packet!( macro_rules! packet { ($packet_type: ident, $id: literal, $client_state: expr, $serverbound: literal, $parse_body: expr, $serialize_body: expr) => { - impl crate::packets::Packet for $packet_type { + impl crate::protocol::packets::Packet for $packet_type { const ID: i32 = $id; - const CLIENT_STATE: crate::ClientState = $client_state; + const CLIENT_STATE: crate::protocol::ClientState = $client_state; const IS_SERVERBOUND: bool = $serverbound; } - impl composition_parsing::parsable::Parsable for $packet_type { + impl crate::protocol::parsing::parsable::Parsable for $packet_type { #[tracing::instrument] - fn parse<'data>(data: &'data [u8]) -> composition_parsing::ParseResult<'data, Self> { + fn parse<'data>( + data: &'data [u8], + ) -> crate::protocol::parsing::ParseResult<'data, Self> { $parse_body(data) } #[tracing::instrument] @@ -155,17 +157,19 @@ macro_rules! packet { $serialize_body(self) } } - impl From<$packet_type> for crate::packets::GenericPacket { + impl From<$packet_type> for crate::protocol::packets::GenericPacket { fn from(value: $packet_type) -> Self { - crate::packets::GenericPacket::$packet_type(value) + crate::protocol::packets::GenericPacket::$packet_type(value) } } - impl TryFrom for $packet_type { + impl TryFrom for $packet_type { type Error = (); - fn try_from(value: crate::packets::GenericPacket) -> Result { + fn try_from( + value: crate::protocol::packets::GenericPacket, + ) -> Result { match value { - crate::packets::GenericPacket::$packet_type(packet) => Ok(packet), + crate::protocol::packets::GenericPacket::$packet_type(packet) => Ok(packet), _ => Err(()), } } diff --git a/crates/composition-protocol/src/packets/serverbound/handshake.rs b/src/protocol/packets/serverbound/handshake.rs similarity index 66% rename from crates/composition-protocol/src/packets/serverbound/handshake.rs rename to src/protocol/packets/serverbound/handshake.rs index 7c90e78..cdc3121 100644 --- a/crates/composition-protocol/src/packets/serverbound/handshake.rs +++ b/src/protocol/packets/serverbound/handshake.rs @@ -1,4 +1,4 @@ -use crate::{mctypes::VarInt, ClientState}; +use crate::protocol::{ClientState, mctypes::VarInt}; #[derive(Clone, Debug, PartialEq)] pub struct SH00Handshake { @@ -7,30 +7,27 @@ pub struct SH00Handshake { pub server_port: u16, pub next_state: ClientState, } -crate::packets::packet!( +crate::protocol::packets::packet!( SH00Handshake, 0x00, ClientState::Handshake, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SH00Handshake> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SH00Handshake> { let (data, protocol_version) = VarInt::parse(data)?; let (data, server_address) = String::parse(data)?; let (data, server_port) = u16::parse(data)?; let (data, next_state) = VarInt::parse(data)?; - Ok(( - data, - SH00Handshake { - protocol_version, - server_address, - server_port, - next_state: match *next_state { - 1 => ClientState::Status, - 2 => ClientState::Login, - _ => todo!("Invalid next state"), - }, + Ok((data, SH00Handshake { + protocol_version, + server_address, + server_port, + next_state: match *next_state { + 1 => ClientState::Status, + 2 => ClientState::Login, + _ => todo!("Invalid next state"), }, - )) + })) }, |packet: &SH00Handshake| -> Vec { let mut output = vec![]; diff --git a/crates/composition-protocol/src/packets/serverbound/login.rs b/src/protocol/packets/serverbound/login.rs similarity index 62% rename from crates/composition-protocol/src/packets/serverbound/login.rs rename to src/protocol/packets/serverbound/login.rs index 208400a..ae10eac 100644 --- a/crates/composition-protocol/src/packets/serverbound/login.rs +++ b/src/protocol/packets/serverbound/login.rs @@ -1,28 +1,25 @@ -use crate::mctypes::{Uuid, VarInt}; -use composition_parsing::take_bytes; +use crate::protocol::mctypes::{Uuid, VarInt}; +use crate::protocol::parsing::take_bytes; #[derive(Clone, Debug, PartialEq)] pub struct SL00LoginStart { pub name: String, pub uuid: Option, } -crate::packets::packet!( +crate::protocol::packets::packet!( SL00LoginStart, 0x00, - crate::ClientState::Login, + crate::protocol::ClientState::Login, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SL00LoginStart> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SL00LoginStart> { let (data, name) = String::parse(data)?; let (data, has_uuid) = bool::parse(data)?; if has_uuid { let (data, uuid) = Uuid::parse(data)?; - Ok(( - data, - SL00LoginStart { - name, - uuid: Some(uuid), - }, - )) + Ok((data, SL00LoginStart { + name, + uuid: Some(uuid), + })) } else { Ok((data, SL00LoginStart { name, uuid: None })) } @@ -43,24 +40,21 @@ pub struct SL01EncryptionResponse { pub shared_secret: Vec, pub verify_token: Vec, } -crate::packets::packet!( +crate::protocol::packets::packet!( SL01EncryptionResponse, 0x01, - crate::ClientState::Login, + crate::protocol::ClientState::Login, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SL01EncryptionResponse> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SL01EncryptionResponse> { let (data, shared_secret_len) = VarInt::parse(data)?; let (data, shared_secret) = take_bytes(*shared_secret_len as usize)(data)?; let (data, verify_token_len) = VarInt::parse(data)?; let (data, verify_token) = take_bytes(*verify_token_len as usize)(data)?; - Ok(( - data, - SL01EncryptionResponse { - shared_secret: shared_secret.to_vec(), - verify_token: verify_token.to_vec(), - }, - )) + Ok((data, SL01EncryptionResponse { + shared_secret: shared_secret.to_vec(), + verify_token: verify_token.to_vec(), + })) }, |packet: &SL01EncryptionResponse| -> Vec { let mut output = vec![]; @@ -78,32 +72,26 @@ pub struct SL02LoginPluginResponse { pub successful: bool, pub data: Vec, } -crate::packets::packet!( +crate::protocol::packets::packet!( SL02LoginPluginResponse, 0x02, - crate::ClientState::Login, + crate::protocol::ClientState::Login, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SL02LoginPluginResponse> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SL02LoginPluginResponse> { let (data, message_id) = VarInt::parse(data)?; let (data, successful) = bool::parse(data)?; if successful { - Ok(( - &[], - SL02LoginPluginResponse { - message_id, - successful, - data: data.to_vec(), - }, - )) + Ok((&[], SL02LoginPluginResponse { + message_id, + successful, + data: data.to_vec(), + })) } else { - Ok(( - data, - SL02LoginPluginResponse { - message_id, - successful, - data: vec![], - }, - )) + Ok((data, SL02LoginPluginResponse { + message_id, + successful, + data: vec![], + })) } }, |packet: &SL02LoginPluginResponse| -> Vec { diff --git a/crates/composition-protocol/src/packets/serverbound/mod.rs b/src/protocol/packets/serverbound/mod.rs similarity index 100% rename from crates/composition-protocol/src/packets/serverbound/mod.rs rename to src/protocol/packets/serverbound/mod.rs diff --git a/crates/composition-protocol/src/packets/serverbound/play.rs b/src/protocol/packets/serverbound/play.rs similarity index 65% rename from crates/composition-protocol/src/packets/serverbound/play.rs rename to src/protocol/packets/serverbound/play.rs index e873b5c..294b5d7 100644 --- a/crates/composition-protocol/src/packets/serverbound/play.rs +++ b/src/protocol/packets/serverbound/play.rs @@ -1,4 +1,4 @@ -use crate::{ +use crate::protocol::{ entities::{EntityPosition, EntityRotation}, mctypes::VarInt, }; @@ -8,21 +8,18 @@ pub struct SP08CommandSuggestionsRequest { pub transaction_id: VarInt, pub text: String, } -crate::packets::packet!( +crate::protocol::packets::packet!( SP08CommandSuggestionsRequest, 0x08, - crate::ClientState::Play, + crate::protocol::ClientState::Play, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SP08CommandSuggestionsRequest> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SP08CommandSuggestionsRequest> { let (data, transaction_id) = VarInt::parse(data)?; let (data, text) = String::parse(data)?; - Ok(( - data, - SP08CommandSuggestionsRequest { - transaction_id, - text, - }, - )) + Ok((data, SP08CommandSuggestionsRequest { + transaction_id, + text, + })) }, |packet: &SP08CommandSuggestionsRequest| -> Vec { let mut output = vec![]; @@ -36,12 +33,12 @@ crate::packets::packet!( pub struct SP11KeepAlive { pub payload: i64, } -crate::packets::packet!( +crate::protocol::packets::packet!( SP11KeepAlive, 0x11, - crate::ClientState::Play, + crate::protocol::ClientState::Play, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SP11KeepAlive> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SP11KeepAlive> { let (data, payload) = i64::parse(data)?; Ok((data, SP11KeepAlive { payload })) }, @@ -53,21 +50,18 @@ pub struct SP13SetPlayerPosition { pub position: EntityPosition, pub on_ground: bool, } -crate::packets::packet!( +crate::protocol::packets::packet!( SP13SetPlayerPosition, 0x13, - crate::ClientState::Play, + crate::protocol::ClientState::Play, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SP13SetPlayerPosition> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SP13SetPlayerPosition> { let (data, position) = EntityPosition::parse(data)?; let (data, on_ground) = bool::parse(data)?; - Ok(( - data, - SP13SetPlayerPosition { - position, - on_ground, - }, - )) + Ok((data, SP13SetPlayerPosition { + position, + on_ground, + })) }, |packet: &SP13SetPlayerPosition| -> Vec { let mut output = vec![]; @@ -83,23 +77,20 @@ pub struct SP14SetPlayerPositionAndRotation { pub rotation: EntityRotation, pub on_ground: bool, } -crate::packets::packet!( +crate::protocol::packets::packet!( SP14SetPlayerPositionAndRotation, 0x14, - crate::ClientState::Play, + crate::protocol::ClientState::Play, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SP14SetPlayerPositionAndRotation> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SP14SetPlayerPositionAndRotation> { let (data, position) = EntityPosition::parse(data)?; let (data, rotation) = EntityRotation::parse(data)?; let (data, on_ground) = bool::parse(data)?; - Ok(( - data, - SP14SetPlayerPositionAndRotation { - position, - rotation, - on_ground, - }, - )) + Ok((data, SP14SetPlayerPositionAndRotation { + position, + rotation, + on_ground, + })) }, |packet: &SP14SetPlayerPositionAndRotation| -> Vec { let mut output = vec![]; @@ -115,21 +106,18 @@ pub struct SP15SetPlayerRotation { pub rotation: EntityRotation, pub on_ground: bool, } -crate::packets::packet!( +crate::protocol::packets::packet!( SP15SetPlayerRotation, 0x15, - crate::ClientState::Play, + crate::protocol::ClientState::Play, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SP15SetPlayerRotation> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SP15SetPlayerRotation> { let (data, rotation) = EntityRotation::parse(data)?; let (data, on_ground) = bool::parse(data)?; - Ok(( - data, - SP15SetPlayerRotation { - rotation, - on_ground, - }, - )) + Ok((data, SP15SetPlayerRotation { + rotation, + on_ground, + })) }, |packet: &SP15SetPlayerRotation| -> Vec { let mut output = vec![]; diff --git a/crates/composition-protocol/src/packets/serverbound/status.rs b/src/protocol/packets/serverbound/status.rs similarity index 61% rename from crates/composition-protocol/src/packets/serverbound/status.rs rename to src/protocol/packets/serverbound/status.rs index 551c480..31f156d 100644 --- a/crates/composition-protocol/src/packets/serverbound/status.rs +++ b/src/protocol/packets/serverbound/status.rs @@ -1,11 +1,11 @@ #[derive(Copy, Clone, Debug, PartialEq)] pub struct SS00StatusRequest; -crate::packets::packet!( +crate::protocol::packets::packet!( SS00StatusRequest, 0x00, - crate::ClientState::Status, + crate::protocol::ClientState::Status, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SS00StatusRequest> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SS00StatusRequest> { Ok((data, SS00StatusRequest)) }, |_packet: &SS00StatusRequest| -> Vec { vec![] } @@ -15,12 +15,12 @@ crate::packets::packet!( pub struct SS01PingRequest { pub payload: i64, } -crate::packets::packet!( +crate::protocol::packets::packet!( SS01PingRequest, 0x01, - crate::ClientState::Status, + crate::protocol::ClientState::Status, true, - |data: &'data [u8]| -> composition_parsing::ParseResult<'data, SS01PingRequest> { + |data: &'data [u8]| -> crate::protocol::parsing::ParseResult<'data, SS01PingRequest> { let (data, payload) = i64::parse(data)?; Ok((data, SS01PingRequest { payload })) }, diff --git a/crates/composition-parsing/src/error.rs b/src/protocol/parsing/error.rs similarity index 81% rename from crates/composition-parsing/src/error.rs rename to src/protocol/parsing/error.rs index 20a9b89..1e55355 100644 --- a/crates/composition-parsing/src/error.rs +++ b/src/protocol/parsing/error.rs @@ -7,7 +7,7 @@ pub enum Error { /// This error was caused by prematurely reaching the end of the input data. #[error("unexpected end of file")] Eof, - /// This error was caused by reading a `composition_parsing::VarInt` that was longer than 5 bytes. + /// This error was caused by reading a `crate::parsing::VarInt` that was longer than 5 bytes. #[error("VarInt was more than 5 bytes")] VarIntTooLong, /// This error is a wrapper for `serde_json::Error`. @@ -19,11 +19,11 @@ pub enum Error { Message(String), } -/// Alias for a Result with the error type `composition_parsing::Error`. +/// Alias for a Result with the error type `crate::parsing::Error`. pub type Result = std::result::Result; /// Alias for a Result that helps with zero-copy parsing. /// -/// The error type is `composition_parsing::Error`, +/// The error type is `crate::parsing::Error`, /// and the result type is a tuple of the remaining bytes and the parsed item. pub type ParseResult<'data, T> = Result<(&'data [u8], T)>; diff --git a/crates/composition-parsing/src/lib.rs b/src/protocol/parsing/mod.rs similarity index 97% rename from crates/composition-parsing/src/lib.rs rename to src/protocol/parsing/mod.rs index 00eded3..b28ac45 100644 --- a/crates/composition-parsing/src/lib.rs +++ b/src/protocol/parsing/mod.rs @@ -4,7 +4,7 @@ pub mod error; pub mod parsable; /// Useful re-exports. pub mod prelude { - pub use crate::{parsable::Parsable, take_bytes, VarInt}; + pub use super::{VarInt, parsable::Parsable, take_bytes}; } pub use error::{Error, ParseResult, Result}; diff --git a/crates/composition-parsing/src/parsable.rs b/src/protocol/parsing/parsable.rs similarity index 98% rename from crates/composition-parsing/src/parsable.rs rename to src/protocol/parsing/parsable.rs index 8a271d1..a451ee0 100644 --- a/crates/composition-parsing/src/parsable.rs +++ b/src/protocol/parsing/parsable.rs @@ -1,4 +1,4 @@ -use crate::{take_bytes, Error, ParseResult, VarInt}; +use super::{Error, ParseResult, VarInt, take_bytes}; use byteorder::{BigEndian, ReadBytesExt}; /// A structure that can be serialized and deserialized. @@ -321,11 +321,7 @@ impl Parsable for bool { } #[tracing::instrument] fn serialize(&self) -> Vec { - if *self { - vec![0x01] - } else { - vec![0x00] - } + if *self { vec![0x01] } else { vec![0x00] } } } diff --git a/crates/composition-core/src/server-icon.png b/src/server-icon.png similarity index 100% rename from crates/composition-core/src/server-icon.png rename to src/server-icon.png diff --git a/crates/composition-core/src/server/mod.rs b/src/server/mod.rs similarity index 99% rename from crates/composition-core/src/server/mod.rs rename to src/server/mod.rs index 45de602..c0d2a0f 100644 --- a/crates/composition-core/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,7 +1,7 @@ use crate::config::Config; use crate::error::Result; use crate::net::{NetworkClient, NetworkClientState}; -use composition_protocol::ClientState; +use crate::protocol::ClientState; use std::sync::Arc; use tokio::net::{TcpListener, ToSocketAddrs}; use tokio::{sync::RwLock, task::JoinHandle}; @@ -162,7 +162,7 @@ impl Server { .filter(|client| matches!(client.state, NetworkClientState::Play)) .count(); 'clients: for client in clients.iter_mut() { - use composition_protocol::packets::{clientbound::*, serverbound::*}; + use crate::protocol::packets::{clientbound::*, serverbound::*}; 'packets: while !client.incoming_packet_queue.is_empty() { // client.read_packet() // None: The client doesn't have any more packets. diff --git a/crates/composition-world/src/chunks.rs b/src/world/chunks.rs similarity index 98% rename from crates/composition-world/src/chunks.rs rename to src/world/chunks.rs index ddfaac8..563bc6a 100644 --- a/crates/composition-world/src/chunks.rs +++ b/src/world/chunks.rs @@ -1,4 +1,4 @@ -use crate::{ +use crate::world::{ blocks::{Block, BlockPosition}, entities::{Entity, EntityId, EntityPosition}, }; diff --git a/crates/composition-world/src/error.rs b/src/world/error.rs similarity index 100% rename from crates/composition-world/src/error.rs rename to src/world/error.rs diff --git a/crates/composition-world/src/generators/mod.rs b/src/world/generators/mod.rs similarity index 100% rename from crates/composition-world/src/generators/mod.rs rename to src/world/generators/mod.rs diff --git a/crates/composition-world/src/generators/superflat.rs b/src/world/generators/superflat.rs similarity index 100% rename from crates/composition-world/src/generators/superflat.rs rename to src/world/generators/superflat.rs diff --git a/crates/composition-world/src/lib.rs b/src/world/mod.rs similarity index 95% rename from crates/composition-world/src/lib.rs rename to src/world/mod.rs index 1ea9b41..25d0fa5 100644 --- a/crates/composition-world/src/lib.rs +++ b/src/world/mod.rs @@ -6,13 +6,13 @@ pub mod error; pub mod generators; /// Useful re-exports. pub mod prelude { - pub use crate::{chunks::Chunk, World}; + pub use super::{World, chunks::Chunk}; } -pub use composition_protocol::{blocks, entities}; +pub use crate::protocol::{blocks, entities}; pub use error::{Error, Result}; -use crate::chunks::{Chunk, ChunkPosition}; +use crate::world::chunks::{Chunk, ChunkPosition}; use blocks::{Block, BlockPosition}; use entities::{Entity, EntityId, EntityPosition}; use std::path::Path;