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"
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"

View File

@ -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)

View File

@ -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 };

View File

@ -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));
}
}

View File

@ -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<u8>`.
pub trait MCType: Into<Vec<u8>> + TryFrom<Vec<u8>> + Display {
fn read(_stream: &mut TcpStream) -> std::io::Result<Self>;
}
// /// Make sure all types can serialize and deserialize to/from `Vec<u8>`.
// pub trait MCType: Into<Vec<u8>> + TryFrom<Vec<u8>> + Display {
// pub async fn read(_stream: &mut TcpStream) -> std::io::Result<Self>;
// }
/// 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<u8> {
pub async fn read_byte(t: &mut TcpStream) -> std::io::Result<u8> {
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<MCBoolean> {
let b = read_byte(t)?;
impl MCBoolean {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCBoolean> {
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<Self> {
let str_len = MCVarInt::read(t)?;
impl MCString {
pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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<Self> {
impl MCChat {
pub async fn read(_t: &mut TcpStream) -> std::io::Result<Self> {
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<MCByte> {
Ok(MCByte::from_bytes(vec![read_byte(t)?]))
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCByte> {
Ok(MCByte::from_bytes(vec![read_byte(t).await?]))
}
pub fn from_bytes(v: Vec<u8>) -> 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<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`
#[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<MCUnsignedByte> {
Ok(MCUnsignedByte::from_bytes(vec![read_byte(t)?]))
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCUnsignedByte> {
Ok(MCUnsignedByte::from_bytes(vec![read_byte(t).await?]))
}
pub fn from_bytes(v: Vec<u8>) -> 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<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`
#[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<MCShort> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCShort> {
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<u8>) -> 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<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`
#[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<MCUnsignedShort> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCUnsignedShort> {
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<u8>) -> 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<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`
#[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<MCInt> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCInt> {
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<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`
#[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<MCUnsignedInt> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCUnsignedInt> {
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<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`
#[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<MCLong> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCLong> {
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<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`
#[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<MCUnsignedLong> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCUnsignedLong> {
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<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`
#[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<MCFloat> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<MCFloat> {
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<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`
#[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<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 {
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<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.
#[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<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 {
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<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.
///
/// Start by updating the network.
pub fn update(&mut self) {
self.network.update();
pub async fn update(&mut self) {
self.network.update().await;
}
}

View File

@ -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;
}

View File

@ -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<Vec<u8>> 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<Self> {
pub async fn read(t: &'_ mut TcpStream) -> std::io::Result<Self> {
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::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?;
}
@ -62,16 +61,16 @@ impl TryFrom<Vec<u8>> 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<Self> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?;
}
@ -101,20 +100,20 @@ impl TryFrom<Vec<u8>> 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<Self> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?;
}
@ -142,22 +141,22 @@ impl TryFrom<Vec<u8>> 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<Self> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?;
}

View File

@ -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<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.
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))
}

View File

@ -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<Vec<u8>> 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<Self> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?;
}
@ -72,15 +71,15 @@ impl TryFrom<Vec<u8>> 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<Self> {
pub async fn read(_t: &mut TcpStream) -> std::io::Result<Self> {
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::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?;
}
@ -108,16 +107,16 @@ impl TryFrom<Vec<u8>> 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<Self> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?;
}
@ -145,18 +144,18 @@ impl TryFrom<Vec<u8>> 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<Self> {
pub async fn read(t: &mut TcpStream) -> std::io::Result<Self> {
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::<Vec<u8>>::into(self.clone()) {
write_byte(t, b)?;
}