Make functions async

This commit is contained in:
Garen Tyler 2021-03-01 20:58:57 -07:00
parent a94491205d
commit a4b461b6c0
10 changed files with 350 additions and 226 deletions

200
Cargo.lock generated
View File

@ -6,6 +6,17 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 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]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@ -23,6 +34,18 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 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]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.10" version = "0.1.10"
@ -63,12 +86,14 @@ dependencies = [
name = "composition" name = "composition"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-trait",
"chrono", "chrono",
"fern", "fern",
"log", "log",
"radix64", "radix64",
"serde", "serde",
"serde_json", "serde_json",
"tokio",
] ]
[[package]] [[package]]
@ -90,6 +115,15 @@ dependencies = [
"libc", "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]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.7" version = "0.4.7"
@ -108,6 +142,15 @@ version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" 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]] [[package]]
name = "log" name = "log"
version = "0.4.14" version = "0.4.14"
@ -117,6 +160,44 @@ dependencies = [
"cfg-if 1.0.0", "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]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.44" version = "0.1.44"
@ -136,6 +217,53 @@ dependencies = [
"autocfg", "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]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.24" version = "1.0.24"
@ -164,12 +292,27 @@ dependencies = [
"cfg-if 0.1.10", "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]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.5" version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.123" version = "1.0.123"
@ -201,6 +344,32 @@ dependencies = [
"serde", "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]] [[package]]
name = "syn" name = "syn"
version = "1.0.60" version = "1.0.60"
@ -223,6 +392,37 @@ dependencies = [
"winapi", "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]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.1" version = "0.2.1"

View File

@ -11,6 +11,8 @@ chrono = "0.4.13"
serde = { version = "1.0.114", features = ["serde_derive"]} serde = { version = "1.0.114", features = ["serde_derive"]}
serde_json = "1.0.59" serde_json = "1.0.59"
radix64 = "0.3.0" radix64 = "0.3.0"
tokio = { version = "1", features = ["full"] }
async-trait = "0.1.42"
# colorful = "0.2.1" # colorful = "0.2.1"
# lazy_static = "1.4.0" # lazy_static = "1.4.0"
# ozelot = "0.9.0" # Ozelot 0.9.0 supports protocol version 578 (1.15.2) # ozelot = "0.9.0" # Ozelot 0.9.0 supports protocol version 578 (1.15.2)

View File

@ -30,7 +30,7 @@ pub fn init() {
} }
/// Start the server. /// Start the server.
pub fn start_server() -> server::GameServer { pub async fn start_server() -> server::GameServer {
// Start the network. // Start the network.
let network = server::net::NetworkServer::new("0.0.0.0:25565"); let network = server::net::NetworkServer::new("0.0.0.0:25565");
let server = server::GameServer { network: network }; let server = server::GameServer { network: network };

View File

@ -1,16 +1,17 @@
use log::info; use log::info;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
pub fn main() { #[tokio::main]
pub async fn main() {
let start_time = Instant::now(); let start_time = Instant::now();
composition::init(); composition::init();
info!("Starting server..."); info!("Starting server...");
let mut server = composition::start_server(); let mut server = composition::start_server().await;
info!("Done! Start took {:?}", start_time.elapsed()); info!("Done! Start took {:?}", start_time.elapsed());
// The main server loop. // The main server loop.
loop { loop {
server.update(); server.update().await;
std::thread::sleep(Duration::from_millis(2)); std::thread::sleep(Duration::from_millis(2));
} }
} }

View File

@ -3,22 +3,20 @@
pub use functions::*; pub use functions::*;
pub use numbers::*; pub use numbers::*;
pub use other::*; pub use other::*;
use std::convert::{Into, TryFrom};
use std::fmt::Display;
use std::io::prelude::*; use std::io::prelude::*;
use std::net::TcpStream; use std::net::TcpStream;
/// Make sure all types can serialize and deserialize to/from `Vec<u8>`. // /// Make sure all types can serialize and deserialize to/from `Vec<u8>`.
pub trait MCType: Into<Vec<u8>> + TryFrom<Vec<u8>> + Display { // pub trait MCType: Into<Vec<u8>> + TryFrom<Vec<u8>> + Display {
fn read(_stream: &mut TcpStream) -> std::io::Result<Self>; // pub async fn read(_stream: &mut TcpStream) -> std::io::Result<Self>;
} // }
/// Helper functions. /// Helper functions.
pub mod functions { pub mod functions {
use super::*; use super::*;
/// Read a single byte from the given `TcpStream`. /// Read a single byte from the given `TcpStream`.
pub fn read_byte(t: &mut TcpStream) -> std::io::Result<u8> { pub async fn read_byte(t: &mut TcpStream) -> std::io::Result<u8> {
let mut buffer = [0u8; 1]; let mut buffer = [0u8; 1];
t.read_exact(&mut buffer)?; t.read_exact(&mut buffer)?;
Ok(buffer[0]) Ok(buffer[0])
@ -114,9 +112,9 @@ pub mod other {
} }
} }
} }
impl MCType for MCBoolean { impl MCBoolean {
fn read(t: &mut TcpStream) -> std::io::Result<MCBoolean> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCBoolean> {
let b = read_byte(t)?; let b = read_byte(t).await?;
Ok(MCBoolean::try_from(vec![b]).unwrap()) Ok(MCBoolean::try_from(vec![b]).unwrap())
} }
} }
@ -189,12 +187,12 @@ pub mod other {
out out
} }
} }
impl MCType for MCString { impl MCString {
fn read(t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
let str_len = MCVarInt::read(t)?; let str_len = MCVarInt::read(t).await?;
let mut str_bytes = vec![]; let mut str_bytes = vec![];
for _ in 0..str_len.into() { for _ in 0..str_len.into() {
str_bytes.push(read_byte(t)?); str_bytes.push(read_byte(t).await?);
} }
Ok(MCString { Ok(MCString {
value: String::from_utf8_lossy(&str_bytes).to_string(), value: String::from_utf8_lossy(&str_bytes).to_string(),
@ -244,8 +242,8 @@ pub mod other {
out out
} }
} }
impl MCType for MCChat { impl MCChat {
fn read(_t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(_t: &mut TcpStream) -> std::io::Result<Self> {
Err(io_error("Cannot read MCChat from stream")) Err(io_error("Cannot read MCChat from stream"))
} }
} }
@ -263,8 +261,8 @@ pub mod numbers {
pub value: i8, // -128 to 127 pub value: i8, // -128 to 127
} }
impl MCByte { impl MCByte {
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCByte> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCByte> {
Ok(MCByte::from_bytes(vec![read_byte(t)?])) Ok(MCByte::from_bytes(vec![read_byte(t).await?]))
} }
pub fn from_bytes(v: Vec<u8>) -> MCByte { pub fn from_bytes(v: Vec<u8>) -> MCByte {
MCByte { MCByte {
@ -314,15 +312,6 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCByte {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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` /// The equivalent of a `u8`
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -330,8 +319,8 @@ pub mod numbers {
pub value: u8, // 0 to 255 pub value: u8, // 0 to 255
} }
impl MCUnsignedByte { impl MCUnsignedByte {
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCUnsignedByte> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCUnsignedByte> {
Ok(MCUnsignedByte::from_bytes(vec![read_byte(t)?])) Ok(MCUnsignedByte::from_bytes(vec![read_byte(t).await?]))
} }
pub fn from_bytes(v: Vec<u8>) -> MCUnsignedByte { pub fn from_bytes(v: Vec<u8>) -> MCUnsignedByte {
MCUnsignedByte { MCUnsignedByte {
@ -381,15 +370,6 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCUnsignedByte {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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` /// The equivalent of an `i16`
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -397,10 +377,10 @@ pub mod numbers {
pub value: i16, // -32768 to 32767 pub value: i16, // -32768 to 32767
} }
impl MCShort { impl MCShort {
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCShort> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCShort> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
bytes.push(read_byte(t)?); // MSD bytes.push(read_byte(t).await?); // MSD
bytes.push(read_byte(t)?); // LSD bytes.push(read_byte(t).await?); // LSD
Ok(MCShort::from_bytes(bytes)) Ok(MCShort::from_bytes(bytes))
} }
pub fn from_bytes(v: Vec<u8>) -> MCShort { pub fn from_bytes(v: Vec<u8>) -> MCShort {
@ -453,15 +433,6 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCShort {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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` /// The equivalent of a `u16`
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -469,10 +440,10 @@ pub mod numbers {
pub value: u16, // 0 to 65535 pub value: u16, // 0 to 65535
} }
impl MCUnsignedShort { impl MCUnsignedShort {
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCUnsignedShort> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCUnsignedShort> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
bytes.push(read_byte(t)?); // MSD bytes.push(read_byte(t).await?); // MSD
bytes.push(read_byte(t)?); // LSD bytes.push(read_byte(t).await?); // LSD
Ok(MCUnsignedShort::from_bytes(bytes)) Ok(MCUnsignedShort::from_bytes(bytes))
} }
pub fn from_bytes(v: Vec<u8>) -> MCUnsignedShort { pub fn from_bytes(v: Vec<u8>) -> MCUnsignedShort {
@ -525,15 +496,6 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCUnsignedShort {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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` /// The equivalent of an `i32`
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -541,10 +503,10 @@ pub mod numbers {
pub value: i32, // -2147483648 to 2147483647 pub value: i32, // -2147483648 to 2147483647
} }
impl MCInt { impl MCInt {
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCInt> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCInt> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
for _ in 0..4 { for _ in 0..4 {
bytes.push(read_byte(t)?); bytes.push(read_byte(t).await?);
} }
Ok(MCInt::from_bytes(bytes)) Ok(MCInt::from_bytes(bytes))
} }
@ -598,15 +560,6 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCInt {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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` /// The equivalent of a `u32`
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -614,10 +567,10 @@ pub mod numbers {
pub value: u32, // 0 to 4294967295 pub value: u32, // 0 to 4294967295
} }
impl MCUnsignedInt { impl MCUnsignedInt {
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCUnsignedInt> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCUnsignedInt> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
for _ in 0..4 { for _ in 0..4 {
bytes.push(read_byte(t)?); bytes.push(read_byte(t).await?);
} }
Ok(MCUnsignedInt::from_bytes(bytes)) Ok(MCUnsignedInt::from_bytes(bytes))
} }
@ -671,15 +624,6 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCUnsignedInt {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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` /// The equivalent of an `864`
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -687,10 +631,10 @@ pub mod numbers {
pub value: i64, // -9223372036854775808 to 9223372036854775807 pub value: i64, // -9223372036854775808 to 9223372036854775807
} }
impl MCLong { impl MCLong {
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCLong> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCLong> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
for _ in 0..8 { for _ in 0..8 {
bytes.push(read_byte(t)?); bytes.push(read_byte(t).await?);
} }
Ok(MCLong::from_bytes(bytes)) Ok(MCLong::from_bytes(bytes))
} }
@ -744,15 +688,6 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCLong {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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` /// The equivalent of a `u64`
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -760,10 +695,10 @@ pub mod numbers {
pub value: u64, // 0 to 18446744073709551615 pub value: u64, // 0 to 18446744073709551615
} }
impl MCUnsignedLong { impl MCUnsignedLong {
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCUnsignedLong> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCUnsignedLong> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
for _ in 0..8 { for _ in 0..8 {
bytes.push(read_byte(t)?); bytes.push(read_byte(t).await?);
} }
Ok(MCUnsignedLong::from_bytes(bytes)) Ok(MCUnsignedLong::from_bytes(bytes))
} }
@ -817,15 +752,6 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCUnsignedLong {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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` /// The equivalent of a `f32`
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -833,10 +759,10 @@ pub mod numbers {
pub value: f32, // 32-bit floating point number pub value: f32, // 32-bit floating point number
} }
impl MCFloat { impl MCFloat {
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCFloat> { pub async fn read(t: &mut TcpStream) -> std::io::Result<MCFloat> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
for _ in 0..4 { for _ in 0..4 {
bytes.push(read_byte(t)?); bytes.push(read_byte(t).await?);
} }
Ok(MCFloat::from_bytes(bytes)) Ok(MCFloat::from_bytes(bytes))
} }
@ -890,21 +816,31 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCFloat {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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` /// The equivalent of a `f64`
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCDouble { pub struct MCDouble {
pub value: f64, // 64-bit floating point number pub value: f64, // 64-bit floating point number
} }
impl MCDouble {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCDouble> {
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<u8>) -> 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<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<f64> for MCDouble { impl From<f64> for MCDouble {
fn from(v: f64) -> MCDouble { fn from(v: f64) -> MCDouble {
MCDouble { value: v } MCDouble { value: v }
@ -944,21 +880,37 @@ pub mod numbers {
self.value.to_be_bytes().to_vec() self.value.to_be_bytes().to_vec()
} }
} }
impl MCType for MCDouble {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
let mut bytes = Vec::new();
for _ in 0..8 {
bytes.push(read_byte(t)?);
}
Ok(MCDouble::try_from(bytes).unwrap())
}
}
/// A variable-length integer. /// A variable-length integer.
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCVarInt { pub struct MCVarInt {
pub value: i32, // Variable length 32-bit integer pub value: i32, // Variable length 32-bit integer
} }
impl MCVarInt {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCVarInt> {
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<u8>) -> MCVarInt {
unimplemented!()
}
pub fn to_bytes(&self) -> Vec<u8> {
unimplemented!()
}
}
impl From<i32> for MCVarInt { impl From<i32> for MCVarInt {
fn from(v: i32) -> MCVarInt { fn from(v: i32) -> MCVarInt {
MCVarInt { value: v } MCVarInt { value: v }
@ -1018,23 +970,4 @@ pub mod numbers {
return out; return out;
} }
} }
impl MCType for MCVarInt {
fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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 })
}
}
} }

View File

@ -9,7 +9,7 @@ impl GameServer {
/// Update the game server. /// Update the game server.
/// ///
/// Start by updating the network. /// Start by updating the network.
pub fn update(&mut self) { pub async fn update(&mut self) {
self.network.update(); self.network.update().await;
} }
} }

View File

@ -41,7 +41,7 @@ impl NetworkServer {
} }
} }
/// Update each client in `self.clients`. /// Update each client in `self.clients`.
pub fn update(&mut self) { pub async fn update(&mut self) {
loop { loop {
match self.receiver.try_recv() { match self.receiver.try_recv() {
Ok(client) => { Ok(client) => {
@ -56,7 +56,7 @@ impl NetworkServer {
} }
} }
for client in self.clients.iter_mut() { 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, /// Updating could mean connecting new clients, reading packets,
/// writing packets, or disconnecting clients. /// writing packets, or disconnecting clients.
pub fn update(&mut self) { pub async fn update(&mut self) {
match self.state { match self.state {
NetworkClientState::Handshake => { NetworkClientState::Handshake => {
let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).unwrap(); let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await.unwrap();
let handshake = Handshake::read(&mut self.stream).unwrap(); let handshake = Handshake::read(&mut self.stream).await.unwrap();
// Minecraft versions 1.8 - 1.8.9 use protocol version 47. // Minecraft versions 1.8 - 1.8.9 use protocol version 47.
let compatible_versions = handshake.protocol_version == 47; let compatible_versions = handshake.protocol_version == 47;
let next_state = match handshake.next_state.into() { let next_state = match handshake.next_state.into() {
@ -103,14 +103,14 @@ impl NetworkClient {
logindisconnect.reason = MCChat { logindisconnect.reason = MCChat {
text: MCString::from("Incompatible client! Server is on 1.8.9"), 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; self.state = NetworkClientState::Disconnected;
} }
debug!("Got handshake: {:?}", handshake); debug!("Got handshake: {:?}", handshake);
} }
NetworkClientState::Status => { NetworkClientState::Status => {
let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).unwrap(); let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await.unwrap();
let statusrequest = StatusRequest::read(&mut self.stream).unwrap(); let statusrequest = StatusRequest::read(&mut self.stream).await.unwrap();
debug!("Got status request: {:?}", statusrequest); debug!("Got status request: {:?}", statusrequest);
let mut statusresponse = StatusResponse::new(); let mut statusresponse = StatusResponse::new();
statusresponse.json_response = json!({ statusresponse.json_response = json!({
@ -123,7 +123,7 @@ impl NetworkClient {
"online": 5, "online": 5,
"sample": [ "sample": [
{ {
"name": "ElementG9", "name": "shvr",
"id": "e3f58380-60bb-4714-91f2-151d525e64aa" "id": "e3f58380-60bb-4714-91f2-151d525e64aa"
} }
] ]
@ -136,27 +136,27 @@ impl NetworkClient {
}) })
.to_string() .to_string()
.into(); .into();
statusresponse.write(&mut self.stream).unwrap(); statusresponse.write(&mut self.stream).await.unwrap();
debug!("Sending status response: StatusResponse"); debug!("Sending status response: StatusResponse");
let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).unwrap(); let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await.unwrap();
let statusping = StatusPing::read(&mut self.stream).unwrap(); let statusping = StatusPing::read(&mut self.stream).await.unwrap();
debug!("Got status ping: {:?}", statusping); debug!("Got status ping: {:?}", statusping);
let mut statuspong = StatusPong::new(); let mut statuspong = StatusPong::new();
statuspong.payload = statusping.payload; statuspong.payload = statusping.payload;
statuspong.write(&mut self.stream).unwrap(); statuspong.write(&mut self.stream).await.unwrap();
debug!("Sending status pong: {:?}", statuspong); debug!("Sending status pong: {:?}", statuspong);
self.state = NetworkClientState::Disconnected; self.state = NetworkClientState::Disconnected;
} }
NetworkClientState::Login => { NetworkClientState::Login => {
let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).unwrap(); let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await.unwrap();
let loginstart = LoginStart::read(&mut self.stream).unwrap(); let loginstart = LoginStart::read(&mut self.stream).await.unwrap();
debug!("{:?}", loginstart); debug!("{:?}", loginstart);
// Offline mode skips encryption and compression. // Offline mode skips encryption and compression.
let mut loginsuccess = LoginSuccess::new(); let mut loginsuccess = LoginSuccess::new();
// We're in offline mode, so this is a temporary uuid. // We're in offline mode, so this is a temporary uuid.
loginsuccess.uuid = "00000000-0000-3000-0000-000000000000".into(); loginsuccess.uuid = "00000000-0000-3000-0000-000000000000".into();
loginsuccess.username = loginstart.player_name; loginsuccess.username = loginstart.player_name;
loginsuccess.write(&mut self.stream).unwrap(); loginsuccess.write(&mut self.stream).await.unwrap();
debug!("{:?}", loginsuccess); debug!("{:?}", loginsuccess);
self.state = NetworkClientState::Play; self.state = NetworkClientState::Play;
} }

View File

@ -1,4 +1,3 @@
use super::Packet;
use crate::mctypes::*; use crate::mctypes::*;
use std::convert::{Into, TryFrom}; use std::convert::{Into, TryFrom};
use std::net::TcpStream; use std::net::TcpStream;
@ -23,18 +22,18 @@ impl TryFrom<Vec<u8>> for StatusResponse {
Err("unimplemented") Err("unimplemented")
} }
} }
impl Packet for StatusResponse { impl StatusResponse {
fn new() -> Self { pub fn new() -> Self {
StatusResponse { StatusResponse {
json_response: MCString::from(""), json_response: MCString::from(""),
} }
} }
fn read(t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(t: &'_ mut TcpStream) -> std::io::Result<Self> {
let mut statusresponse = StatusResponse::new(); let mut statusresponse = StatusResponse::new();
statusresponse.json_response = MCString::read(t)?; statusresponse.json_response = MCString::read(t).await?;
Ok(statusresponse) 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::<Vec<u8>>::into(self.clone()) { for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?; write_byte(t, b)?;
} }
@ -62,16 +61,16 @@ impl TryFrom<Vec<u8>> for StatusPong {
Err("unimplemented") Err("unimplemented")
} }
} }
impl Packet for StatusPong { impl StatusPong {
fn new() -> Self { pub fn new() -> Self {
StatusPong { payload: 0.into() } StatusPong { payload: 0.into() }
} }
fn read(t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
let mut statuspong = StatusPong::new(); let mut statuspong = StatusPong::new();
statuspong.payload = MCLong::read(t)?; statuspong.payload = MCLong::read(t).await?;
Ok(statuspong) 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::<Vec<u8>>::into(self.clone()) { for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?; write_byte(t, b)?;
} }
@ -101,20 +100,20 @@ impl TryFrom<Vec<u8>> for LoginSuccess {
Err("unimplemented") Err("unimplemented")
} }
} }
impl Packet for LoginSuccess { impl LoginSuccess {
fn new() -> Self { pub fn new() -> Self {
LoginSuccess { LoginSuccess {
uuid: MCString::from(""), uuid: MCString::from(""),
username: MCString::from(""), username: MCString::from(""),
} }
} }
fn read(t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
let mut loginsuccess = LoginSuccess::new(); let mut loginsuccess = LoginSuccess::new();
loginsuccess.uuid = MCString::read(t)?; loginsuccess.uuid = MCString::read(t).await?;
loginsuccess.username = MCString::read(t)?; loginsuccess.username = MCString::read(t).await?;
Ok(loginsuccess) 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::<Vec<u8>>::into(self.clone()) { for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?; write_byte(t, b)?;
} }
@ -142,22 +141,22 @@ impl TryFrom<Vec<u8>> for LoginDisconnect {
Err("unimplemented") Err("unimplemented")
} }
} }
impl Packet for LoginDisconnect { impl LoginDisconnect {
fn new() -> Self { pub fn new() -> Self {
LoginDisconnect { LoginDisconnect {
reason: MCChat { reason: MCChat {
text: MCString::from(""), text: MCString::from(""),
}, },
} }
} }
fn read(t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
let mut logindisconnect = LoginDisconnect::new(); let mut logindisconnect = LoginDisconnect::new();
logindisconnect.reason = MCChat { logindisconnect.reason = MCChat {
text: MCString::read(t)?, text: MCString::read(t).await?,
}; };
Ok(logindisconnect) 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::<Vec<u8>>::into(self.clone()) { for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?; write_byte(t, b)?;
} }

View File

@ -3,24 +3,14 @@ pub mod clientbound;
/// The packets that get sent to the server by the client. /// The packets that get sent to the server by the client.
pub mod serverbound; pub mod serverbound;
use crate::mctypes::{MCType, MCVarInt}; use crate::mctypes::MCVarInt;
pub use clientbound::*; pub use clientbound::*;
pub use serverbound::*; pub use serverbound::*;
use std::convert::{Into, TryFrom};
use std::net::TcpStream; use std::net::TcpStream;
/// All packets need to serialize/deserialize to/from `Vec<u8>`.
pub trait Packet: Into<Vec<u8>> + TryFrom<Vec<u8>> {
fn new() -> Self;
/// Read the packet body from the given `TcpStream`.
fn read(_stream: &mut TcpStream) -> std::io::Result<Self>;
/// 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. /// A helper function to read the packet header.
pub fn read_packet_header(t: &mut TcpStream) -> std::io::Result<(MCVarInt, MCVarInt)> { pub async fn read_packet_header(t: &mut TcpStream) -> std::io::Result<(MCVarInt, MCVarInt)> {
let length = MCVarInt::read(t)?; let length = MCVarInt::read(t).await?;
let id = MCVarInt::read(t)?; let id = MCVarInt::read(t).await?;
Ok((length, id)) Ok((length, id))
} }

View File

@ -1,4 +1,3 @@
use super::Packet;
use crate::mctypes::*; use crate::mctypes::*;
use std::convert::{Into, TryFrom}; use std::convert::{Into, TryFrom};
use std::net::TcpStream; use std::net::TcpStream;
@ -30,8 +29,8 @@ impl TryFrom<Vec<u8>> for Handshake {
Err("unimplemented") Err("unimplemented")
} }
} }
impl Packet for Handshake { impl Handshake {
fn new() -> Self { pub fn new() -> Self {
Handshake { Handshake {
protocol_version: 0.into(), protocol_version: 0.into(),
server_address: "".into(), server_address: "".into(),
@ -39,15 +38,15 @@ impl Packet for Handshake {
next_state: 0.into(), next_state: 0.into(),
} }
} }
fn read(t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
let mut handshake = Handshake::new(); let mut handshake = Handshake::new();
handshake.protocol_version = MCVarInt::read(t)?; handshake.protocol_version = MCVarInt::read(t).await?;
handshake.server_address = MCString::read(t)?; handshake.server_address = MCString::read(t).await?;
handshake.server_port = MCUnsignedShort::read(t)?; handshake.server_port = MCUnsignedShort::read(t).await?;
handshake.next_state = MCVarInt::read(t)?; handshake.next_state = MCVarInt::read(t).await?;
Ok(handshake) 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::<Vec<u8>>::into(self.clone()) { for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?; write_byte(t, b)?;
} }
@ -72,15 +71,15 @@ impl TryFrom<Vec<u8>> for StatusRequest {
Err("unimplemented") Err("unimplemented")
} }
} }
impl Packet for StatusRequest { impl StatusRequest {
fn new() -> Self { pub fn new() -> Self {
StatusRequest {} StatusRequest {}
} }
fn read(_t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(_t: &mut TcpStream) -> std::io::Result<Self> {
let statusrequest = StatusRequest::new(); let statusrequest = StatusRequest::new();
Ok(statusrequest) 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::<Vec<u8>>::into(self.clone()) { for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?; write_byte(t, b)?;
} }
@ -108,16 +107,16 @@ impl TryFrom<Vec<u8>> for StatusPing {
Err("unimplemented") Err("unimplemented")
} }
} }
impl Packet for StatusPing { impl StatusPing {
fn new() -> Self { pub fn new() -> Self {
StatusPing { payload: 0.into() } StatusPing { payload: 0.into() }
} }
fn read(t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
let mut statusping = StatusPing::new(); let mut statusping = StatusPing::new();
statusping.payload = MCLong::read(t)?; statusping.payload = MCLong::read(t).await?;
Ok(statusping) 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::<Vec<u8>>::into(self.clone()) { for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?; write_byte(t, b)?;
} }
@ -145,18 +144,18 @@ impl TryFrom<Vec<u8>> for LoginStart {
Err("unimplemented") Err("unimplemented")
} }
} }
impl Packet for LoginStart { impl LoginStart {
fn new() -> Self { pub fn new() -> Self {
LoginStart { LoginStart {
player_name: "".into(), player_name: "".into(),
} }
} }
fn read(t: &mut TcpStream) -> std::io::Result<Self> { pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
let mut loginstart = LoginStart::new(); let mut loginstart = LoginStart::new();
loginstart.player_name = MCString::read(t)?; loginstart.player_name = MCString::read(t).await?;
Ok(loginstart) 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::<Vec<u8>>::into(self.clone()) { for b in Into::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?; write_byte(t, b)?;
} }