From 6fa9ee968ebcbd1672fa18fe8176ea8135c2e749 Mon Sep 17 00:00:00 2001 From: Garen Tyler Date: Wed, 17 Mar 2021 21:16:20 -0600 Subject: [PATCH] Player spawning works --- src/mctypes.rs | 60 +++++++++++++++++++++++++++++++ src/server/mod.rs | 5 ++- src/server/packets/clientbound.rs | 41 +++++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/src/mctypes.rs b/src/mctypes.rs index 8a1ea93..9cae875 100644 --- a/src/mctypes.rs +++ b/src/mctypes.rs @@ -247,6 +247,66 @@ pub mod other { Err(io_error("Cannot read MCChat from stream")) } } + + // TODO: Actually make the MCPosition work. + #[derive(Debug, PartialEq, Clone)] + pub struct MCPosition { + x: MCLong, + y: MCLong, + z: MCLong, + } + impl Display for MCPosition { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "({}, {}, {})", + self.x, + self.y, + self.z, + ) + } + } + impl TryFrom> for MCPosition { + type Error = &'static str; + fn try_from(_bytes: Vec) -> Result { + Err("Cannot read MCPosition from bytes") + } + } + impl Into> for MCPosition { + fn into(self) -> Vec { + // Just output + // {"text": ""} + let mut out = vec![]; + let mut temp = vec![]; + temp.extend_from_slice( + &( + ( + ((Into::::into(self.x) & 0x3FFFFFF) << 38) + | ((Into::::into(self.y) & 0xFFF) << 26) + | (Into::::into(self.z) & 0x3FFFFFF) + ) as u64 + ).to_be_bytes() + ); + // temp.extend_from_slice(&"{\"text\": \"".to_owned().into_bytes()); + // temp.extend_from_slice(&self.text.value.into_bytes()); + // temp.extend_from_slice(&"\"}".to_owned().into_bytes()); + out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); + out.extend_from_slice(&temp); + out + } + } + impl MCPosition { + pub fn new() -> MCPosition { + MCPosition { + x: 0.into(), + y: 0.into(), + z: 0.into(), + } + } + pub async fn read(_t: &mut TcpStream) -> tokio::io::Result { + Err(io_error("Cannot read MCPosition from stream")) + } + } } /// All the numbers, from `i8` and `u8` to `i64` and `u64`, plus `VarInt`s. diff --git a/src/server/mod.rs b/src/server/mod.rs index c9fbd2a..bbf30d7 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -225,7 +225,7 @@ impl NetworkClient { // TODO: S->C Player Position and Look let playerpositionandlook = PlayerPositionAndLook::new(); // TODO: Retrieve player position from storage. - // playerpositionandlook.write(&mut self.stream).await.unwrap(); + playerpositionandlook.write(&mut self.stream).await.unwrap(); debug!("{:?}", playerpositionandlook); // TODO: S->C Player Info (Add Player action) (1.16?) // TODO: S->C Player Info (Update latency action) (1.16?) @@ -234,6 +234,9 @@ impl NetworkClient { // TODO: S->C Chunk Data // TODO: S->C World Border // TODO: S->C Spawn Position + let spawnposition = SpawnPosition::new(); + spawnposition.write(&mut self.stream).await.unwrap(); + debug!("{:?}", spawnposition); // TODO: S->C Player Position and Look // TODO: C->S Teleport Confirm // TODO: C->S Player Position and Look diff --git a/src/server/packets/clientbound.rs b/src/server/packets/clientbound.rs index 1c3eec8..9962b5a 100644 --- a/src/server/packets/clientbound.rs +++ b/src/server/packets/clientbound.rs @@ -391,3 +391,44 @@ impl PlayerPositionAndLook { Ok(()) } } + +// TODO: Actually send the position. +#[derive(Debug, Clone)] +pub struct SpawnPosition { + position: MCPosition, +} +impl Into> for SpawnPosition { + fn into(self) -> Vec { + let mut out = vec![]; + let mut temp: Vec = MCVarInt::from(0x05).into(); // 0x05 Spawn Position. + // temp.extend_from_slice(&Into::>::into(self.position)); + temp.extend_from_slice(&0u64.to_be_bytes()); + out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); + out.extend_from_slice(&temp); + out + } +} +impl TryFrom> for SpawnPosition { + type Error = &'static str; + fn try_from(_bytes: Vec) -> Result { + Err("unimplemented") + } +} +impl SpawnPosition { + pub fn new() -> Self { + SpawnPosition { + position: MCPosition::new(), + } + } + pub async fn read(t: &mut TcpStream) -> tokio::io::Result { + let mut spawnposition = SpawnPosition::new(); + spawnposition.position = MCPosition::read(t).await?; + Ok(spawnposition) + } + pub async fn write(&self, t: &mut TcpStream) -> tokio::io::Result<()> { + for b in Into::>::into(self.clone()) { + write_byte(t, b).await?; + } + Ok(()) + } +}