From 6841e785d92ddffe9bd4b7ad29170840af1a8b24 Mon Sep 17 00:00:00 2001 From: Garen Tyler Date: Fri, 19 Mar 2021 20:50:10 -0600 Subject: [PATCH] Better packet logging, player movement packets read --- src/mctypes.rs | 15 ++ src/server/net/mod.rs | 52 +++-- src/server/net/packets/clientbound.rs | 74 +++++-- src/server/net/packets/mod.rs | 12 +- src/server/net/packets/serverbound.rs | 283 +++++++++++++++++++++++++- 5 files changed, 391 insertions(+), 45 deletions(-) diff --git a/src/mctypes.rs b/src/mctypes.rs index 83d7a7b..8b76d2e 100644 --- a/src/mctypes.rs +++ b/src/mctypes.rs @@ -1014,6 +1014,21 @@ pub mod numbers { unimplemented!() } } + impl From for MCVarInt { + fn from(v: u8) -> MCVarInt { + MCVarInt { value: v as i32 } + } + } + impl Into for MCVarInt { + fn into(self) -> u8 { + self.value as u8 + } + } + impl PartialEq for MCVarInt { + fn eq(&self, other: &u8) -> bool { + self.value == *other as i32 + } + } impl From for MCVarInt { fn from(v: i32) -> MCVarInt { MCVarInt { value: v } diff --git a/src/server/net/mod.rs b/src/server/net/mod.rs index 5465e4d..9fe8a37 100644 --- a/src/server/net/mod.rs +++ b/src/server/net/mod.rs @@ -72,12 +72,10 @@ impl NetworkClient { self.send_packet(logindisconnect).await?; self.state = NetworkClientState::Disconnected; } - debug!("{:?}", handshake); } NetworkClientState::Status => { let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await?; - let statusrequest = self.get_packet::().await?; - debug!("{:?}", statusrequest); + let _statusrequest = self.get_packet::().await?; let mut statusresponse = StatusResponse::new(); statusresponse.json_response = json!({ "version": { @@ -104,7 +102,6 @@ impl NetworkClient { self.send_packet(statusresponse).await?; let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await?; let statusping = self.get_packet::().await?; - debug!("{:?}", statusping); let mut statuspong = StatusPong::new(); statuspong.payload = statusping.payload; self.send_packet(statuspong).await?; @@ -113,7 +110,6 @@ impl NetworkClient { NetworkClientState::Login => { let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await?; let loginstart = self.get_packet::().await?; - debug!("{:?}", loginstart); // Offline mode skips encryption and compression. // TODO: Encryption and compression let mut loginsuccess = LoginSuccess::new(); @@ -129,9 +125,8 @@ impl NetworkClient { // TODO: Fill out `joingame` with actual information. self.send_packet(joingame).await?; let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await?; - let clientsettings = self.get_packet::().await?; + let _clientsettings = self.get_packet::().await?; // TODO: Actually use client settings. - debug!("{:?}", clientsettings); let helditemchange = HeldItemChange::new(); // TODO: Retrieve selected slot from storage. self.send_packet(helditemchange).await?; @@ -141,7 +136,7 @@ impl NetworkClient { // TODO: S->C Declare Commands (1.16?) // TODO: S->C Unlock Recipes (1.16?) // TODO: S->C Player Position and Look - let playerpositionandlook = PlayerPositionAndLook::new(); + let playerpositionandlook = ClientboundPlayerPositionAndLook::new(); // TODO: Retrieve player position from storage. self.send_packet(playerpositionandlook).await?; // TODO: S->C Player Info (Add Player action) (1.16?) @@ -172,6 +167,31 @@ impl NetworkClient { self.send_chat_message("keep alive").await?; self.keep_alive().await?; } + let (packet_length, packet_id) = read_packet_header(&mut self.stream).await?; + // debug!("{}", packet_id); + if packet_id == Player::id() { + let _player = self.get_packet::().await?; + } else if packet_id == PlayerPosition::id() { + let _playerposition = self.get_packet::().await?; + } else if packet_id == PlayerLook::id() { + let _playerlook = self.get_packet::().await?; + } else if packet_id == ServerboundPlayerPositionAndLook::id() { + let _playerpositionandlook = self + .get_packet::() + .await?; + } else if packet_id == ServerboundChatMessage::id() { + let serverboundchatmessage = + self.get_packet::().await?; + self.send_chat_message(format!( + "<{}> {}", + self.username.as_ref().unwrap_or(&"unknown".to_owned()), + serverboundchatmessage.text + )) + .await?; + } else { + let _ = read_bytes(&mut self.stream, Into::::into(packet_length) as usize) + .await?; + } } NetworkClientState::Disconnected => { if self.connected { @@ -183,17 +203,16 @@ impl NetworkClient { } /// Send a generic packet to the client. - pub async fn send_packet + core::fmt::Debug>( - &mut self, - packet: P, - ) -> tokio::io::Result<()> { - debug!("{:?}", packet); - Into::::into(packet).write(&mut self.stream).await + pub async fn send_packet(&mut self, packet: P) -> tokio::io::Result<()> { + debug!("Sent {:?} {:#04X?} {:?}", self.state, P::id(), packet); + packet.write(&mut self.stream).await } /// Read a generic packet from the network. pub async fn get_packet(&mut self) -> tokio::io::Result { - Ok(T::read(&mut self.stream).await?) + let packet = T::read(&mut self.stream).await?; + debug!("Got {:?} {:#04X?} {:?}", self.state, T::id(), packet); + Ok(packet) } /// Send the client a message in chat. @@ -231,8 +250,7 @@ impl NetworkClient { self.send_packet(clientboundkeepalive).await?; // Keep alive pong to server. let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).await?; - let serverboundkeepalive = self.get_packet::().await?; - debug!("{:?}", serverboundkeepalive); + let _serverboundkeepalive = self.get_packet::().await?; self.last_keep_alive = Instant::now(); Ok(()) } diff --git a/src/server/net/packets/clientbound.rs b/src/server/net/packets/clientbound.rs index 818ed7a..2c227cb 100644 --- a/src/server/net/packets/clientbound.rs +++ b/src/server/net/packets/clientbound.rs @@ -11,7 +11,7 @@ pub struct StatusResponse { impl Into> for StatusResponse { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x00).into(); // 0x00 Status Response. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x00 Status Response. temp.extend_from_slice(&Into::>::into(self.json_response)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); @@ -31,6 +31,9 @@ impl PacketCommon for StatusResponse { json_response: MCString::from(""), } } + fn id() -> u8 { + 0x00 + } async fn read(t: &'_ mut TcpStream) -> tokio::io::Result { let mut statusresponse = StatusResponse::new(); statusresponse.json_response = MCString::read(t).await?; @@ -51,7 +54,7 @@ pub struct StatusPong { impl Into> for StatusPong { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x01).into(); // 0x01 Status Pong. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x01 Status Pong. temp.extend_from_slice(&Into::>::into(self.payload)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); @@ -69,6 +72,9 @@ impl PacketCommon for StatusPong { fn new() -> Self { StatusPong { payload: 0.into() } } + fn id() -> u8 { + 0x01 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut statuspong = StatusPong::new(); statuspong.payload = MCLong::read(t).await?; @@ -90,7 +96,7 @@ pub struct LoginSuccess { impl Into> for LoginSuccess { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x02).into(); // 0x02 Login Success. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x02 Login Success. temp.extend_from_slice(&Into::>::into(self.uuid)); temp.extend_from_slice(&Into::>::into(self.username)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); @@ -112,6 +118,9 @@ impl PacketCommon for LoginSuccess { username: MCString::from(""), } } + fn id() -> u8 { + 0x02 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut loginsuccess = LoginSuccess::new(); loginsuccess.uuid = MCString::read(t).await?; @@ -133,7 +142,7 @@ pub struct LoginDisconnect { impl Into> for LoginDisconnect { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x00).into(); // 0x00 Login Disconnect. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x00 Login Disconnect. temp.extend_from_slice(&Into::>::into(self.reason)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); @@ -155,6 +164,9 @@ impl PacketCommon for LoginDisconnect { }, } } + fn id() -> u8 { + 0x00 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut logindisconnect = LoginDisconnect::new(); logindisconnect.reason = MCChat { @@ -183,7 +195,7 @@ pub struct JoinGame { impl Into> for JoinGame { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x01).into(); // 0x01 Join Game. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x01 Join Game. temp.extend_from_slice(&Into::>::into(self.entity_id)); temp.extend_from_slice(&Into::>::into(self.gamemode)); temp.extend_from_slice(&Into::>::into(self.dimension)); @@ -215,6 +227,9 @@ impl PacketCommon for JoinGame { reduced_debug_info: false.into(), // The debug info should be useful. } } + fn id() -> u8 { + 0x01 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut joingame = JoinGame::new(); joingame.entity_id = MCInt::read(t).await?; @@ -241,7 +256,7 @@ pub struct HeldItemChange { impl Into> for HeldItemChange { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x09).into(); // 0x09 Held Item Change. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x09 Held Item Change. temp.extend_from_slice(&Into::>::into(self.selected_slot)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); @@ -261,6 +276,9 @@ impl PacketCommon for HeldItemChange { selected_slot: 0.into(), } } + fn id() -> u8 { + 0x09 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut helditemchange = HeldItemChange::new(); helditemchange.selected_slot = MCByte::read(t).await?; @@ -305,7 +323,7 @@ pub struct EntityStatus { impl Into> for EntityStatus { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x1a).into(); // 0x1a Entity Status. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x1a Entity Status. temp.extend_from_slice(&Into::>::into(self.entity_id)); temp.extend_from_slice(&Into::>::into(self.entity_status)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); @@ -327,6 +345,9 @@ impl PacketCommon for EntityStatus { entity_status: 0.into(), } } + fn id() -> u8 { + 0x1a + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut entitystatus = EntityStatus::new(); entitystatus.entity_id = MCInt::read(t).await?; @@ -342,7 +363,7 @@ impl PacketCommon for EntityStatus { } #[derive(Debug, Clone)] -pub struct PlayerPositionAndLook { +pub struct ClientboundPlayerPositionAndLook { pub x: MCDouble, pub y: MCDouble, pub z: MCDouble, @@ -350,10 +371,10 @@ pub struct PlayerPositionAndLook { pub pitch: MCFloat, pub flags: MCByte, } -impl Into> for PlayerPositionAndLook { +impl Into> for ClientboundPlayerPositionAndLook { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x08).into(); // 0x08 Player Position and Look. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x08 Player Position and Look. temp.extend_from_slice(&Into::>::into(self.x)); temp.extend_from_slice(&Into::>::into(self.y)); temp.extend_from_slice(&Into::>::into(self.z)); @@ -365,16 +386,16 @@ impl Into> for PlayerPositionAndLook { out } } -impl TryFrom> for PlayerPositionAndLook { +impl TryFrom> for ClientboundPlayerPositionAndLook { type Error = &'static str; fn try_from(_bytes: Vec) -> Result { Err("unimplemented") } } #[async_trait::async_trait] -impl PacketCommon for PlayerPositionAndLook { +impl PacketCommon for ClientboundPlayerPositionAndLook { fn new() -> Self { - PlayerPositionAndLook { + ClientboundPlayerPositionAndLook { x: 0.0.into(), y: 0.0.into(), z: 0.0.into(), @@ -383,8 +404,11 @@ impl PacketCommon for PlayerPositionAndLook { flags: 0x00.into(), } } + fn id() -> u8 { + 0x08 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { - let mut playerpositionandlook = PlayerPositionAndLook::new(); + let mut playerpositionandlook = ClientboundPlayerPositionAndLook::new(); playerpositionandlook.x = MCDouble::read(t).await?; playerpositionandlook.y = MCDouble::read(t).await?; playerpositionandlook.z = MCDouble::read(t).await?; @@ -409,8 +433,8 @@ pub struct SpawnPosition { 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)); + let mut temp: Vec = MCVarInt::from(Self::id()).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); @@ -430,6 +454,9 @@ impl PacketCommon for SpawnPosition { position: MCPosition::new(), } } + fn id() -> u8 { + 0x05 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut spawnposition = SpawnPosition::new(); spawnposition.position = MCPosition::read(t).await?; @@ -450,7 +477,7 @@ pub struct KeepAlivePing { impl Into> for KeepAlivePing { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x00).into(); // 0x00 Keep Alive. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x00 Keep Alive. temp.extend_from_slice(&Into::>::into(self.payload)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); @@ -468,6 +495,9 @@ impl PacketCommon for KeepAlivePing { fn new() -> Self { KeepAlivePing { payload: 0.into() } } + fn id() -> u8 { + 0x00 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut keepalive = KeepAlivePing::new(); keepalive.payload = MCVarInt::read(t).await?; @@ -488,7 +518,7 @@ pub struct Disconnect { impl Into> for Disconnect { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x40).into(); // 0x40 Disconnect. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x40 Disconnect. temp.extend_from_slice(&Into::>::into(self.reason)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); @@ -510,6 +540,9 @@ impl PacketCommon for Disconnect { }, } } + fn id() -> u8 { + 0x40 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut keepalive = Disconnect::new(); keepalive.reason = MCChat::read(t).await?; @@ -531,7 +564,7 @@ pub struct ClientboundChatMessage { impl Into> for ClientboundChatMessage { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x02).into(); // 0x02 Clientbound Chat Message. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x02 Clientbound Chat Message. temp.extend_from_slice(&Into::>::into(self.text)); temp.extend_from_slice(&Into::>::into(self.position)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); @@ -553,6 +586,9 @@ impl PacketCommon for ClientboundChatMessage { position: 0.into(), } } + fn id() -> u8 { + 0x02 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut clientboundchatmessage = ClientboundChatMessage::new(); clientboundchatmessage.text = MCChat::read(t).await?; diff --git a/src/server/net/packets/mod.rs b/src/server/net/packets/mod.rs index 1f00ec0..1377b44 100644 --- a/src/server/net/packets/mod.rs +++ b/src/server/net/packets/mod.rs @@ -76,7 +76,7 @@ register_packets!( JoinGame, HeldItemChange, EntityStatus, - PlayerPositionAndLook, + ClientboundPlayerPositionAndLook, SpawnPosition, KeepAlivePing, Disconnect, @@ -87,15 +87,21 @@ register_packets!( StatusPing, LoginStart, ClientSettings, - KeepAlivePong + KeepAlivePong, + ServerboundChatMessage, + Player, + PlayerPosition, + PlayerLook, + ServerboundPlayerPositionAndLook ); #[async_trait::async_trait] -pub trait PacketCommon +pub trait PacketCommon: Into + core::fmt::Debug where Self: Sized, { fn new() -> Self; + fn id() -> u8; async fn read(t: &'_ mut TcpStream) -> tokio::io::Result; async fn write(&self, t: &'_ mut TcpStream) -> tokio::io::Result<()>; } diff --git a/src/server/net/packets/serverbound.rs b/src/server/net/packets/serverbound.rs index f34907f..b07c916 100644 --- a/src/server/net/packets/serverbound.rs +++ b/src/server/net/packets/serverbound.rs @@ -14,7 +14,7 @@ pub struct Handshake { impl Into> for Handshake { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x00).into(); // 0x00 Handshake. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x00 Handshake. temp.extend_from_slice(&Into::>::into(self.protocol_version)); temp.extend_from_slice(&Into::>::into(self.server_address)); temp.extend_from_slice(&Into::>::into(self.server_port)); @@ -40,6 +40,9 @@ impl PacketCommon for Handshake { next_state: 0.into(), } } + fn id() -> u8 { + 0x00 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut handshake = Handshake::new(); handshake.protocol_version = MCVarInt::read(t).await?; @@ -61,7 +64,7 @@ pub struct StatusRequest {} impl Into> for StatusRequest { fn into(self) -> Vec { let mut out = vec![]; - let temp: Vec = MCVarInt::from(0x00).into(); // 0x00 Status Request. + let temp: Vec = MCVarInt::from(Self::id()).into(); // 0x00 Status Request. out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); out @@ -78,6 +81,9 @@ impl PacketCommon for StatusRequest { fn new() -> Self { StatusRequest {} } + fn id() -> u8 { + 0x00 + } async fn read(_t: &mut TcpStream) -> tokio::io::Result { let statusrequest = StatusRequest::new(); Ok(statusrequest) @@ -97,7 +103,7 @@ pub struct StatusPing { impl Into> for StatusPing { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x01).into(); // 0x01 Status Pong. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x01 Status Pong. temp.extend_from_slice(&Into::>::into(self.payload)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); @@ -115,6 +121,9 @@ impl PacketCommon for StatusPing { fn new() -> Self { StatusPing { payload: 0.into() } } + fn id() -> u8 { + 0x01 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut statusping = StatusPing::new(); statusping.payload = MCLong::read(t).await?; @@ -135,7 +144,7 @@ pub struct LoginStart { impl Into> for LoginStart { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x00).into(); // 0x00 Login Start. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x00 Login Start. temp.extend_from_slice(&Into::>::into(self.player_name)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); @@ -155,6 +164,9 @@ impl PacketCommon for LoginStart { player_name: "".into(), } } + fn id() -> u8 { + 0x00 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut loginstart = LoginStart::new(); loginstart.player_name = MCString::read(t).await?; @@ -187,7 +199,7 @@ pub struct ClientSettings { impl Into> for ClientSettings { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x15).into(); // 0x15 Client Settings. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x15 Client Settings. temp.extend_from_slice(&Into::>::into(self.locale)); temp.extend_from_slice(&Into::>::into(self.view_distance)); temp.extend_from_slice(&Into::>::into(self.chat_mode)); @@ -215,6 +227,9 @@ impl PacketCommon for ClientSettings { displayed_skin_parts: 0xff.into(), // Enable all parts. } } + fn id() -> u8 { + 0x15 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut clientsettings = ClientSettings::new(); clientsettings.locale = MCString::read(t).await?; @@ -239,7 +254,7 @@ pub struct KeepAlivePong { impl Into> for KeepAlivePong { fn into(self) -> Vec { let mut out = vec![]; - let mut temp: Vec = MCVarInt::from(0x00).into(); // 0x00 Keep Alive. + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x00 Keep Alive. temp.extend_from_slice(&Into::>::into(self.payload)); out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); out.extend_from_slice(&temp); @@ -257,6 +272,9 @@ impl PacketCommon for KeepAlivePong { fn new() -> Self { KeepAlivePong { payload: 0.into() } } + fn id() -> u8 { + 0x00 + } async fn read(t: &mut TcpStream) -> tokio::io::Result { let mut keepalive = KeepAlivePong::new(); keepalive.payload = MCVarInt::read(t).await?; @@ -269,3 +287,256 @@ impl PacketCommon for KeepAlivePong { Ok(()) } } + +#[derive(Debug, Clone)] +pub struct ServerboundChatMessage { + pub text: MCString, +} +impl Into> for ServerboundChatMessage { + fn into(self) -> Vec { + let mut out = vec![]; + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x01 Serverbound Chat Message. + temp.extend_from_slice(&Into::>::into(self.text)); + out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); + out.extend_from_slice(&temp); + out + } +} +impl TryFrom> for ServerboundChatMessage { + type Error = &'static str; + fn try_from(_bytes: Vec) -> Result { + Err("unimplemented") + } +} +#[async_trait::async_trait] +impl PacketCommon for ServerboundChatMessage { + fn new() -> Self { + ServerboundChatMessage { text: "".into() } + } + fn id() -> u8 { + 0x01 + } + async fn read(t: &mut TcpStream) -> tokio::io::Result { + let mut serverboundchatmessage = ServerboundChatMessage::new(); + serverboundchatmessage.text = MCString::read(t).await?; + Ok(serverboundchatmessage) + } + async fn write(&self, t: &mut TcpStream) -> tokio::io::Result<()> { + for b in Into::>::into(self.clone()) { + write_byte(t, b).await?; + } + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct Player { + pub on_ground: MCBoolean, +} +impl Into> for Player { + fn into(self) -> Vec { + let mut out = vec![]; + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x03 Player. + temp.extend_from_slice(&Into::>::into(self.on_ground)); + out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); + out.extend_from_slice(&temp); + out + } +} +impl TryFrom> for Player { + type Error = &'static str; + fn try_from(_bytes: Vec) -> Result { + Err("unimplemented") + } +} +#[async_trait::async_trait] +impl PacketCommon for Player { + fn new() -> Self { + Player { + on_ground: false.into(), + } + } + fn id() -> u8 { + 0x03 + } + async fn read(t: &mut TcpStream) -> tokio::io::Result { + let mut player = Player::new(); + player.on_ground = MCBoolean::read(t).await?; + Ok(player) + } + async fn write(&self, t: &mut TcpStream) -> tokio::io::Result<()> { + for b in Into::>::into(self.clone()) { + write_byte(t, b).await?; + } + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct PlayerPosition { + pub x: MCDouble, + pub y: MCDouble, + pub z: MCDouble, + pub on_ground: MCBoolean, +} +impl Into> for PlayerPosition { + fn into(self) -> Vec { + let mut out = vec![]; + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x04 Player Position. + temp.extend_from_slice(&Into::>::into(self.x)); + temp.extend_from_slice(&Into::>::into(self.y)); + temp.extend_from_slice(&Into::>::into(self.z)); + temp.extend_from_slice(&Into::>::into(self.on_ground)); + out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); + out.extend_from_slice(&temp); + out + } +} +impl TryFrom> for PlayerPosition { + type Error = &'static str; + fn try_from(_bytes: Vec) -> Result { + Err("unimplemented") + } +} +#[async_trait::async_trait] +impl PacketCommon for PlayerPosition { + fn new() -> Self { + PlayerPosition { + x: 0.0.into(), + y: 0.0.into(), + z: 0.0.into(), + on_ground: false.into(), + } + } + fn id() -> u8 { + 0x04 + } + async fn read(t: &mut TcpStream) -> tokio::io::Result { + let mut playerposition = PlayerPosition::new(); + playerposition.x = MCDouble::read(t).await?; + playerposition.y = MCDouble::read(t).await?; + playerposition.z = MCDouble::read(t).await?; + playerposition.on_ground = MCBoolean::read(t).await?; + Ok(playerposition) + } + async fn write(&self, t: &mut TcpStream) -> tokio::io::Result<()> { + for b in Into::>::into(self.clone()) { + write_byte(t, b).await?; + } + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct PlayerLook { + pub yaw: MCFloat, + pub pitch: MCFloat, + pub on_ground: MCBoolean, +} +impl Into> for PlayerLook { + fn into(self) -> Vec { + let mut out = vec![]; + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x05 Player Look. + temp.extend_from_slice(&Into::>::into(self.yaw)); + temp.extend_from_slice(&Into::>::into(self.pitch)); + temp.extend_from_slice(&Into::>::into(self.on_ground)); + out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); + out.extend_from_slice(&temp); + out + } +} +impl TryFrom> for PlayerLook { + type Error = &'static str; + fn try_from(_bytes: Vec) -> Result { + Err("unimplemented") + } +} +#[async_trait::async_trait] +impl PacketCommon for PlayerLook { + fn new() -> Self { + PlayerLook { + yaw: 0.0.into(), + pitch: 0.0.into(), + on_ground: false.into(), + } + } + fn id() -> u8 { + 0x05 + } + async fn read(t: &mut TcpStream) -> tokio::io::Result { + let mut playerlook = PlayerLook::new(); + playerlook.yaw = MCFloat::read(t).await?; + playerlook.pitch = MCFloat::read(t).await?; + playerlook.on_ground = MCBoolean::read(t).await?; + Ok(playerlook) + } + async fn write(&self, t: &mut TcpStream) -> tokio::io::Result<()> { + for b in Into::>::into(self.clone()) { + write_byte(t, b).await?; + } + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct ServerboundPlayerPositionAndLook { + pub x: MCDouble, + pub y: MCDouble, + pub z: MCDouble, + pub yaw: MCFloat, + pub pitch: MCFloat, + pub on_ground: MCBoolean, +} +impl Into> for ServerboundPlayerPositionAndLook { + fn into(self) -> Vec { + let mut out = vec![]; + let mut temp: Vec = MCVarInt::from(Self::id()).into(); // 0x06 Serverbound Player Position And Look. + temp.extend_from_slice(&Into::>::into(self.x)); + temp.extend_from_slice(&Into::>::into(self.y)); + temp.extend_from_slice(&Into::>::into(self.z)); + temp.extend_from_slice(&Into::>::into(self.yaw)); + temp.extend_from_slice(&Into::>::into(self.pitch)); + temp.extend_from_slice(&Into::>::into(self.on_ground)); + out.extend_from_slice(&Into::>::into(MCVarInt::from(temp.len() as i32))); + out.extend_from_slice(&temp); + out + } +} +impl TryFrom> for ServerboundPlayerPositionAndLook { + type Error = &'static str; + fn try_from(_bytes: Vec) -> Result { + Err("unimplemented") + } +} +#[async_trait::async_trait] +impl PacketCommon for ServerboundPlayerPositionAndLook { + fn new() -> Self { + ServerboundPlayerPositionAndLook { + x: 0.0.into(), + y: 0.0.into(), + z: 0.0.into(), + yaw: 0.0.into(), + pitch: 0.0.into(), + on_ground: false.into(), + } + } + fn id() -> u8 { + 0x06 + } + async fn read(t: &mut TcpStream) -> tokio::io::Result { + let mut playerpositionandlook = ServerboundPlayerPositionAndLook::new(); + playerpositionandlook.x = MCDouble::read(t).await?; + playerpositionandlook.y = MCDouble::read(t).await?; + playerpositionandlook.z = MCDouble::read(t).await?; + playerpositionandlook.yaw = MCFloat::read(t).await?; + playerpositionandlook.pitch = MCFloat::read(t).await?; + playerpositionandlook.on_ground = MCBoolean::read(t).await?; + Ok(playerpositionandlook) + } + async fn write(&self, t: &mut TcpStream) -> tokio::io::Result<()> { + for b in Into::>::into(self.clone()) { + write_byte(t, b).await?; + } + Ok(()) + } +}