diff --git a/Cargo.toml b/Cargo.toml index d3f2c15..aa8661e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,3 +60,7 @@ proc-macro2 = "1" quote = "1" serde = {version = "1", features = ["derive"]} serde_json = "1" + +[features] +# Exposes the raw protocol API +protocol = [] diff --git a/build/entity.rs b/build/entity.rs index 87f82cc..3800126 100644 --- a/build/entity.rs +++ b/build/entity.rs @@ -2150,11 +2150,11 @@ pub fn build() -> anyhow::Result<()> { #getter_setters - pub(crate) fn initial_metadata(&self, data: &mut Vec) { + pub(crate) fn initial_metadata(&self, #[allow(unused)] data: &mut Vec) { #initial_metadata_fields } - pub(crate) fn updated_metadata(&self, data: &mut Vec) { + pub(crate) fn updated_metadata(&self, #[allow(unused)] data: &mut Vec) { if self.modified_flags == 0 { return; } diff --git a/src/block.rs b/src/block.rs index 1c2cd35..7a872ff 100644 --- a/src/block.rs +++ b/src/block.rs @@ -5,8 +5,7 @@ use std::io::{Read, Write}; use anyhow::Context; -use crate::protocol::{Decode, Encode}; -use crate::var_int::VarInt; +use crate::protocol::{Decode, Encode, VarInt}; include!(concat!(env!("OUT_DIR"), "/block.rs")); diff --git a/src/chunk.rs b/src/chunk.rs index 9ac3c20..a305c0e 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -9,12 +9,10 @@ use num::Integer; use rayon::iter::{IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator}; use crate::block::BlockState; -use crate::packets::play::s2c::{ +use crate::protocol::packets::play::s2c::{ BlockChange, ChunkDataAndUpdateLight, ChunkDataHeightmaps, MultiBlockChange, S2cPlayPacket, }; -use crate::protocol::{Encode, Nbt}; -use crate::var_int::VarInt; -use crate::var_long::VarLong; +use crate::protocol::{Encode, Nbt, VarInt, VarLong}; use crate::{BiomeId, BlockPos, ChunkPos, DimensionId, Server, Ticks}; pub struct Chunks { diff --git a/src/client.rs b/src/client.rs index 5697e17..76c204e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -11,14 +11,13 @@ use uuid::Uuid; use vek::Vec3; use crate::biome::{Biome, BiomeGrassColorModifier, BiomePrecipitation}; -use crate::block_pos::BlockPos; -use crate::byte_angle::ByteAngle; use crate::dimension::{Dimension, DimensionEffects}; use crate::entity::types::Player; use crate::entity::{velocity_to_packet_units, EntityType}; -use crate::packets::play::c2s::{C2sPlayPacket, DiggingStatus}; -pub use crate::packets::play::s2c::ChatMessageType; -use crate::packets::play::s2c::{ +use crate::player_textures::SignedPlayerTextures; +use crate::protocol::packets::play::c2s::{C2sPlayPacket, DiggingStatus, InteractType}; +pub use crate::protocol::packets::play::s2c::ChatMessageType; +use crate::protocol::packets::play::s2c::{ AcknowledgeBlockChanges, Biome as BiomeRegistryBiome, BiomeAdditionsSound, BiomeEffects, BiomeMoodSound, BiomeMusic, BiomeParticle, BiomeParticleOptions, BiomeProperty, BiomeRegistry, ChangeGameState, ChangeGameStateReason, ChatTypeRegistry, DestroyEntities, DimensionType, @@ -28,15 +27,13 @@ use crate::packets::play::s2c::{ S2cPlayPacket, SpawnPosition, SystemChatMessage, UnloadChunk, UpdateViewDistance, UpdateViewPosition, }; -use crate::player_textures::SignedPlayerTextures; -use crate::protocol::{BoundedInt, Nbt, RawBytes}; +use crate::protocol::{BoundedInt, ByteAngle, Nbt, RawBytes, VarInt}; use crate::server::C2sPacketChannels; use crate::slotmap::{Key, SlotMap}; use crate::util::{chunks_in_view_distance, is_chunk_in_view_distance}; -use crate::var_int::VarInt; use crate::{ - ident, ChunkPos, Chunks, DimensionId, Entities, EntityId, NewClientData, Server, SpatialIndex, - Text, Ticks, WorldMeta, LIBRARY_NAMESPACE, + ident, BlockPos, ChunkPos, Chunks, DimensionId, Entities, EntityId, NewClientData, Server, + SpatialIndex, Text, Ticks, WorldMeta, LIBRARY_NAMESPACE, }; pub struct Clients { @@ -441,7 +438,6 @@ impl Client { // TODO: verify that the client has line of sight to the targeted entity and // that the distance is <=4 blocks. - use crate::packets::play::c2s::InteractType; self.events.push(Event::InteractWithEntity { id, sneaking: p.sneaking, diff --git a/src/client/event.rs b/src/client/event.rs index 3f713a0..2eed5aa 100644 --- a/src/client/event.rs +++ b/src/client/event.rs @@ -2,9 +2,9 @@ use std::time::Duration; use vek::Vec3; -use crate::packets::play::c2s::BlockFace; -pub use crate::packets::play::c2s::{ChatMode, DisplayedSkinParts, Hand, MainHand}; -pub use crate::packets::play::s2c::GameMode; +use crate::protocol::packets::play::c2s::BlockFace; +pub use crate::protocol::packets::play::c2s::{ChatMode, DisplayedSkinParts, Hand, MainHand}; +pub use crate::protocol::packets::play::s2c::GameMode; use crate::{BlockPos, EntityId}; #[derive(Debug)] diff --git a/src/entity.rs b/src/entity.rs index c73c3bd..aca23a7 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -12,14 +12,12 @@ pub use types::{EntityMeta, EntityType}; use uuid::Uuid; use vek::{Aabb, Vec3}; -use crate::byte_angle::ByteAngle; -use crate::packets::play::s2c::{ +use crate::protocol::packets::play::s2c::{ EntityMetadata, S2cPlayPacket, SpawnEntity, SpawnExperienceOrb, SpawnPlayer, }; -use crate::protocol::RawBytes; +use crate::protocol::{ByteAngle, RawBytes, VarInt}; use crate::slotmap::{Key, SlotMap}; use crate::util::aabb_from_bottom_and_size; -use crate::var_int::VarInt; pub struct Entities { sm: SlotMap, diff --git a/src/entity/meta.rs b/src/entity/meta.rs index 486dfc8..3950ebc 100644 --- a/src/entity/meta.rs +++ b/src/entity/meta.rs @@ -2,8 +2,7 @@ use std::io::Write; -use crate::protocol::Encode; -use crate::var_int::VarInt; +use crate::protocol::{Encode, VarInt}; #[derive(Clone, Copy, Default, PartialEq, PartialOrd, Debug)] pub struct ArmorStandRotations { diff --git a/src/entity/types.rs b/src/entity/types.rs index c04d9e3..f32d21b 100644 --- a/src/entity/types.rs +++ b/src/entity/types.rs @@ -2,8 +2,7 @@ use crate::block::BlockState; use crate::entity::meta::*; -use crate::protocol::Encode; -use crate::var_int::VarInt; +use crate::protocol::{Encode, VarInt}; use crate::{BlockPos, EntityId, Text, Uuid}; include!(concat!(env!("OUT_DIR"), "/entity.rs")); diff --git a/src/lib.rs b/src/lib.rs index f6bca66..d96208d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,26 +11,24 @@ pub mod biome; pub mod block; mod block_pos; mod bvh; -mod byte_angle; pub mod chunk; mod chunk_pos; pub mod client; -mod codec; pub mod config; pub mod dimension; pub mod entity; pub mod ident; -mod packets; mod player_list; pub mod player_textures; +#[cfg(not(feature = "protocol"))] mod protocol; +#[cfg(feature = "protocol")] +pub mod protocol; pub mod server; mod slotmap; -pub mod spatial_index; +mod spatial_index; pub mod text; pub mod util; -mod var_int; -mod var_long; pub mod world; pub use async_trait::async_trait; diff --git a/src/player_list.rs b/src/player_list.rs index 8df0bd7..37fe78f 100644 --- a/src/player_list.rs +++ b/src/player_list.rs @@ -5,12 +5,12 @@ use bitfield_struct::bitfield; use uuid::Uuid; use crate::client::GameMode; -use crate::packets::play::s2c::{ +use crate::player_textures::SignedPlayerTextures; +use crate::protocol::packets::play::s2c::{ PlayerInfo, PlayerInfoAddPlayer, PlayerListHeaderFooter, S2cPlayPacket, }; -use crate::packets::Property; -use crate::player_textures::SignedPlayerTextures; -use crate::var_int::VarInt; +use crate::protocol::packets::Property; +use crate::protocol::VarInt; use crate::Text; pub struct PlayerList { diff --git a/src/protocol.rs b/src/protocol.rs index cd22461..724a165 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -1,16 +1,24 @@ +mod byte_angle; +pub mod codec; +pub mod packets; +mod var_int; +mod var_long; + use std::io::{Read, Write}; use std::mem; use anyhow::{anyhow, ensure, Context}; use arrayvec::ArrayVec; use bitvec::prelude::*; +pub use byte_angle::ByteAngle; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use serde::de::DeserializeOwned; use serde::Serialize; use uuid::Uuid; +pub use var_int::VarInt; +pub use var_long::VarLong; use vek::{Vec2, Vec3, Vec4}; -use crate::var_int::VarInt; use crate::EntityId; /// Trait for types that can be written to the Minecraft protocol. @@ -18,7 +26,7 @@ pub trait Encode { fn encode(&self, w: &mut impl Write) -> anyhow::Result<()>; } -/// Trait for types that can be constructed from the Minecraft protocol. +/// Trait for types that can be read from the Minecraft protocol. pub trait Decode: Sized { fn decode(r: &mut impl Read) -> anyhow::Result; } diff --git a/src/byte_angle.rs b/src/protocol/byte_angle.rs similarity index 100% rename from src/byte_angle.rs rename to src/protocol/byte_angle.rs diff --git a/src/codec.rs b/src/protocol/codec.rs similarity index 98% rename from src/codec.rs rename to src/protocol/codec.rs index e5d2928..d6863f5 100644 --- a/src/codec.rs +++ b/src/protocol/codec.rs @@ -12,8 +12,7 @@ use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; use tokio::time::timeout; use super::packets::{DecodePacket, EncodePacket}; -use crate::protocol::{Decode, Encode, MAX_PACKET_SIZE}; -use crate::var_int::VarInt; +use crate::protocol::{Decode, Encode, VarInt, MAX_PACKET_SIZE}; pub struct Encoder { write: W, @@ -238,7 +237,7 @@ mod tests { use tokio::sync::oneshot; use super::*; - use crate::packets::test::TestPacket; + use crate::protocol::packets::test::TestPacket; #[tokio::test] async fn encode_decode() { diff --git a/src/packets.rs b/src/protocol/packets.rs similarity index 98% rename from src/packets.rs rename to src/protocol/packets.rs index e036ccb..57310c9 100644 --- a/src/packets.rs +++ b/src/protocol/packets.rs @@ -16,10 +16,10 @@ use uuid::Uuid; use vek::Vec3; use crate::block_pos::BlockPos; -use crate::byte_angle::ByteAngle; -use crate::protocol::{BoundedArray, BoundedInt, BoundedString, Decode, Encode, Nbt, RawBytes}; -use crate::var_int::VarInt; -use crate::var_long::VarLong; +use crate::protocol::{ + BoundedArray, BoundedInt, BoundedString, ByteAngle, Decode, Encode, Nbt, RawBytes, VarInt, + VarLong, +}; use crate::{Ident, Text}; /// Trait for types that can be written to the Minecraft protocol as a complete @@ -27,7 +27,7 @@ use crate::{Ident, Text}; /// /// A complete packet is one that starts with a `VarInt` packet ID, followed by /// the body of the packet. -pub trait EncodePacket: fmt::Debug + private::Sealed { +pub trait EncodePacket: fmt::Debug { /// Writes a packet to the Minecraft protocol, including its packet ID. fn encode_packet(&self, w: &mut impl Write) -> anyhow::Result<()>; } @@ -37,7 +37,7 @@ pub trait EncodePacket: fmt::Debug + private::Sealed { /// /// A complete packet is one that starts with a `VarInt` packet ID, followed by /// the body of the packet. -pub trait DecodePacket: Sized + fmt::Debug + private::Sealed { +pub trait DecodePacket: Sized + fmt::Debug { /// Reads a packet from the Minecraft protocol, including its packet ID. fn decode_packet(r: &mut impl Read) -> anyhow::Result; } @@ -94,8 +94,6 @@ macro_rules! def_struct { } $( - impl private::Sealed for $name {} - impl EncodePacket for $name { fn encode_packet(&self, w: &mut impl Write) -> anyhow::Result<()> { VarInt($id) @@ -206,8 +204,6 @@ macro_rules! def_enum { } $( - impl private::Sealed for $name {} - impl EncodePacket for $name { fn encode_packet(&self, w: &mut impl Write) -> anyhow::Result<()> { VarInt($id) @@ -325,10 +321,6 @@ macro_rules! def_bitfield { } } -mod private { - pub trait Sealed {} -} - def_struct! { #[derive(PartialEq, Serialize, Deserialize)] Property { @@ -339,6 +331,14 @@ def_struct! { } } +def_struct! { + SignatureData { + timestamp: u64, + public_key: Vec, + signature: Vec, + } +} + /// Packets and types used during the handshaking state. pub mod handshake { use super::*; @@ -440,14 +440,6 @@ pub mod login { } } - def_struct! { - SignatureData { - timestamp: i64, - public_key: Vec, - signature: Vec, - } - } - def_struct! { EncryptionResponse 0x01 { shared_secret: BoundedArray, @@ -475,7 +467,6 @@ pub mod login { pub mod play { pub mod s2c { use super::super::*; - use crate::packets::login::c2s::SignatureData; def_struct! { SpawnEntity 0x00 { @@ -1173,8 +1164,6 @@ pub mod play { $($packet($packet)),* } - impl private::Sealed for S2cPlayPacket {} - $( impl From<$packet> for S2cPlayPacket { fn from(p: $packet) -> S2cPlayPacket { @@ -1831,8 +1820,6 @@ pub mod play { $($packet($packet)),* } - impl private::Sealed for C2sPlayPacket {} - impl DecodePacket for C2sPlayPacket { fn decode_packet(r: &mut impl Read) -> anyhow::Result { let packet_id = VarInt::decode(r).context("failed to read c2s play packet ID")?.0; @@ -1926,7 +1913,7 @@ pub mod play { } #[cfg(test)] -pub mod test { +pub(crate) mod test { use super::*; def_struct! { diff --git a/src/var_int.rs b/src/protocol/var_int.rs similarity index 100% rename from src/var_int.rs rename to src/protocol/var_int.rs diff --git a/src/var_long.rs b/src/protocol/var_long.rs similarity index 100% rename from src/var_long.rs rename to src/protocol/var_long.rs diff --git a/src/server.rs b/src/server.rs index 02b8392..5cbe152 100644 --- a/src/server.rs +++ b/src/server.rs @@ -26,20 +26,19 @@ use tokio::runtime::{Handle, Runtime}; use tokio::sync::{oneshot, Semaphore}; use uuid::Uuid; -use crate::codec::{Decoder, Encoder}; use crate::config::{Config, ServerListPing}; -use crate::packets::handshake::{Handshake, HandshakeNextState}; -use crate::packets::login::c2s::{EncryptionResponse, LoginStart, VerifyTokenOrMsgSig}; -use crate::packets::login::s2c::{EncryptionRequest, LoginSuccess, SetCompression}; -use crate::packets::play::c2s::C2sPlayPacket; -use crate::packets::play::s2c::S2cPlayPacket; -use crate::packets::status::c2s::{Ping, Request}; -use crate::packets::status::s2c::{Pong, Response}; -use crate::packets::{login, Property}; use crate::player_textures::SignedPlayerTextures; -use crate::protocol::{BoundedArray, BoundedString}; +use crate::protocol::codec::{Decoder, Encoder}; +use crate::protocol::packets::handshake::{Handshake, HandshakeNextState}; +use crate::protocol::packets::login::c2s::{EncryptionResponse, LoginStart, VerifyTokenOrMsgSig}; +use crate::protocol::packets::login::s2c::{EncryptionRequest, LoginSuccess, SetCompression}; +use crate::protocol::packets::play::c2s::C2sPlayPacket; +use crate::protocol::packets::play::s2c::S2cPlayPacket; +use crate::protocol::packets::status::c2s::{Ping, Request}; +use crate::protocol::packets::status::s2c::{Pong, Response}; +use crate::protocol::packets::{login, Property}; +use crate::protocol::{BoundedArray, BoundedString, VarInt}; use crate::util::valid_username; -use crate::var_int::VarInt; use crate::world::Worlds; use crate::{ Biome, BiomeId, Client, Dimension, DimensionId, Ticks, PROTOCOL_VERSION, VERSION_NAME, diff --git a/src/slot.rs b/src/slot.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/slotmap.rs b/src/slotmap.rs index 13088ca..e5384bb 100644 --- a/src/slotmap.rs +++ b/src/slotmap.rs @@ -40,6 +40,7 @@ impl Key { } } + #[allow(unused)] pub fn index(self) -> u32 { self.index } @@ -161,6 +162,7 @@ impl SlotMap { } } + #[allow(unused)] pub fn clear(&mut self) { self.slots.clear(); self.next_free_head = 0;