From a4b461b6c0db0a899a5aa912ce3c014350d61392 Mon Sep 17 00:00:00 2001 From: Garen Tyler Date: Mon, 1 Mar 2021 20:58:57 -0700 Subject: [PATCH] Make functions async --- Cargo.lock | 200 +++++++++++++++++++++++ Cargo.toml | 2 + src/lib.rs | 2 +- src/main.rs | 7 +- src/mctypes.rs | 223 +++++++++----------------- src/server/mod.rs | 4 +- src/server/net/mod.rs | 32 ++-- src/server/net/packets/clientbound.rs | 43 +++-- src/server/net/packets/mod.rs | 18 +-- src/server/net/packets/serverbound.rs | 45 +++--- 10 files changed, 350 insertions(+), 226 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f5289a..2465327 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,17 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +[[package]] +name = "async-trait" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atty" version = "0.2.14" @@ -23,6 +34,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bytes" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" + [[package]] name = "cfg-if" version = "0.1.10" @@ -63,12 +86,14 @@ dependencies = [ name = "composition" version = "0.1.0" dependencies = [ + "async-trait", "chrono", "fern", "log", "radix64", "serde", "serde_json", + "tokio", ] [[package]] @@ -90,6 +115,15 @@ dependencies = [ "libc", ] +[[package]] +name = "instant" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "itoa" version = "0.4.7" @@ -108,6 +142,15 @@ version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" +[[package]] +name = "lock_api" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.14" @@ -117,6 +160,44 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" + +[[package]] +name = "mio" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" +dependencies = [ + "socket2", + "winapi", +] + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -136,6 +217,53 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a" + +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827" + [[package]] name = "proc-macro2" version = "1.0.24" @@ -164,12 +292,27 @@ dependencies = [ "cfg-if 0.1.10", ] +[[package]] +name = "redox_syscall" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +dependencies = [ + "bitflags", +] + [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "serde" version = "1.0.123" @@ -201,6 +344,32 @@ dependencies = [ "serde", ] +[[package]] +name = "signal-hook-registry" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "socket2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "winapi", +] + [[package]] name = "syn" version = "1.0.60" @@ -223,6 +392,37 @@ dependencies = [ "winapi", ] +[[package]] +name = "tokio" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-xid" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index 3be2273..bc945fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,8 @@ chrono = "0.4.13" serde = { version = "1.0.114", features = ["serde_derive"]} serde_json = "1.0.59" radix64 = "0.3.0" +tokio = { version = "1", features = ["full"] } +async-trait = "0.1.42" # colorful = "0.2.1" # lazy_static = "1.4.0" # ozelot = "0.9.0" # Ozelot 0.9.0 supports protocol version 578 (1.15.2) diff --git a/src/lib.rs b/src/lib.rs index 559ccbf..2eded7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,7 @@ pub fn init() { } /// Start the server. -pub fn start_server() -> server::GameServer { +pub async fn start_server() -> server::GameServer { // Start the network. let network = server::net::NetworkServer::new("0.0.0.0:25565"); let server = server::GameServer { network: network }; diff --git a/src/main.rs b/src/main.rs index 65c1c21..ee226ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,17 @@ use log::info; use std::time::{Duration, Instant}; -pub fn main() { +#[tokio::main] +pub async fn main() { let start_time = Instant::now(); composition::init(); info!("Starting server..."); - let mut server = composition::start_server(); + let mut server = composition::start_server().await; info!("Done! Start took {:?}", start_time.elapsed()); // The main server loop. loop { - server.update(); + server.update().await; std::thread::sleep(Duration::from_millis(2)); } } diff --git a/src/mctypes.rs b/src/mctypes.rs index 9f844fa..4de4bf2 100644 --- a/src/mctypes.rs +++ b/src/mctypes.rs @@ -3,22 +3,20 @@ pub use functions::*; pub use numbers::*; pub use other::*; -use std::convert::{Into, TryFrom}; -use std::fmt::Display; use std::io::prelude::*; use std::net::TcpStream; -/// Make sure all types can serialize and deserialize to/from `Vec`. -pub trait MCType: Into> + TryFrom> + Display { - fn read(_stream: &mut TcpStream) -> std::io::Result; -} +// /// Make sure all types can serialize and deserialize to/from `Vec`. +// pub trait MCType: Into> + TryFrom> + Display { +// pub async fn read(_stream: &mut TcpStream) -> std::io::Result; +// } /// Helper functions. pub mod functions { use super::*; /// Read a single byte from the given `TcpStream`. - pub fn read_byte(t: &mut TcpStream) -> std::io::Result { + pub async fn read_byte(t: &mut TcpStream) -> std::io::Result { let mut buffer = [0u8; 1]; t.read_exact(&mut buffer)?; Ok(buffer[0]) @@ -114,9 +112,9 @@ pub mod other { } } } - impl MCType for MCBoolean { - fn read(t: &mut TcpStream) -> std::io::Result { - let b = read_byte(t)?; + impl MCBoolean { + pub async fn read(t: &mut TcpStream) -> std::io::Result { + let b = read_byte(t).await?; Ok(MCBoolean::try_from(vec![b]).unwrap()) } } @@ -189,12 +187,12 @@ pub mod other { out } } - impl MCType for MCString { - fn read(t: &mut TcpStream) -> std::io::Result { - let str_len = MCVarInt::read(t)?; + impl MCString { + pub async fn read(t: &mut TcpStream) -> std::io::Result { + let str_len = MCVarInt::read(t).await?; let mut str_bytes = vec![]; for _ in 0..str_len.into() { - str_bytes.push(read_byte(t)?); + str_bytes.push(read_byte(t).await?); } Ok(MCString { value: String::from_utf8_lossy(&str_bytes).to_string(), @@ -244,8 +242,8 @@ pub mod other { out } } - impl MCType for MCChat { - fn read(_t: &mut TcpStream) -> std::io::Result { + impl MCChat { + pub async fn read(_t: &mut TcpStream) -> std::io::Result { Err(io_error("Cannot read MCChat from stream")) } } @@ -263,8 +261,8 @@ pub mod numbers { pub value: i8, // -128 to 127 } impl MCByte { - pub fn from_stream(t: &mut TcpStream) -> std::io::Result { - Ok(MCByte::from_bytes(vec![read_byte(t)?])) + pub async fn read(t: &mut TcpStream) -> std::io::Result { + Ok(MCByte::from_bytes(vec![read_byte(t).await?])) } pub fn from_bytes(v: Vec) -> MCByte { MCByte { @@ -314,15 +312,6 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCByte { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..1 { - bytes.push(read_byte(t)?); - } - Ok(MCByte::try_from(bytes).unwrap()) - } - } /// The equivalent of a `u8` #[derive(Debug, Copy, Clone, PartialEq)] @@ -330,8 +319,8 @@ pub mod numbers { pub value: u8, // 0 to 255 } impl MCUnsignedByte { - pub fn from_stream(t: &mut TcpStream) -> std::io::Result { - Ok(MCUnsignedByte::from_bytes(vec![read_byte(t)?])) + pub async fn read(t: &mut TcpStream) -> std::io::Result { + Ok(MCUnsignedByte::from_bytes(vec![read_byte(t).await?])) } pub fn from_bytes(v: Vec) -> MCUnsignedByte { MCUnsignedByte { @@ -381,15 +370,6 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCUnsignedByte { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..1 { - bytes.push(read_byte(t)?); - } - Ok(MCUnsignedByte::try_from(bytes).unwrap()) - } - } /// The equivalent of an `i16` #[derive(Debug, Copy, Clone, PartialEq)] @@ -397,10 +377,10 @@ pub mod numbers { pub value: i16, // -32768 to 32767 } impl MCShort { - pub fn from_stream(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut bytes = Vec::new(); - bytes.push(read_byte(t)?); // MSD - bytes.push(read_byte(t)?); // LSD + bytes.push(read_byte(t).await?); // MSD + bytes.push(read_byte(t).await?); // LSD Ok(MCShort::from_bytes(bytes)) } pub fn from_bytes(v: Vec) -> MCShort { @@ -453,15 +433,6 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCShort { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..2 { - bytes.push(read_byte(t)?); - } - Ok(MCShort::try_from(bytes).unwrap()) - } - } /// The equivalent of a `u16` #[derive(Debug, Copy, Clone, PartialEq)] @@ -469,10 +440,10 @@ pub mod numbers { pub value: u16, // 0 to 65535 } impl MCUnsignedShort { - pub fn from_stream(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut bytes = Vec::new(); - bytes.push(read_byte(t)?); // MSD - bytes.push(read_byte(t)?); // LSD + bytes.push(read_byte(t).await?); // MSD + bytes.push(read_byte(t).await?); // LSD Ok(MCUnsignedShort::from_bytes(bytes)) } pub fn from_bytes(v: Vec) -> MCUnsignedShort { @@ -525,15 +496,6 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCUnsignedShort { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..2 { - bytes.push(read_byte(t)?); - } - Ok(MCUnsignedShort::try_from(bytes).unwrap()) - } - } /// The equivalent of an `i32` #[derive(Debug, Copy, Clone, PartialEq)] @@ -541,10 +503,10 @@ pub mod numbers { pub value: i32, // -2147483648 to 2147483647 } impl MCInt { - pub fn from_stream(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut bytes = Vec::new(); for _ in 0..4 { - bytes.push(read_byte(t)?); + bytes.push(read_byte(t).await?); } Ok(MCInt::from_bytes(bytes)) } @@ -598,15 +560,6 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCInt { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..4 { - bytes.push(read_byte(t)?); - } - Ok(MCInt::try_from(bytes).unwrap()) - } - } /// The equivalent of a `u32` #[derive(Debug, Copy, Clone, PartialEq)] @@ -614,10 +567,10 @@ pub mod numbers { pub value: u32, // 0 to 4294967295 } impl MCUnsignedInt { - pub fn from_stream(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut bytes = Vec::new(); for _ in 0..4 { - bytes.push(read_byte(t)?); + bytes.push(read_byte(t).await?); } Ok(MCUnsignedInt::from_bytes(bytes)) } @@ -671,15 +624,6 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCUnsignedInt { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..4 { - bytes.push(read_byte(t)?); - } - Ok(MCUnsignedInt::try_from(bytes).unwrap()) - } - } /// The equivalent of an `864` #[derive(Debug, Copy, Clone, PartialEq)] @@ -687,10 +631,10 @@ pub mod numbers { pub value: i64, // -9223372036854775808 to 9223372036854775807 } impl MCLong { - pub fn from_stream(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut bytes = Vec::new(); for _ in 0..8 { - bytes.push(read_byte(t)?); + bytes.push(read_byte(t).await?); } Ok(MCLong::from_bytes(bytes)) } @@ -744,15 +688,6 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCLong { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..8 { - bytes.push(read_byte(t)?); - } - Ok(MCLong::try_from(bytes).unwrap()) - } - } /// The equivalent of a `u64` #[derive(Debug, Copy, Clone, PartialEq)] @@ -760,10 +695,10 @@ pub mod numbers { pub value: u64, // 0 to 18446744073709551615 } impl MCUnsignedLong { - pub fn from_stream(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut bytes = Vec::new(); for _ in 0..8 { - bytes.push(read_byte(t)?); + bytes.push(read_byte(t).await?); } Ok(MCUnsignedLong::from_bytes(bytes)) } @@ -817,15 +752,6 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCUnsignedLong { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..8 { - bytes.push(read_byte(t)?); - } - Ok(MCUnsignedLong::try_from(bytes).unwrap()) - } - } /// The equivalent of a `f32` #[derive(Debug, Copy, Clone, PartialEq)] @@ -833,10 +759,10 @@ pub mod numbers { pub value: f32, // 32-bit floating point number } impl MCFloat { - pub fn from_stream(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut bytes = Vec::new(); for _ in 0..4 { - bytes.push(read_byte(t)?); + bytes.push(read_byte(t).await?); } Ok(MCFloat::from_bytes(bytes)) } @@ -890,21 +816,31 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCFloat { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..4 { - bytes.push(read_byte(t)?); - } - Ok(MCFloat::try_from(bytes).unwrap()) - } - } /// The equivalent of a `f64` #[derive(Debug, Copy, Clone, PartialEq)] pub struct MCDouble { pub value: f64, // 64-bit floating point number } + impl MCDouble { + pub async fn read(t: &mut TcpStream) -> std::io::Result { + let mut bytes = Vec::new(); + for _ in 0..8 { + bytes.push(read_byte(t).await?); + } + Ok(MCDouble::from_bytes(bytes)) + } + pub fn from_bytes(v: Vec) -> MCDouble { + let mut a = [0u8; 8]; + a.copy_from_slice(&get_bytes(v, 8)); + MCDouble { + value: f64::from_be_bytes(a), + } + } + pub fn to_bytes(&self) -> Vec { + self.value.to_be_bytes().to_vec() + } + } impl From for MCDouble { fn from(v: f64) -> MCDouble { MCDouble { value: v } @@ -944,21 +880,37 @@ pub mod numbers { self.value.to_be_bytes().to_vec() } } - impl MCType for MCDouble { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut bytes = Vec::new(); - for _ in 0..8 { - bytes.push(read_byte(t)?); - } - Ok(MCDouble::try_from(bytes).unwrap()) - } - } /// A variable-length integer. #[derive(Debug, Copy, Clone, PartialEq)] pub struct MCVarInt { pub value: i32, // Variable length 32-bit integer } + impl MCVarInt { + pub async fn read(t: &mut TcpStream) -> std::io::Result { + let mut num_read = 0; + let mut result = 0i32; + let mut read = 0u8; + let mut run_once = false; + while (read & 0b10000000) != 0 || !run_once { + run_once = true; + read = read_byte(t).await?; + let value = (read & 0b01111111) as i32; + result |= value << (7 * num_read); + num_read += 1; + if num_read > 5 { + return Err(io_error("MCVarInt is too big")); + } + } + Ok(MCVarInt { value: result }) + } + pub fn from_bytes(_v: Vec) -> MCVarInt { + unimplemented!() + } + pub fn to_bytes(&self) -> Vec { + unimplemented!() + } + } impl From for MCVarInt { fn from(v: i32) -> MCVarInt { MCVarInt { value: v } @@ -1018,23 +970,4 @@ pub mod numbers { return out; } } - impl MCType for MCVarInt { - fn read(t: &mut TcpStream) -> std::io::Result { - let mut num_read = 0; - let mut result = 0i32; - let mut read = 0u8; - let mut run_once = false; - while (read & 0b10000000) != 0 || !run_once { - run_once = true; - read = read_byte(t)?; - let value = (read & 0b01111111) as i32; - result |= value << (7 * num_read); - num_read += 1; - if num_read > 5 { - return Err(io_error("MCVarInt is too big")); - } - } - Ok(MCVarInt { value: result }) - } - } } diff --git a/src/server/mod.rs b/src/server/mod.rs index 75c4dc8..f6ae366 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -9,7 +9,7 @@ impl GameServer { /// Update the game server. /// /// Start by updating the network. - pub fn update(&mut self) { - self.network.update(); + pub async fn update(&mut self) { + self.network.update().await; } } diff --git a/src/server/net/mod.rs b/src/server/net/mod.rs index 1cec900..4550104 100644 --- a/src/server/net/mod.rs +++ b/src/server/net/mod.rs @@ -41,7 +41,7 @@ impl NetworkServer { } } /// Update each client in `self.clients`. - pub fn update(&mut self) { + pub async fn update(&mut self) { loop { match self.receiver.try_recv() { Ok(client) => { @@ -56,7 +56,7 @@ impl NetworkServer { } } for client in self.clients.iter_mut() { - client.update(); + client.update().await; } } } @@ -84,11 +84,11 @@ impl NetworkClient { /// /// Updating could mean connecting new clients, reading packets, /// writing packets, or disconnecting clients. - pub fn update(&mut self) { + pub async fn update(&mut self) { match self.state { NetworkClientState::Handshake => { - let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).unwrap(); - let handshake = Handshake::read(&mut self.stream).unwrap(); + let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await.unwrap(); + let handshake = Handshake::read(&mut self.stream).await.unwrap(); // Minecraft versions 1.8 - 1.8.9 use protocol version 47. let compatible_versions = handshake.protocol_version == 47; let next_state = match handshake.next_state.into() { @@ -103,14 +103,14 @@ impl NetworkClient { logindisconnect.reason = MCChat { text: MCString::from("Incompatible client! Server is on 1.8.9"), }; - logindisconnect.write(&mut self.stream).unwrap(); + logindisconnect.write(&mut self.stream).await.unwrap(); self.state = NetworkClientState::Disconnected; } debug!("Got handshake: {:?}", handshake); } NetworkClientState::Status => { - let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).unwrap(); - let statusrequest = StatusRequest::read(&mut self.stream).unwrap(); + let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await.unwrap(); + let statusrequest = StatusRequest::read(&mut self.stream).await.unwrap(); debug!("Got status request: {:?}", statusrequest); let mut statusresponse = StatusResponse::new(); statusresponse.json_response = json!({ @@ -123,7 +123,7 @@ impl NetworkClient { "online": 5, "sample": [ { - "name": "ElementG9", + "name": "shvr", "id": "e3f58380-60bb-4714-91f2-151d525e64aa" } ] @@ -136,27 +136,27 @@ impl NetworkClient { }) .to_string() .into(); - statusresponse.write(&mut self.stream).unwrap(); + statusresponse.write(&mut self.stream).await.unwrap(); debug!("Sending status response: StatusResponse"); - let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).unwrap(); - let statusping = StatusPing::read(&mut self.stream).unwrap(); + let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await.unwrap(); + let statusping = StatusPing::read(&mut self.stream).await.unwrap(); debug!("Got status ping: {:?}", statusping); let mut statuspong = StatusPong::new(); statuspong.payload = statusping.payload; - statuspong.write(&mut self.stream).unwrap(); + statuspong.write(&mut self.stream).await.unwrap(); debug!("Sending status pong: {:?}", statuspong); self.state = NetworkClientState::Disconnected; } NetworkClientState::Login => { - let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).unwrap(); - let loginstart = LoginStart::read(&mut self.stream).unwrap(); + let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await.unwrap(); + let loginstart = LoginStart::read(&mut self.stream).await.unwrap(); debug!("{:?}", loginstart); // Offline mode skips encryption and compression. let mut loginsuccess = LoginSuccess::new(); // We're in offline mode, so this is a temporary uuid. loginsuccess.uuid = "00000000-0000-3000-0000-000000000000".into(); loginsuccess.username = loginstart.player_name; - loginsuccess.write(&mut self.stream).unwrap(); + loginsuccess.write(&mut self.stream).await.unwrap(); debug!("{:?}", loginsuccess); self.state = NetworkClientState::Play; } diff --git a/src/server/net/packets/clientbound.rs b/src/server/net/packets/clientbound.rs index 6c0754e..dc86297 100644 --- a/src/server/net/packets/clientbound.rs +++ b/src/server/net/packets/clientbound.rs @@ -1,4 +1,3 @@ -use super::Packet; use crate::mctypes::*; use std::convert::{Into, TryFrom}; use std::net::TcpStream; @@ -23,18 +22,18 @@ impl TryFrom> for StatusResponse { Err("unimplemented") } } -impl Packet for StatusResponse { - fn new() -> Self { +impl StatusResponse { + pub fn new() -> Self { StatusResponse { json_response: MCString::from(""), } } - fn read(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &'_ mut TcpStream) -> std::io::Result { let mut statusresponse = StatusResponse::new(); - statusresponse.json_response = MCString::read(t)?; + statusresponse.json_response = MCString::read(t).await?; Ok(statusresponse) } - fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { + pub async fn write(&self, t: &'_ mut TcpStream) -> std::io::Result<()> { for b in Into::>::into(self.clone()) { write_byte(t, b)?; } @@ -62,16 +61,16 @@ impl TryFrom> for StatusPong { Err("unimplemented") } } -impl Packet for StatusPong { - fn new() -> Self { +impl StatusPong { + pub fn new() -> Self { StatusPong { payload: 0.into() } } - fn read(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut statuspong = StatusPong::new(); - statuspong.payload = MCLong::read(t)?; + statuspong.payload = MCLong::read(t).await?; Ok(statuspong) } - fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { + pub async fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { for b in Into::>::into(self.clone()) { write_byte(t, b)?; } @@ -101,20 +100,20 @@ impl TryFrom> for LoginSuccess { Err("unimplemented") } } -impl Packet for LoginSuccess { - fn new() -> Self { +impl LoginSuccess { + pub fn new() -> Self { LoginSuccess { uuid: MCString::from(""), username: MCString::from(""), } } - fn read(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut loginsuccess = LoginSuccess::new(); - loginsuccess.uuid = MCString::read(t)?; - loginsuccess.username = MCString::read(t)?; + loginsuccess.uuid = MCString::read(t).await?; + loginsuccess.username = MCString::read(t).await?; Ok(loginsuccess) } - fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { + pub async fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { for b in Into::>::into(self.clone()) { write_byte(t, b)?; } @@ -142,22 +141,22 @@ impl TryFrom> for LoginDisconnect { Err("unimplemented") } } -impl Packet for LoginDisconnect { - fn new() -> Self { +impl LoginDisconnect { + pub fn new() -> Self { LoginDisconnect { reason: MCChat { text: MCString::from(""), }, } } - fn read(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut logindisconnect = LoginDisconnect::new(); logindisconnect.reason = MCChat { - text: MCString::read(t)?, + text: MCString::read(t).await?, }; Ok(logindisconnect) } - fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { + pub async fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { for b in Into::>::into(self.clone()) { write_byte(t, b)?; } diff --git a/src/server/net/packets/mod.rs b/src/server/net/packets/mod.rs index 5f35105..934cc4f 100644 --- a/src/server/net/packets/mod.rs +++ b/src/server/net/packets/mod.rs @@ -3,24 +3,14 @@ pub mod clientbound; /// The packets that get sent to the server by the client. pub mod serverbound; -use crate::mctypes::{MCType, MCVarInt}; +use crate::mctypes::MCVarInt; pub use clientbound::*; pub use serverbound::*; -use std::convert::{Into, TryFrom}; use std::net::TcpStream; -/// All packets need to serialize/deserialize to/from `Vec`. -pub trait Packet: Into> + TryFrom> { - fn new() -> Self; - /// Read the packet body from the given `TcpStream`. - fn read(_stream: &mut TcpStream) -> std::io::Result; - /// Write the packet (body and header) to the given `TcpStream`. - fn write(&self, _stream: &mut TcpStream) -> std::io::Result<()>; -} - /// A helper function to read the packet header. -pub fn read_packet_header(t: &mut TcpStream) -> std::io::Result<(MCVarInt, MCVarInt)> { - let length = MCVarInt::read(t)?; - let id = MCVarInt::read(t)?; +pub async fn read_packet_header(t: &mut TcpStream) -> std::io::Result<(MCVarInt, MCVarInt)> { + let length = MCVarInt::read(t).await?; + let id = MCVarInt::read(t).await?; Ok((length, id)) } diff --git a/src/server/net/packets/serverbound.rs b/src/server/net/packets/serverbound.rs index 78cf419..e3311c9 100644 --- a/src/server/net/packets/serverbound.rs +++ b/src/server/net/packets/serverbound.rs @@ -1,4 +1,3 @@ -use super::Packet; use crate::mctypes::*; use std::convert::{Into, TryFrom}; use std::net::TcpStream; @@ -30,8 +29,8 @@ impl TryFrom> for Handshake { Err("unimplemented") } } -impl Packet for Handshake { - fn new() -> Self { +impl Handshake { + pub fn new() -> Self { Handshake { protocol_version: 0.into(), server_address: "".into(), @@ -39,15 +38,15 @@ impl Packet for Handshake { next_state: 0.into(), } } - fn read(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut handshake = Handshake::new(); - handshake.protocol_version = MCVarInt::read(t)?; - handshake.server_address = MCString::read(t)?; - handshake.server_port = MCUnsignedShort::read(t)?; - handshake.next_state = MCVarInt::read(t)?; + handshake.protocol_version = MCVarInt::read(t).await?; + handshake.server_address = MCString::read(t).await?; + handshake.server_port = MCUnsignedShort::read(t).await?; + handshake.next_state = MCVarInt::read(t).await?; Ok(handshake) } - fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { + pub async fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { for b in Into::>::into(self.clone()) { write_byte(t, b)?; } @@ -72,15 +71,15 @@ impl TryFrom> for StatusRequest { Err("unimplemented") } } -impl Packet for StatusRequest { - fn new() -> Self { +impl StatusRequest { + pub fn new() -> Self { StatusRequest {} } - fn read(_t: &mut TcpStream) -> std::io::Result { + pub async fn read(_t: &mut TcpStream) -> std::io::Result { let statusrequest = StatusRequest::new(); Ok(statusrequest) } - fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { + pub async fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { for b in Into::>::into(self.clone()) { write_byte(t, b)?; } @@ -108,16 +107,16 @@ impl TryFrom> for StatusPing { Err("unimplemented") } } -impl Packet for StatusPing { - fn new() -> Self { +impl StatusPing { + pub fn new() -> Self { StatusPing { payload: 0.into() } } - fn read(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut statusping = StatusPing::new(); - statusping.payload = MCLong::read(t)?; + statusping.payload = MCLong::read(t).await?; Ok(statusping) } - fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { + pub async fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { for b in Into::>::into(self.clone()) { write_byte(t, b)?; } @@ -145,18 +144,18 @@ impl TryFrom> for LoginStart { Err("unimplemented") } } -impl Packet for LoginStart { - fn new() -> Self { +impl LoginStart { + pub fn new() -> Self { LoginStart { player_name: "".into(), } } - fn read(t: &mut TcpStream) -> std::io::Result { + pub async fn read(t: &mut TcpStream) -> std::io::Result { let mut loginstart = LoginStart::new(); - loginstart.player_name = MCString::read(t)?; + loginstart.player_name = MCString::read(t).await?; Ok(loginstart) } - fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { + pub async fn write(&self, t: &mut TcpStream) -> std::io::Result<()> { for b in Into::>::into(self.clone()) { write_byte(t, b)?; }