diff --git a/src/args.rs b/src/args.rs index 62e8561..8358bf6 100644 --- a/src/args.rs +++ b/src/args.rs @@ -31,7 +31,7 @@ pub struct Args { #[arg(short, long, default_value = "25565", env = "LIMBO_PORT")] pub port: u16, // Whether or not to enable Velocity forwarding. - #[arg(short, long, default_value = "true", env = "LIMBO_VELOCITY_FORWARDING")] + #[arg(short, long, env = "LIMBO_VELOCITY_FORWARDING")] pub velocity_forwarding: bool, /// The x coordinate of the spawnpoint. #[arg(short = 'x', long, default_value = "0", env = "LIMBO_SPAWN_X")] diff --git a/src/net/cache.rs b/src/net/cache.rs index 0067065..c308c11 100644 --- a/src/net/cache.rs +++ b/src/net/cache.rs @@ -25,7 +25,7 @@ use crate::{ protocol::{ datatypes::VarInt, packets::{ - login::registry::{AllRegistries, Registry, AllTags}, + login::registry::{AllRegistries, AllTags, Registry}, play::ChunkDataUpdateLightC, }, Encoder, @@ -33,7 +33,6 @@ use crate::{ world::{blocks::Blocks, BlockEntity, Container, World}, CrawlState, }; -use crate::protocol::packets::login::registry::RegistryItem; #[derive(Debug)] pub struct WorldCache { @@ -57,7 +56,7 @@ impl WorldCache { let containers = chunks .iter() - .map(|(_, c)| { + .flat_map(|(_, c)| { c.block_entities .iter() .filter_map(|block_entity| { @@ -78,9 +77,7 @@ impl WorldCache { }, ); - let Some(block_entity) = block_entity else { - return None; - }; + let block_entity = block_entity?; match block_entity.id.as_str() { "minecraft:chest" | "minecraft:trapped_chest" | "minecraft:barrel" => { @@ -97,7 +94,6 @@ impl WorldCache { }) .collect::>() }) - .flatten() .collect(); debug!("Containers: {:?}", containers); @@ -133,12 +129,10 @@ impl From<&AllTags> for TagCache { fn from(tags: &AllTags) -> Self { let mut encoder = Encoder::new(); - encoder - .append_packet(tags) - .expect("Failed to encode tags"); + encoder.append_packet(tags).expect("Failed to encode tags"); Self { - encoded: encoder.take().to_vec() + encoded: encoder.take().to_vec(), } } } diff --git a/src/net/io.rs b/src/net/io.rs index 6ec95f4..27315fa 100644 --- a/src/net/io.rs +++ b/src/net/io.rs @@ -107,7 +107,7 @@ impl NetIo { if read_half .read_buf(&mut buf) .await - .context("failed read_buf")? + .wrap_err("failed read_buf")? == 0 { let mut c = self.connected.write().await; @@ -132,18 +132,24 @@ impl NetIo { trace!("raw packet is {} bytes", bytes.len()); trace!("{:?}", bytes.to_vec()); let mut writer = self.write_half.lock().await; - Ok(writer.write_all(&bytes).await?) + writer + .write_all(&bytes) + .await + .wrap_err("failed to write bytes") } pub async fn tx_raw(&self, packet: &[u8]) -> Result<()> { trace!("Sending packet {:?}", packet); let mut writer = self.write_half.lock().await; - Ok(writer.write_all(packet).await?) + writer + .write_all(packet) + .await + .wrap_err("failed to write bytes") } pub async fn rx_raw(&self) -> Result { let mut decoder = self.decoder.lock().await; - if let Some(frame) = decoder.try_read_next().context("failed try_read_next")? { + if let Some(frame) = decoder.try_read_next().wrap_err("failed try_read_next")? { return Ok(frame); }; @@ -152,7 +158,12 @@ impl NetIo { { let mut reader = self.read_half.lock().await; - if reader.read_buf(&mut buf).await.context("failed read_buf")? == 0 { + if reader + .read_buf(&mut buf) + .await + .wrap_err("failed read_buf")? + == 0 + { let mut c = self.connected.write().await; *c = false; return Err(std::io::Error::from(ErrorKind::UnexpectedEof).into()); diff --git a/src/net/player.rs b/src/net/player.rs index 43be169..29a30aa 100644 --- a/src/net/player.rs +++ b/src/net/player.rs @@ -25,7 +25,7 @@ use std::{ time::Duration, }; -use color_eyre::eyre::{bail, Result}; +use color_eyre::eyre::{bail, Context, Result}; use rand::Rng; use serde_json::json; use thiserror::Error; @@ -51,13 +51,14 @@ use crate::{ Frame, Packet, ProtocolState, }, server::window::{Window, WindowType}, + world::Container, CrawlState, }; +use super::{entity::Entity, io::NetIo}; #[cfg(feature = "encryption")] use crate::protocol::{datatypes::Bytes, packets::login::PluginRequestC}; use crate::protocol::{PacketDirection, PACKETS}; -use super::{entity::Entity, io::NetIo}; #[derive(Debug)] pub struct Player { @@ -148,7 +149,7 @@ impl SharedPlayer { ); match self.begin_play().await { - Ok(()) => debug!("Play loop for {} done.", self.id()), + Ok(()) => debug!("Spawned play loop for player {}.", self.id()), Err(why) => error!("Failed to play player {}! {why}", self.id()), } } @@ -214,9 +215,12 @@ impl SharedPlayer { self.0.io.tx(&res).await?; let ping: PingS = self.0.io.rx::().await?.decode()?; - self.0.io.tx(&PingC { - payload: ping.payload - }).await?; + self.0 + .io + .tx(&PingC { + payload: ping.payload, + }) + .await?; Ok(()) } @@ -532,7 +536,10 @@ impl SharedPlayer { let resource = PACKETS .get_resource_id(packet_state, PacketDirection::Serverbound, frame.id) .unwrap_or_else(|| { - panic!("{} cannot map to any resource in state {:?}", frame.id, packet_state) + panic!( + "{} cannot map to any resource in state {:?}", + frame.id, packet_state + ) }) .as_str(); @@ -569,7 +576,7 @@ impl SharedPlayer { } id => { - debug!( + trace!( "Got packet with id {id} from player {}, ignoring", self.0.id ); @@ -583,49 +590,56 @@ impl SharedPlayer { let crawlstate = self.0.crawlstate.clone(); let server = crawlstate.get_server().await; - let x = packet.location.x as i32; - let y = packet.location.y as i32; - let z = packet.location.z as i32; + let x = packet.location.x; + let y = packet.location.y; + let z = packet.location.z; debug!("Player {} clicked at {}, {}, {}", self.id(), x, y, z); match server.get_container(x, y, z) { None => (), - Some(container) => { - let id = { - let mut next_window_id = self.0.next_window_id.lock().await; - let id = *next_window_id; - *next_window_id = next_window_id.wrapping_add(1); - if *next_window_id == 0 { - *next_window_id = 1; - } - id - }; - - let window = Window { - id, - kind: WindowType::Generic9x3, - title: "Hi".into(), - }; - - self.0.io.tx(&OpenScreenC::from(&window)).await?; - - self.0 - .io - .tx(&SetContainerContentC { - window_id: id, - // FIXME: track this correctly - state_id: 0, - slot_data: container.0, - carried_item: Slot::default(), - }) - .await?; - - { - let mut sw = self.0.window.write().await; - *sw = Some(window); - } + Some(container) => self + .open_container(container) + .await + .wrap_err_with(|| format!("failed to open container at {x}, {y}, {z}"))?, + } + + Ok(()) + } + + async fn open_container(&self, container: Container) -> Result<()> { + let id = { + let mut next_window_id = self.0.next_window_id.lock().await; + let id = *next_window_id; + *next_window_id = next_window_id.wrapping_add(1); + if *next_window_id == 0 { + *next_window_id = 1; } + id + }; + + let window = Window { + id, + kind: WindowType::Generic9x3, + title: "Hi".into(), + }; + + self.0.io.tx(&OpenScreenC::from(&window)).await?; + + self.0 + .io + .tx(&SetContainerContentC { + window_id: id, + // FIXME: track this correctly + state_id: 0, + slot_data: container.0, + carried_item: Slot::default(), + }) + .await?; + + { + let mut sw = self.0.window.write().await; + *sw = Some(window); } Ok(()) diff --git a/src/protocol/datatypes/slot.rs b/src/protocol/datatypes/slot.rs index bf8f83a..090d0f1 100644 --- a/src/protocol/datatypes/slot.rs +++ b/src/protocol/datatypes/slot.rs @@ -21,7 +21,7 @@ use crate::{protocol::Encode, server::registries::REGISTRIES, world::Item}; use super::VarInt; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct Slot { item_count: i8, item_id: Option, @@ -52,17 +52,6 @@ impl From for Slot { } } -impl Default for Slot { - fn default() -> Self { - Self { - item_count: 0, - item_id: None, - components_to_add: None, - components_to_remove: None, - } - } -} - impl Encode for Slot { fn encode(&self, mut w: impl std::io::Write) -> color_eyre::eyre::Result<()> { self.item_count.encode(&mut w)?; diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 6e130db..bfe3145 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -77,13 +77,13 @@ pub mod packets { mod decoder; mod encoder; -use std::{fmt::Debug, io::Write}; -use std::collections::HashMap; -use std::sync::LazyLock; use bit_vec::BitVec; use color_eyre::eyre::{Context, Result}; -use serde::{Deserialize, Serialize}; use datatypes::{Bounded, VarInt}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::sync::LazyLock; +use std::{fmt::Debug, io::Write}; use thiserror::Error; pub use decoder::*; @@ -92,7 +92,7 @@ pub use encoder::*; pub static PACKETS: LazyLock = LazyLock::new(|| { Packets::new( serde_json::from_str(include_str!("../../assets/packets.json")) - .expect("packets.json should be parseable") + .expect("packets.json should be parseable"), ) }); @@ -102,55 +102,71 @@ pub struct PacketType { } #[derive(Clone, Debug, Deserialize)] -pub struct ForwardPackets(pub HashMap>>); +pub struct ForwardPackets( + pub HashMap>>, +); #[derive(Clone, Debug)] pub struct Packets { forward: ForwardPackets, - reverse: HashMap>> + reverse: HashMap>>, } impl Packets { pub fn new(forward: ForwardPackets) -> Self { Self { reverse: Self::build_reverse(&forward), - forward + forward, } } - pub fn get_protocol_id(&self, state: PacketState, direction: PacketDirection, name: &str) -> Option { + pub fn get_protocol_id( + &self, + state: PacketState, + direction: PacketDirection, + name: &str, + ) -> Option { Some( self.forward - .0.get(&state) - ?.get(&direction) - ?.get(name.into()) - ?.protocol_id + .0 + .get(&state)? + .get(&direction)? + .get(name)? + .protocol_id, ) } - pub fn get_resource_id(&self, state: PacketState, direction: PacketDirection, protocol_id: i32) -> Option<&String> { - Some( - self.reverse - .get(&state) - ?.get(&direction) - ?.get(&protocol_id)? - ) + pub fn get_resource_id( + &self, + state: PacketState, + direction: PacketDirection, + protocol_id: i32, + ) -> Option<&String> { + self.reverse.get(&state)?.get(&direction)?.get(&protocol_id) } - fn build_reverse(forward: &ForwardPackets) -> HashMap>> { + fn build_reverse( + forward: &ForwardPackets, + ) -> HashMap>> { let mut reverse = HashMap::new(); for state in forward.0.keys() { let direction_mapping = reverse .entry(*state) - .or_insert_with(|| { HashMap::new() }) + .or_insert_with(HashMap::new) .entry(PacketDirection::Serverbound) - .or_insert_with(|| { HashMap::new() }); - - for (key, value) in forward.0.get(&state).unwrap().get(&PacketDirection::Serverbound).unwrap() { + .or_insert_with(HashMap::new); + + for (key, value) in forward + .0 + .get(state) + .unwrap() + .get(&PacketDirection::Serverbound) + .unwrap() + { direction_mapping .entry(value.protocol_id) - .or_insert_with(move || { key.clone() }); + .or_insert_with(move || key.clone()); } } @@ -188,7 +204,7 @@ pub enum PacketState { Login, Configuration, Play, - Status + Status, } #[derive(Clone, Copy, Debug)] @@ -206,14 +222,14 @@ pub enum ProtocolStateDecodeError { InvalidState(i32), } -impl Into for ProtocolState { - fn into(self) -> PacketState { - match self { +impl From for PacketState { + fn from(value: ProtocolState) -> Self { + match value { ProtocolState::Handshaking => PacketState::Handshake, ProtocolState::Play => PacketState::Play, ProtocolState::Status => PacketState::Status, ProtocolState::Login => PacketState::Login, - ProtocolState::Transfer => PacketState::Login + ProtocolState::Transfer => PacketState::Login, } } } diff --git a/src/protocol/packets/play/teleport.rs b/src/protocol/packets/play/teleport.rs index a347ccb..23c454c 100644 --- a/src/protocol/packets/play/teleport.rs +++ b/src/protocol/packets/play/teleport.rs @@ -52,6 +52,7 @@ mod flags { #[allow(unused)] impl SynchronisePositionC { + #[allow(clippy::too_many_arguments)] pub fn new( x: f64, y: f64, @@ -60,7 +61,7 @@ impl SynchronisePositionC { velocity_y: f64, velocity_z: f64, yaw: f32, - pitch: f32 + pitch: f32, ) -> Self { Self { x, diff --git a/src/world/container.rs b/src/world/container.rs index acbd702..dd33427 100644 --- a/src/world/container.rs +++ b/src/world/container.rs @@ -40,7 +40,7 @@ impl TryFrom for Container { "minecraft:chest" | "minecraft:trapped_chest" | "minecraft:barrel" => { let items = value .try_get_items() - .map_err(|e| ContainerCreationError::ParseError(e))?; + .map_err(ContainerCreationError::ParseError)?; let mut slots = vec![Slot::default(); 27];