Expose the protocol API behind a feature flag

This could be useful for building proxies or clients in the future.
This commit is contained in:
Ryan 2022-06-30 11:53:57 -07:00
parent fa2241c038
commit 560163fd2e
20 changed files with 70 additions and 84 deletions

View file

@ -60,3 +60,7 @@ proc-macro2 = "1"
quote = "1"
serde = {version = "1", features = ["derive"]}
serde_json = "1"
[features]
# Exposes the raw protocol API
protocol = []

View file

@ -2150,11 +2150,11 @@ pub fn build() -> anyhow::Result<()> {
#getter_setters
pub(crate) fn initial_metadata(&self, data: &mut Vec<u8>) {
pub(crate) fn initial_metadata(&self, #[allow(unused)] data: &mut Vec<u8>) {
#initial_metadata_fields
}
pub(crate) fn updated_metadata(&self, data: &mut Vec<u8>) {
pub(crate) fn updated_metadata(&self, #[allow(unused)] data: &mut Vec<u8>) {
if self.modified_flags == 0 {
return;
}

View file

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

View file

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

View file

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

View file

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

View file

@ -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<Entity>,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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<W> {
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() {

View file

@ -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<Self>;
}
@ -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<u8>,
signature: Vec<u8>,
}
}
/// 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<u8>,
signature: Vec<u8>,
}
}
def_struct! {
EncryptionResponse 0x01 {
shared_secret: BoundedArray<u8, 16, 128>,
@ -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<C2sPlayPacket> {
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! {

View file

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

View file

View file

@ -40,6 +40,7 @@ impl Key {
}
}
#[allow(unused)]
pub fn index(self) -> u32 {
self.index
}
@ -161,6 +162,7 @@ impl<T> SlotMap<T> {
}
}
#[allow(unused)]
pub fn clear(&mut self) {
self.slots.clear();
self.next_free_head = 0;